# Rules list¶

## $HTTP_RAW_POST_DATA¶ Starting at PHP 5.6,$HTTP_RAW_POST_DATA is deprecated, and should be replaced by php://input. You may get ready by setting always_populate_raw_post_data to -1.

<?php

// PHP 5.5 and older
$postdata =$HTTP_RAW_POST_DATA;

// PHP 5.6 and more recent
$postdata = file_get_contents(php://input); ?>   Command Line Php/RawPostDataUsage Analyzers CompatibilityPHP56, Analyze, CompatibilityPHP70, CompatibilityPHP71 ##$this Belongs To Classes Or Traits¶

$this variable represents only the current object. It is a pseudo-variable, and should be used within class’s or trait’s methods (except for static) and not outside. PHP 7.1 is stricter and check for$this at several positions. Some are found by static analysis, some are dynamic analysis.

<?php

// as an argument
function foo($this) { // Using global global$this;
// Using static (not a property)
static $this; // Can't unset it unset($this);

try {
// inside a foreach
foreach($a as$this) {  }
foreach($a as$this => $b) { } foreach($a as $b =>$this) {  }
} catch (Exception $this) { // inside a catch } // with Variable Variable$a = this;
$$a = 42; } class foo { function bar() { // Using references a =& this; a = 42; // Using 'extract(), 'parse_str() or similar functions extract([this => 42]); // throw new Error(Cannot re-assign this) var_dump(this); } static function '__call(name, args) { // Using '__call var_dump(this); // prints object(C)#1 (0) {}, php-7.0 printed NULL this->test(); // prints ops } } ?>   Command Line Classes/ThisIsForClasses Analyzers Analyze ## this Is Not An Array¶ this variable represents the current object and it is not an array, unless the class (or its parents) has the ‘ArrayAccess interface. <?php // this is an array class Foo extends 'ArrayAccess { function bar() { ++this[3]; } } // this is not an array class Foo2 { function bar() { ++this[3]; } } ?>   Command Line Classes/ThisIsNotAnArray Analyzers Analyze ## this Is Not For Static Methods¶ Static methods shouldn’t use this variable. this variable represents an object (the current object) and it is not compatible with a static method, which may operate without any object. <?php class foo { static public function bar() { return this->a; // No this usage in a static method } } ?>   Command Line Classes/ThisIsNotForStatic clearPHP no-static-this Analyzers Analyze ## ** For Exponent¶ PHP 5.6 introduced the operator ‘** to provide exponents, instead of the slower function ‘pow(). <?php cube = pow(2, 3); // 8 cubeInPHP56 = 2 '** 3; // 8 ?>  If the code needs to be backward compatible to 5.5 or less, don’t use the new operator.  Command Line Php/NewExponent Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55 ## ... Usage¶ Usage of the ... keyword, either in function definitions, either in functioncalls.  Command Line Php/EllipsisUsage Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55 ## ::class¶ PHP 5.5 introduced a special class constant, relying on the ‘class’ keyword. It will solve the classname that is used in the left part of the operator. <?php class foo { public function bar( ) { echo ClassName::class; } } f = new Foo( ); f->bar( ); // return Namespace\ClassName ?>   Command Line Php/StaticclassUsage Analyzers CompatibilityPHP53, CompatibilityPHP54 ## <?= Usage¶ Usage of the <?= tag, that echo’s directly the following content. <?= variable; ?>  Command Line Php/EchoTagUsage Analyzers Analyze ## Abstract Static Methods¶ Methods cannot be both abstract and static. Static methods belong to a class, and will not be overridden by the child class. For normal methods, PHP will start at the object level, then go up the hierarchy to find the method. With static, you have to mention the name, or use Late Static Binding, with self or static. Hence, it is useless to have an abstract static method : it should be a simple static method. A child class is able to declare a method with the same name than a static method in the parent, but those two methods will stay independant.  Command Line Classes/AbstractStatic Analyzers Analyze ## Access Protected Structures¶ It is not allowed to access protected properties or methods from outside the class or its relatives.  Command Line Classes/AccessProtected Analyzers Analyze ## Accessing Private¶ List of calls to private properties/methods that will compile but yield some fatal error upon execution. <?php class a { private a; } class b extends a { function c() { this->a; } } ?>   Command Line Classes/AccessPrivate Analyzers Analyze ## Action Should Be In Controller¶ Action methods should be in a controller and public. <?php use Zend\Mvc\Controller\AbstractActionController; class SomeController extends AbstractActionController { // Good method public function indexAction() { doSomething(); } // Bad method : protected // turn protected into public, or drop the Action suffix protected function protectedIndexAction() { doSomething(); } // Bad method : private // turn private into public, or drop the Action suffix protected function privateIndexAction() { doSomething(); } } ?>   Command Line ZendF/ActionInController Analyzers ZendFramework ## Adding Zero¶ Adding 0 is useless, as 0 is the neutral element for addition. It may trigger a cast (to integer), though behavior changes from PHP 7.0 to PHP 7.1. <?php a = 123 + 0; a = 0 + 123; // Also works with minus b = 0 - c; // drop the 0, but keep the minus b = c - 0; // drop the 0 and the minus ?>  If it is used to type cast a value to integer, then casting (integer) is clearer.  Command Line Structures/AddZero clearPHP no-useless-math Analyzers Analyze ## Aliases Usage¶ PHP manual recommends to avoid function aliases. Some functions have several names, and both may be used the same way. However, one of the names is the main name, and the others are aliases. Aliases may be removed or change or dropped in the future. Even if this is not forecast, it is good practice to use the main name, instead of the aliases. <?php // official way to count an array n = count(array); // official way to count an array n = sizeof(array); ?>  Aliases are compiled in PHP, and do not provide any performances over the normal function. Aliases are more likely to be removed later, but they have been around for a long time. See documentation : List of function aliases.  Command Line Functions/AliasesUsage clearPHP no-aliases Analyzers Analyze ## All Uppercase Variables¶ Usually, global variables are all in uppercase, so as to differentiate them easily. Though, this is not always the case, with examples like argc, argv or http_response_header. When using custom variables, try to use lowercase variables, camelCase, sturdyCase or snake_case. <?php // PHP super global, also identified by the initial _ localVariable = _POST; // PHP globals localVariable = GLOBALS['HTTPS']; ?>  Predefined Variables  Command Line Variables/VariableUppercase Analyzers Coding Conventions ## Already Parents Interface¶ The same interface is implemented by a class and one of its children. That way, the child doesn’t need to implement the interface, nor define its methods to be an instance of the interface. <?php interface i { function i(); } class A implements i { function i() { return '__METHOD__; } } // This implements is useless. class AB extends A implements i { // No definition for function i() } // Implements i is understated class AB extends A { // redefinition of the i method function i() { return '__METHOD__.' '; } } x = new AB; var_dump(x 'instanceof i); // true x = new AC; var_dump(x 'instanceof i); // true ?>   Command Line Interfaces/AlreadyParentsInterface Analyzers Analyze ## Altering Foreach Without Reference¶ Foreach() loop that should use a reference. When using a foreach loop that modifies the original source, it is recommended to use referenced variables, rather than access the original value with source[index]. Using references is then must faster, and easier to read. <?php // Using references in foreach foreach(source as key => &value) { value = newValue(value, key); } // Avoid foreach : use array_map source = array_walk(source, 'newValue'); // Here, key MUST be the second argument or newValue // Slow version to update the array foreach(source as key => &value) { source[key] = newValue(value, key); } ?>  You may also use ‘array_walk() or ‘array_map() (when key is not used) to avoid the use of foreach.  Command Line Structures/AlteringForeachWithoutReference clearPHP use-reference-to-alter-in-foreach Analyzers Analyze ## Alternative Syntax Consistence¶ PHP allows for two syntax : the alternative syntax, and the classic syntax. The classic syntax is almost always used. When used, the alternative syntax is used in templates. This analysis reports files that are using both syntax at the same time. This is confusing. <?php // Mixing both syntax is confusing. foreach(array as item) : if (item > 1) { print item elements\n; } else { print item element\n; } endforeach; ?>   Command Line Structures/AlternativeConsistenceByFile Analyzers Analyze ## Always Positive Comparison¶ Some PHP native functions, such as ‘count(), strlen(), or ‘abs() only returns positive or null values. When comparing them to 0, the following expressions are always true and should be avoided. <?php a = [1, 2, 3]; var_dump(count(a) >= 0); var_dump(count(a) < 0); ?>   Command Line Structures/NeverNegative Analyzers Analyze ## Ambiguous Array Index¶ Those indexes are defined with different types, in the same array. Array indices only accept integers and strings, so any other type of literal is reported. <?php x = [ 1 => 1, '1' => 2, 1.0 => 3, true => 4]; // x only contains one element : 1 => 4 // Still wrong, immediate typecast to 1 x[1.0] = 5; x[true] = 6; ?>  They are indeed distinct, but may lead to confusion.  Command Line Arrays/AmbiguousKeys Analyzers Analyze ## Anonymous Classes¶ Anonymous classes. <?php // Anonymous class, available since PHP 7.0 object = new class { function '__construct() { echo '__METHOD__; } }; ?>   Command Line Classes/Anonymous Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56 ## Argument Should Be Typehinted¶ When a method expects objects as argument, those arguments should be typehinted, so as to provide early warning that a wrong object is being sent to the method. The analyzer will detect situations where a class, or the keywords ‘array’ or ‘callable’. <?php // What are the possible classes that have a 'foo' method? function foo(bar) { return bar->foo(); } ?>  ‘Closure arguments are omitted.  Command Line Functions/ShouldBeTypehinted clearPHP always-typehint Analyzers Analyze ## Assign Default To Properties¶ Properties may be assigned default values at declaration time. Such values may be later modified, if needed. <?php class foo { private propertyWithDefault = 1; private propertyWithoutDefault; private propertyThatCantHaveDefault; public function '__construct() { // Skip this extra line, and give the default value above this->propertyWithoutDefault = 1; // Static expressions are available to set up simple computation at definition time. this->propertyWithoutDefault = OtherClass::CONSTANT + 1; // Arrays, just like scalars, may be set at definition time this->propertyWithoutDefault = [1,2,3]; // Objects or resources can't be made default. That is OK. this->propertyThatCantHaveDefault = fopen('/path/to/file.txt'); this->propertyThatCantHaveDefault = new Fileinfo(); } } ?>  Default values will save some instructions in the constructor, and makes the value obvious in the code.  Command Line Classes/MakeDefault clearPHP use-properties-default-values Analyzers Analyze ## Assigned Twice¶ The same variable is assigned twice in the same function. While this is possible and quite common, it is also a good practice to avoid changing a value from one literal to another. It is far better to assign the new value to Incremental changes to a variables are not reported here. <?php function foo() { // incremental changes of a; a = 'a'; a++; a = uppercase(a); b = 1; c = bar(b); // B changed its purpose. Why not call it d? b = array(1,2,3); // This is some forgotten debug e = config->getSomeList(); e = array('OneElement'); } ?>   Command Line Variables/AssignedTwiceOrMore Analyzers Analyze ## Avoid Large Array Assignation¶ Avoid setting large arrays to local variables. This is done everytime the function is called. There are different ways to avoid this : inject the array, build the array once. Using an constant or even a global variable is faster. The effect on small arrays (less than 10 elements) is not significant. Arrays with 10 elements or more are reported here. The effect is also more important on functions that are called often, or within loops. <?php // with constants, for functions const ARRAY = array(1,2,3,4,5,6,7,8,9,10,11); function foo() { array = ARRAY; //more code } // with class constants, for methods class x { const ARRAY = array(1,2,3,4,5,6,7,8,9,10,11); function foo() { array = self::ARRAY; //more code } } // with properties, for methods class x { private array = array(1,2,3,4,5,6,7,8,9,10,11); function foo() { array = this->array; //more code } } // injection, leveraging default values function foo(array = array(1,2,3,4,5,6,7,8,9,10,11)) { //more code } // local cache with static function foo() { static array; if (array === null) { array = array(1,2,3,4,5,6,7,8,9,10,11); } //more code } // Avoid creating the same array all the time in a function class x { function foo() { // assign to non local variable is OK. // Here, to a property, though it may be better in a '__construct or as default values this->s = array(1,2,3,4,5,6,7,8,9,10,11); // This is wasting resources, as it is done each time. array = array(1,2,3,4,5,6,7,8,9,10,11); } } ?>   Command Line Structures/NoAssignationInFunction Analyzers Performances ## Avoid Non Wordpress Globals¶ Refren using any global variable that is not Wordpress’s own. Global variables are available for write and read across the whole application, making their data both easily accessible, and difficult to track when a unexpected change happen. It is recommended to rely on a mix of arguments passing and classes structures to reduce the code of any variable to a smaller part of the code. <?php my_hook() { // This is a Wordpress global GLOBALS['is_safari'] = true; // is_iphone7 is not a Wordpress variable global is_iphone7; } ?>  See also Global Variables  Command Line Wordpress/AvoidOtherGlobals Analyzers Wordpress ## Avoid Parenthesis¶ Avoid Parenthesis for language construct. Languages constructs are a few PHP native elements, that looks like functions but are not. Among other distinction, those elements cannot be directly used as variable function call, and they may be used with or without parenthesis. The usage of parenthesis actually give some feeling of confort, it won’t prevent PHP from combining those argument with any later operators, leading to unexpected results. Even if most of the time, usage of parenthesis is legit, it is recommended to avoid them.  Command Line Structures/PrintWithoutParenthesis Analyzers Analyze ## Avoid Those Hash Functions¶ The following cryptographic algorithms are considered unsecure, and should be replaced with new and more performant algorithms. MD2, MD4, MD5, SHA0, SHA1, CRC, DES, 3DES, RC2, RC4. When possible, avoid using them, may it be as PHP functions, or hashing function configurations (mcrypt, hash...). <?php // Weak cryptographic algorithm echo md5('The quick brown fox jumped over the lazy dog.'); // Weak crypotgraphic algorthim, used with a modern PHP extension (easier to update) echo hash('md5', 'The quick brown fox jumped over the lazy dog.'); // Strong crypotgraphic algorthim, used with a modern PHP extension echo hash('sha156', 'The quick brown fox jumped over the lazy dog.'); ?>  Weak crypto are commonly used for hashing values when caching them. In such cases, security is not a primary concern. However, it may later become such, when hackers get access to the cache folders, or if the cached identifier is published. As a preventive protection, it is recommended to always use a secure hashing function. See also  <https://en.wikipedia.org/wiki/Secure_Hash_Algorithms>_.  Command Line Security/AvoidThoseCrypto Analyzers Security ## Avoid Using stdClass¶ stdClass is the default class for PHP. It is instantiated when PHP needs to return a object, but no class is specifically available. It is recommended to avoid instantiating this class, nor use it is any way. <?php json = '{a:1,b:2,c:3}'; object = json_decode(json); // object is a stdClass, as returned by json_decode // Fast building of o a = []; a['a'] = 1; a['b'] = 2; a['c'] = 3; json_encode( (object) a); // Slow building of o o = new stdClass(); o->a = 1; o->b = 2; o->c = 3; json_encode(o); ?>  If you need a stdClass object, it is faster to build it as an array, then cast it, than instantiate stdClass. This is a micro-optimisation.  Command Line Php/UseStdclass Analyzers Analyze ## Avoid array_push()¶ ‘array_push() is slower than the [] operator. This is also true if the [] operator is called several times, while ‘array_push() may be called only once. And using count after the push is also faster than collecting ‘array_push() return value. <?php a = [1,2,3]; // Fast version a[] = 4; a[] = 5; a[] = 6; a[] = 7; count = count(a); // Slow version array_push(a, 4); count = array_push(a, 5,6,7); // Multiple version : a[] = 1; a[] = 2; a[] = 3; array_push(a, 1, 2, 3); ?>  This is a micro-optimisation.  Command Line Performances/AvoidArrayPush Analyzers Performances ## Avoid array_unique()¶ The native function ‘array_unique() is much slower than using other alternative, such as ‘array_count_values(), ‘array_flip()/‘array_keys(), or even a ‘foreach() loops. <?php // using 'array_unique() uniques = array_unique(someValues); // When values are strings or integers uniques = array_keys(array_count_values(someValues)); uniques = array_flip(array_flip(someValues)) //even some loops are faster. uniques = []; foreach(someValues as s) { if (!in_array(uniques, s)) { uniques[] s; } } ?>   Command Line Structures/NoArrayUnique Analyzers Performances ## Avoid get_class()¶ get_class() should be replaced with the ‘instanceof operator to check the class of an object. get_class() will only compare the full namespace name of the object’s class, while ‘instanceof actually resolve the name, using the local namespace and aliases. <?php use Stdclass as baseClass; function foo(arg) { // Slow and prone to namespace errors if (get_class(arg) === 'Stdclass') { // doSomething() } } function bar(arg) { // Faster, and uses aliases. if (arg 'instanceof baseClass) { // doSomething() } } ?>   Command Line Structures/UseInstanceof Analyzers none ## Avoid sleep()/usleep()¶ ‘sleep() and ‘usleep() help saturate the web server. Pausing the script for a specific amount of time means that the Web server is also making all related ressources sleep, such as database, sockets, session, etc. This may used to set up a DOS on the server. <?php begin = microtime(true); checkLogin(user, password); end = microtime(true); // Making all login checks looks the same usleep(1000000 - (end - begin) * 1000000); // Any hit on this page now uses 1 second, no matter if load is high or not // Is it now possible to saturate the webserver in 1 s ? ?>  As much as possible, avoid delaying the end of the script. ‘sleep() and ‘usleep() have less impact in commandline (CLI).  Command Line Security/NoSleep Analyzers Security ## Bail Out Early¶ When using conditions, it is recommended to return in the then, and avoid else clause. The main benefit is to make clear the method applies a condition, and stop quickly went it is not satisfied. The main sequence is then focused on the useful code. This works with ‘break, ‘continue too, inside loops. <?php // Bailing out early, low level of indentation function foo1(a) { if (a > 0) { return false; } a++; return a; } // Works with 'continue too foreach(array as a => b) { if (a > 0) { 'continue false; } a++; return a; } // No need for else function foo2(a) { if (a > 0) { return false; } else { a++; } return a; } // No need for else : return goes into then. function foo3(a) { if (a < 0) { a++; } else { return false; } return a; } ?>   Command Line Structures/BailOutEarly Analyzers Analyze ## Binary Glossary¶ List of all the integer values using the binary format. <?php a = 0b10; b = 0B0101; ?>   Command Line Type/Binary Analyzers CompatibilityPHP53 ## Bracketless Blocks¶ PHP allows one liners as ‘for(), ‘foreach(), ‘while(), ‘do..while() loops, or as then/else expressions. It is generally considered a bad practice, as readability is lower and there are non-négligeable risk of excluding from the loop the next instruction. <?php // Legit one liner foreach(range('a', 'z') as letter) ++letterCount; // More readable version, even for a one liner. foreach(range('a', 'z') as letter) { ++letterCount; } ?>  ‘switch() cannot be without bracket.  Command Line Structures/Bracketless Analyzers Coding Conventions ## Break Outside Loop¶ Starting with PHP 7, ‘break or ‘continue that are outside a loop (for, ‘foreach(), do...’while() <http://php.net/manual/en/control-structures.while.php>_, ‘while()) or a ‘switch() statement won’t compile anymore. It is not possible anymore to include a piece of code inside a loop that will then ‘break. <?php // outside a loop : This won't compile 'break 1; foreach(array as a) { 'break 1; // Compile OK 'break 2; // This won't compile, as this 'break is in one loop, and not 2 } foreach(array as a) { foreach(array2 as a2) { 'break 2; // OK in PHP 5 and 7 } } ?>   Command Line Structures/BreakOutsideLoop Analyzers Analyze, CompatibilityPHP70, CompatibilityPHP71 ## Break With 0¶ Cannot ‘break 0, as this makes no sense. Break 1 is the minimum, and is the default value. <?php // Can't 'break 0. Must be 1 or more, depending on the level of nesting. for(i = 0; i < 10; i++) { 'break 0; } for(i = 0; i < 10; i++) { for(j = 0; j < 10; j++) { 'break 2; } } ?>   Command Line Structures/Break0 Analyzers Analyze, CompatibilityPHP53 ## Break With Non Integer¶ When using a ‘break, the argument of the operator must be a positive non-null integer literal or be omitted. Other values were acceptable in PHP 5.3 and previous version, but this is now reported as an error. <?php // Can't 'break a, even if it contains an integer. a = 1; for(i = 0; i < 10; i++) { 'break a; } // can't 'break on float for(i = 0; i < 10; i++) { for(j = 0; j < 10; j++) { 'break 2.2; } } ?>   Command Line Structures/BreakNonInteger Analyzers Analyze, CompatibilityPHP54, CompatibilityPHP70, CompatibilityPHP55, CompatibilityPHP56, CompatibilityPHP71 ## Buried Assignation¶ Those assignations are buried in the code, and placed in unexpected situations. They will be difficult to spot, and may be confusing. It is advised to place them in a more visible place.  Command Line Structures/BuriedAssignation Analyzers Analyze ## CakePHP 2.5.0 Undefined Classes¶ CakePHP classes, interfaces and traits that are not defined in version 2.5.0.  Command Line Cakephp/Cakephp25 Analyzers Cakephp ## CakePHP 2.6.0 Undefined Classes¶ CakePHP classes, interfaces and traits that are not defined in version 2.6.0. 5 new classes  Command Line Cakephp/Cakephp26 Analyzers Cakephp ## CakePHP 2.7.0 Undefined Classes¶ CakePHP classes, interfaces and traits that are not defined in version 2.7.0. 12 new classes 2 removed classes  Command Line Cakephp/Cakephp27 Analyzers Cakephp ## CakePHP 2.8.0 Undefined Classes¶ CakePHP classes, interfaces and traits that are not defined in version 2.8.0. 8 new classes  Command Line Cakephp/Cakephp28 Analyzers Cakephp ## CakePHP 2.9.0 Undefined Classes¶ CakePHP classes, interfaces and traits that are not defined in version 2.9.0. 16 new classes 2 removed classes  Command Line Cakephp/Cakephp29 Analyzers Cakephp ## CakePHP 3.0 Deprecated Class¶ According to the Cake 3.0 migration guide, the following class is deprecated and should be removed. • Set (CakeUtilitySet) : replace it with Hash (CakeUtilityHash)  Command Line Cakephp/Cake30DeprecatedClass Analyzers Cakephp ## CakePHP 3.0.0 Undefined Classes¶ CakePHP classes, interfaces and traits that are not defined in version 3.0.0. 754 new classes 13 new interfaces 34 new traits 1062 removed classes 7 removed interfaces  Command Line Cakephp/Cakephp30 Analyzers Cakephp ## CakePHP 3.1.0 Undefined Classes¶ CakePHP classes, interfaces and traits that are not defined in version 3.1.0. 64 new classes 5 new interfaces 5 new traits 16 removed classes  Command Line Cakephp/Cakephp31 Analyzers Cakephp ## CakePHP 3.2.0 Undefined Classes¶ CakePHP classes, interfaces and traits that are not defined in version 3.2.0. 27 new classes 4 new interfaces 4 new traits 1 removed classe  Command Line Cakephp/Cakephp32 Analyzers Cakephp ## CakePHP 3.3 Deprecated Class¶ According to the Cake 3.3 migration guide, the following class is deprecated and should be removed. • Mcrypt (CakeUtilityCryptoMcrypt) : replace it with CakeUtilityCryptoOpenssl or ext/openssl  Command Line Cakephp/Cake33DeprecatedClass Analyzers Cakephp ## CakePHP 3.3.0 Undefined Classes¶ CakePHP classes, interfaces and traits that are not defined in version 3.3.0. 93 new classes 5 new interfaces 1 new trait 19 removed classes 1 removed interface  Command Line Cakephp/Cakephp33 Analyzers Cakephp ## CakePHP 3.4.0 Undefined Classes¶ CakePHP classes, interfaces and traits that are not defined in version 3.4.0. 41 new classes 1 new interface 1 new trait 16 removed classes 2 removed traits  Command Line Cakephp/Cakephp34 Analyzers Cakephp ## CakePHP Used¶ CakePHP classes, interfaces and traits being used in the code.  Command Line Cakephp/CakePHPUsed Analyzers Cakephp ## Calltime Pass By Reference¶ PHP doesn’t allow when a value is turned into a reference at functioncall, since PHP 5.4. Either the function use a reference in its signature, either the reference won’t pass.  Command Line Structures/CalltimePassByReference Analyzers Analyze, CompatibilityPHP54, CompatibilityPHP70, CompatibilityPHP55, CompatibilityPHP56, CompatibilityPHP71 ## Can’t Extend Final¶ It is not possible to extend final classes. Since PHP fails with a fatal error, this means that the extending class is probably not used in the rest of the code. Check for dead code. <?php // File Foo final class foo { public final function bar() { // doSomething } } ?>  In a separate file : <?php // File Bar class bar extends foo { } ?>   Command Line Classes/CantExtendFinal Analyzers Analyze, Dead code ## Cant Use Return Value In Write Context¶ Until PHP 5.5, it was not possible to use directly function calls inside an ‘empty() function call : they were met with a ‘Can’t use function return value in write context’ fatal error. <?php function foo(boolean) { return boolean; } // Valid since PHP 5.5 echo empty(foo(true)) : 'true' : 'false'; ?>  This also applies to methodcalls, static or not.  Command Line Php/CantUseReturnValueInWriteContext Analyzers CompatibilityPHP53, CompatibilityPHP54 ## Cast To Boolean¶ This expression may be reduced by casting to boolean type. <?php variable = condition == 'met' ? 1 : 0; // Same as variable = (bool) condition == 'met'; variable = condition == 'met' ? 0 : 1; // Same as (Note the condition inversion) variable = (bool) condition != 'met'; // also, with an indentical condition variable = !(bool) condition == 'met'; ?>   Command Line Structures/CastToBoolean Analyzers Analyze ## Catch Overwrite Variable¶ The try...catch structure uses some variables that also in use in this scope. In case of a caught exception, the exception will be put in the catch variable, and overwrite the current value, loosing some data. It is recommended to use another name for these catch variables.  Command Line Structures/CatchShadowsVariable clearPHP no-catch-overwrite Analyzers Analyze ## Check All Types¶ When checking for time, avoid using else. Mention explicitely all tested type, and raise an exception when reaching else. PHP has a short list of scalar types : null, boolean, integer, real, strings, object, resource and array. When a variable is not holding one the the type, then it may be of any other type. Most of the time, when using a simple is_*() / else test, this is relying on the conception of the code. By construction, the arguments may be one of two types : array or string. What happens often is that in case of failure in the code (database not working, another class not checking its results), a third type is pushed to the structure, and it ends up breaking the execution. The safe way is to check the various types all the time, and use the default case (here, the else) to throw exception() or test an assertion and handle the special case. <?php // hasty version if (is_array(argument)) { out = argument; } else { // Here, argument is NOT an array. What if it is an object ? or a NULL ? out = array(argument); } // Safe type checking : do not assume that 'not an array' means that it is the other expected type. if (is_array(argument)) { out = argument; } elseif (is_string(argument)) { out = array(argument); } else { assert(false, 'argument is not an array nor a string, as expected!'); } ?>  Using ‘is_callable(), is_iterable() with this structure is fine : when variable is callable or not, while a variable is an integer or else. Using a type test without else is also accepted here. This is a special treatment for this test, and all others are ignored. This aspect may vary depending on situations and projects.  Command Line Structures/CheckAllTypes Analyzers Analyze ## Class Const With Array¶ Constant defined with const keyword may be arrays but only stating with PHP 5.6. Define never accept arrays : it only accepts scalar values.  Command Line Php/ClassConstWithArray Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55 ## Class Function Confusion¶ Avoid classes and functions bearing the same name. When functions and classes bear the same name, calling them may be confusing. This may also lead to forgotten ‘new’ keyword. <?php class foo {} function foo() {} // Forgetting the 'new' operator is easy object = new foo(); object = foo(); ?>   Command Line Php/ClassFunctionConfusion Analyzers Analyze ## Class Name Case Difference¶ The spotted classes are used with a different case than their definition. While PHP accepts this, it makes the code harder to read. It may also be a violation of coding conventions. <?php // This use statement has wrong case for origin. use Foo as X; // Definition of the class class foo {} // Those instantiations have wrong case new FOO(); new X(); ?>   Command Line Classes/WrongCase Analyzers Coding Conventions, Analyze ## Class Should Be Final By Ocramius¶ ‘Make your classes always final, if they implement an interface, and no other public methods are defined’. When a class should be final, as explained by Ocramiux (Marco Pivetta). Full article : When to declare classes final. <?php interface i1 { function i1() ; } // Class should final, as its public methods are in an interface class finalClass implements i1 { // public interface function i1 () {} // private method private function a1 () {} } ?>   Command Line Classes/FinalByOcramius Analyzers Analyze ## Class, Interface Or Trait With Identical Names¶ The following names are used at the same time for classes, interfaces or traits. For example, class a {} interface a {} trait a {} Even if they are in different namespaces, this makes them easy to confuse. Besides, it is recommended to have markers to differentiate classes from interfaces from traits.  Command Line Classes/CitSameName Analyzers Analyze ## Classes Mutually Extending Each Other¶ Those classes are extending each other, creating an extension loop. PHP will yield a fatal error at running time, even if it is compiling the code. <?php // This code is lintable but won't run class Foo extends Bar { } class Bar extends Foo { } // The loop may be quite large class Foo extends Bar { } class Bar extends Bar2 { } class Bar2 extends Foo { } ?>   Command Line Classes/MutualExtension Analyzers Analyze ## Close Tags¶ PHP manual recommends that script should be left open, without the final closing ?>. This way, one will avoid the infamous bug ‘Header already sent’, associated with left-over spaces, that are lying after this closing tag.  Command Line Php/CloseTags clearPHP leave-last-closing-out Analyzers Coding Conventions ## Closure May Use this¶ When closure were introduced in PHP, they couldn’t use the this variable, making is cumbersome to access local properties when the closure was created within an object. This is not the case anymore since PHP 5.4.  Command Line Php/ClosureThisSupport Analyzers Analyze, CompatibilityPHP53 ## Common Alternatives¶ In the following conditional structures, expressions were found that are common to both ‘then’ and ‘else’. It may be interesting, though not always possible, to put them both out of the conditional, and reduce line count. <?php if (c == 5) { b = strtolower(b[2]); a++; } else { b = strtolower(b[2]); b++; } ?>  may be rewritten in : <?php b = strtolower(b[2]); if (c == 5) { a++; } else { b++; } ?>   Command Line Structures/CommonAlternatives Analyzers Analyze ## Compare Hash¶ When comparing hash values, it is important to use the strict comparison : === or !==. In a number of situations, the hash value will start with ‘0e’, and PHP will understand that the comparison involves integers : it will then convert the strings into numbers, and it may end up converting them to 0. Here is an example <?php // The two following passwords hashes matches, while they are not the same. hashed_password = 0e462097431906509000000000000; if (hash('md5','240610708',false) == hashed_password) { print Matched.\n; } ?>  You may also use ‘password_hash() and ‘password_verify(). See also Magic Hashes.  Command Line Security/CompareHash clearPHP strict-comparisons Analyzers Security ## Compared Comparison¶ Usually, comparison are sufficient, and it is rare to have to compare the result of comparison. Check if this two-stage comparison is really needed.  Command Line Structures/ComparedComparison Analyzers Analyze ## Concrete Visibility¶ Methods that implements an interface in a class must be public. PHP doesn’t lint this, but won’t start a script with a Fatal error : ‘Access level to c::iPrivate() must be public (as in class i) ‘; <?php interface i { function iPrivate() ; function iProtected() ; function iPublic() ; } class c implements i { // Methods that implements an interface in a class must be public. private function iPrivate() {} protected function iProtected() {} public function iPublic() {} } ?>  See also Interfaces.  Command Line Interfaces/ConcreteVisibility Analyzers Analyze ## Confusing Names¶ The following variables’s name are very close and may lead to confusion. Variables are 3 letters long (at least). Variables names build with an extra ‘s’ are omitted. Variables may be scattered across the code, or close to each other. <?php // Variable names with one letter difference fWScale = 1; fHScale = 1; fScale = 2; oFrame = 3; iFrame = new Foo(); v2_norm = array(); v1_norm = 'string'; exept11 = 1; exept10 = 2; exept8 = 3; // This even looks like a typo privileges = 1; privilieges = true; // This is not reported : Adding extra s is tolerated. rows[] = row; ?>   Command Line Variables/CloseNaming Analyzers Analyze ## Const With Array¶ The const keyword supports array since PHP 5.6.  Command Line Php/ConstWithArray Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55 ## Constant Class¶ A class or an interface only made up of constants. Constants usually have to be used in conjunction of some behavior (methods, class...) and never alone. As such, they should be PHP constants (build with define or const), or included in a class with other methods and properties.  Command Line Classes/ConstantClass Analyzers Analyze ## Constant Comparison¶ Constant to the left or right is a favorite. Comparisons are commutative : they may be a == B or B == a. The analyzed code show less than 10% of one of the two : for consistency reasons, it is recommended to make them all the same. Putting the constant on the left is also called ‘Yoda Comparison’, as it mimics the famous characters style of speech. It prevents errors like ‘B = a’ where the comparison is turned into an assignation. The natural way is to put the constant on the right. It is often less surprising. Every comparison operator is used when finding the favorite. <?php // if (a === B) { doSomething(); } if (c > D) { doSomething(); } if (e !== G) { doSomething(); } do { doSomething(); } while (f === B); while (a === B) { doSomething(); } // be consistent if (B === a) {} // Compari if (B <= a) {} ?>   Command Line Structures/ConstantComparisonConsistance Analyzers Coding Conventions ## Constant Scalar Expressions¶ Starting with PHP 5.6, it is possible to define constant that are the result of expressions. Those expressions (using simple operators) may only manipulate other constants, and all values must be known at compile time. This is not compatible with previous versions.  Command Line Structures/ConstantScalarExpression Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55 ## Constants Created Outside Its Namespace¶ Constants Created Outside Its Namespace. Using the ‘define() function, it is possible to create constant outside their namespace, but using the fully qualified namespace. <?php namespace A\B { // define A\B\C as 1 define('C', 1); } namespace D\E { // define A\B\C as 1, while outside the A\B namespace define('A\B\C', 1); } ?>  However, this makes the code confusing and difficult to debug. It is recommended to move the constant definition to its namespace.  Command Line Constants/CreatedOutsideItsNamespace Analyzers Analyze ## Constants With Strange Names¶ List of constants being defined with names that are incompatible with PHP standards. <?php // Define a valid PHP constant define('ABC', 1); const ABCD = 2; // Define an invalid PHP constant define('ABC!', 1); echo defined('ABC!') ? constant('ABC!') : 'Undefined'; // Const doesn't allow illegal names ?>   Command Line Constants/ConstantStrangeNames Analyzers Analyze ## Could Be Class Constant¶ When a property is defined and read, but never modified, it may be a constant. <?php class foo { // this->bar is never modified. private bar = 1; // this->foofoo is modified, at least once private foofoo = 2; function method(a) { this->foofoo = this->bar + a + this->foofoo; return this->foofoo; } } ?>  Starting with PHP 5.6, even array() may be defined as constants.  Command Line Classes/CouldBeClassConstant Analyzers Analyze ## Could Be Protected Property¶ Those properties are declared public, but are never used publicly. They may be made protected. <?php class foo { // Public, and used publicly public publicProperty; // Public, but never used outside the class or its children public protectedProperty; function bar() { this->protectedProperty = 1; } } foo = new Foo(); foo->publicProperty = 3; ?>  This property may even be made private.  Command Line Classes/CouldBeProtectedProperty Analyzers Analyze ## Could Be Static¶ This global is only used in one function or method. It may be called ‘static’, instead of global. This allows you to keep the value between call to the function, but will not be accessible outside this function. <?php function foo( ) { static variableIsReservedForX; // only accessible within foo( ), even between calls. global variableIsGlobal; // accessible everywhere in the application } ?>   Command Line Structures/CouldBeStatic Analyzers Analyze ## Could Be Typehinted Callable¶ Those arguments may use the callable Typehint. ‘callable’ is a PHP keyword that represents callback functions. Those may be used in dynamic function call, like function(); or as callback functions, like with ‘array_map(); callable may be a string representing a function name or a static call (including ::), an array with two elements, (a class or object, and a method), or a closure. When arguments are used to call a function, but are not marked with ‘callable’, they are reported by this analysis. <?php function foo(callable callable) { // very simple callback return callable(); } function foo2(array, callable) { // very simple callback return array_map(array, callable); } ?>  See also Callback / callable.  Command Line Functions/CouldBeCallable Analyzers Analyze ## Could Make A Function¶ When a function is called across the code with the same arguments often enough, it should be turned into a local API. This approach is similar to turning literals into constants : it centralize the value, it helps refactoring by updating it. It also makes the code more readable. Moreover, it often highlight common grounds between remote code locations. The analysis looks for functions calls, and checks the arguments. When the calls occurs more than 4 times, it is reported. <?php // str_replace is used to clean '&' from strings. // It should be upgraded to a central function function foo(arg ) { arg = str_replace('&', '', arg); // do something with arg } class y { function bar(database ) { value = database->queryName(); value = str_replace('&', '', value); // value = removeAmpersand(value); // do something with arg2 } } // helper function function removeAmpersand(string) { return str_replace('&', '', string); } ?>   Command Line Functions/CouldCentralize Analyzers Analyze ## Could Return Void¶ The following functions may bear the Void return typeHint. <?php // This can be Void function foo(&a) { ++a; return; } // This can't be Void function bar(a) { ++a; return a; } ?>   Command Line Functions/CouldReturnVoid Analyzers Analyze ## Could Typehint¶ Arguments that are tested with ‘instanceof gain from making it a Typehint. <?php function foo(a, b) { // a is tested for B with 'instanceof. if (!a 'instanceof B) { return; } // More code } function foo(B a, b) { // May omit the initial test // More code } ?>   Command Line Functions/CouldTypehint Analyzers Analyze ## Could Use Alias¶ This long name may be reduced by using an available alias. <?php use a\b\c; // This may be reduced with the above alias new a\b\c\d(); // This too new a\b\c\d\e\f(); // This yet again new a\b\c(); ?>   Command Line Namespaces/CouldUseAlias Analyzers Analyze ## Could Use Short Assignation¶ Some operators have a compact ‘do-and-assign’ version. They looks like a compacted version for = and the operator. This syntax is good for readability, and saves some memory in the process. <?php a = a + 0; a += 0; b = b - 1; b -= 1; c = c * 2; c *= 2; d = d / 3; d /= 3; e = e % 4; e %= 4; f = f | 5; f |= 5; g = g & 6; g &= 6; h = h ^ 7; h ^= 7; i = i >> 8; i >>= 8; j = j << 9; j <<= 9; ?>   Command Line Structures/CouldUseShortAssignation clearPHP use-short-assignations Analyzers Analyze, Performances ## Could Use __DIR__¶ Use ‘__DIR__ function to access the current file’s parent directory. <?php assert(dirname('__FILE__) == '__DIR__); ?>  ‘__DIR__ has been introduced in PHP 5.3.0.  Command Line Structures/CouldUseDir Analyzers Analyze ## Could Use self¶ ‘self’ keyword refers to the current class, or any of its parents. Using it is just as fast as the full classname, it is as readable and it is will not be changed upon class or namespace change. It is also routinely used in traits : there, ‘self’ represents the class in which the trait is used, or the trait itself. <?php class x { const FOO = 1; public function bar() { return self::FOO; // same as return x::FOO; } } ?>   Command Line Classes/ShouldUseSelf Analyzers Analyze ## Could Use str_repeat()¶ Use ‘str_repeat() or ‘str_pad() instead of making a loop. Making a loop to repeat the same concatenation is actually much longer than using str_repeat. As soon as the loop repeats more than twice, ‘str_repeat() is much faster. With arrays of 30, the difference is significative, though the whole operation is short by itself. <?php // This adds 7 'e' to x x .= str_repeat('e', 7); // This is the same as above, for(a = 3; a < 10; ++a) { x .= 'e'; } // here, default must contains 7 elements to be equivalent to the previous code foreach(default as c) { x .= 'e'; } ?>   Command Line Structures/CouldUseStrrepeat Analyzers Analyze ## Courrier Anti-Pattern¶ The courrier anti-pattern is the storage of a dependency by a class, in order to create an instance that requires this dependendy. The class itself doesn’t actually need this dependency, but has de dependency to a class that requires it. <?php // The foo class requires bar class Foo { public function '__construct(Bar b) { } } // Class A doesn't depends on Bar, but depends on Foo // Class A never uses Bar, but only uses Foo. class A { private courrier; public function '__construct(Bar courrier) { this->courrier = courrier; } public function Afoo() { b = new Foo(this->courrier); } } ?>  The alternative here is to inject Foo instead of Bar. See also Courrier Anti-pattern.  Command Line Patterns/CourrierAntiPattern Analyzers Analyze ## Crc32() Might Be Negative¶ ‘crc32() may return a negative number, on 32bits platforms. According to the manual : Because PHP’s integer type is signed many crc32 checksums will result in negative integers on 32bit platforms. On 64bit installations all ‘crc32() results will be positive integers though. <?php // display the checksum with %u, to make it unsigned echo sprintf('%u', crc32(str)); // turn the checksum into an unsigned hexadecimal echo dechex(crc32(str)); // avoid concatenating crc32 to a string, as it may be negative on 32bits platforms echo 'prefix'.crc32(str); ?>  See also crc32().  Command Line Php/Crc32MightBeNegative Analyzers Analyze ## Curly Arrays¶ It is possible to access individual elements in an array by using its offset between square brackets [] or curly brackets {}. Curly brackets are seldom used, and will probably confuse or surprise the reader. It is recommended not to used them.  Command Line Arrays/CurlyArrays Analyzers Coding Conventions ## Dangling Array References¶ Always unset a referenced-variable used in a loop. It is highly recommended to unset blind variables when they are set up as references after a loop. <?php array = array(1,2,3,4); foreach(array as &a) { a += 1; } // This only unset the reference, not the value unset(a); // Dangling array problem foreach(array as &a) { a += 1; } //array === array(3,4,5,6); // This does nothing (apparently) foreach(array as a) {} //array === array(3,4,5,6); ?>  When omitting this step, the next loop that will also require this variable will deal with garbage values, and produce unexpected results. See also : No Dangling Reference.  Command Line Structures/DanglingArrayReferences clearPHP no-dangling-reference Analyzers Analyze ## Deep Definitions¶ Structures, such as functions, classes, interfaces, traits, etc. may be defined anywhere in the code, including inside functions. This is legit code for PHP. Since the availability of __autoload, there is no need for that kind of code. Structures should be defined, and accessible to the autoloading. Inclusion and deep definitions should be avoided, as they compell code to load some definitions, while autoloading will only load them if needed. Functions are excluded from autoload, but shall be gathered in libraries, and not hidden inside other code. Constants definitions are tolerated inside functions : they may be used for avoiding repeat, or noting the usage of such function.  Command Line Functions/DeepDefinitions Analyzers Analyze ## Define With Array¶ PHP 7.0 has the ability to define an array as a constant, using the ‘define() native call. This was not possible until that version, only with the const keyword.  Command Line Php/DefineWithArray Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56 ## Dependant Trait¶ Traits should be autonomous. It is recommended to avoid depending on methods or properties that should be in the using class. The following traits make usage of methods and properties, static or not, that are not defined in the trait. This means the host class must provide those methods and properties, but there is no way to enforce this. This may also lead to dead code : when the trait is removed, the host class have unused properties and methods. <?php // autonomous trait : all it needs is within the trait trait t { private p = 0; function foo() { return ++this->p; } } // dependant trait : the host class needs to provide some properties or methods trait t2 { function foo() { return ++this->p; } } class x { use t2; private p = 0; } ?>   Command Line Traits/DependantTrait Analyzers Analyze ## Deprecated Code¶ The following functions have been deprecated in PHP. Whatever the version you are using, it is recommended to stop using them and replace them with a durable equivalent.  Command Line Php/Deprecated clearPHP no-deprecated Analyzers Analyze ## Deprecated Methodcalls in Cake 3.2¶ According to the Cake 3.2 migration guide, the following are deprecated and should be changed. • Shell::error() • CakeDatabaseExpressionQueryExpression::type() • CakeORMResultSet::_calculateTypeMap() • CakeORMResultSet::_castValues()  Command Line Cakephp/Cake32DeprecatedMethods Analyzers Cakephp ## Deprecated Methodcalls in Cake 3.3¶ According to the Cake 3.3 migration guide, the following are deprecated and should be changed. • Shell::error()  Command Line Cakephp/Cake33DeprecatedMethods Analyzers Cakephp ## Deprecated Static calls in Cake 3.3¶ According to the Cake 3.3 migration guide, the following are deprecated and should be changed. • Router::mapResources() is deprecated. Use routing scopes and routes->resources() instead. • Router::redirect() is deprecated. Use routing scopes and routes->redirect() instead.  Command Line Cakephp/Cake33DeprecatedStaticmethodcall Analyzers Cakephp ## Deprecated Trait in Cake 3.3¶ According to the Cake 3.3 migration guide, the following are deprecated and should be changed. • CakeRoutingRequestActionTrait  Command Line Cakephp/Cake33DeprecatedTraits Analyzers Cakephp ## Dereferencing String And Arrays¶ PHP 5.5 introduced the direct dereferencing of strings and array. No need anymore for an intermediate variable between a string and array (or any expression generating such value) and accessing an index. x = array(4,5,6); y = x[2] ; // is 6 May be replaced by y = array(4,5,6)[2]; y = [4,5,6][2];  Command Line Structures/DereferencingAS Analyzers CompatibilityPHP53, CompatibilityPHP54 ## Direct Injection¶ The following code act directly upon PHP incoming variables like _GET and _POST. This make those snippet very unsafe.  Command Line Security/DirectInjection Analyzers Security ## Don’t Change Incomings¶ PHP hands over a lot of information using special variables like _GET, _POST, etc... Modifying those variables and those values inside de variables means that the original content is lost, while it will still look like raw data, and, as such, will be untrustworthy. <?php // filtering and keeping the incoming value. _DATA'id'] = (int) _GET['id']; // filtering and changing the incoming value. _GET['id'] = strtolower(_GET['id']); ?>  It is recommended to put the modified values in another variable, and keep the original one intact.  Command Line Structures/NoChangeIncomingVariables Analyzers Analyze ## Dont Change The Blind Var¶ When using a ‘foreach(), the blind variables are a copy. It is confusing to change them. <?php foo = [1, 2, 3]; foreach(foo as bar) { // bar is updated but its final value is lost print bar . ' => ' . (bar + 1) . PHP_EOL; // if bar + 1 is repeated several times, consider assigning it to a variable. foobar(bar + 1); } foo = [1, 2, 3]; foreach(foo as bar) { // bar is updated but its final value is lost print bar . ' => ' . (++bar) . PHP_EOL; // Now that bar is reused, it is easy to confuse its value foobar(bar); } ?>   Command Line Structures/DontChangeBlindKey Analyzers Analyze ## Dont Echo Error¶ It is recommended to avoid displaying error messages directly to the browser. <?php // Inside a 'or' test mysql_connect('localhost', user, pass) or 'die(mysql_error()); // Inside a if test result = pg_query( db, query ); if( !result ) { echo Erreur SQL: . pg_error(); 'exit; } ?>  Error messages should be logged, but not displayed.  Command Line Security/DontEchoError Analyzers Analyze, Security ## Double Assignation¶ This happens when a container (variable, property, array index) is assigned with values twice in a row. One of them is probably a debug instruction, that was forgotten. <?php // Normal assignation a = 1; // Double assignation b = 2; b = 3; ?>   Command Line Structures/DoubleAssignation Analyzers Analyze ## Double Instructions¶ Twice the same call in a row. This is worth a check. <?php ?>   Command Line Structures/DoubleInstruction Analyzers Analyze ## Drop Else After Return¶ Avoid else clause when the then clause returns, but not the else. The else may simply be set in the main sequence of the function. This is also true if else has a return, and then not : simply reverse the condition. <?php // drop the else if (a) { return a; } else { doSomething(); } // drop the then if (b) { doSomething(); } else { return a; } // return in else and then if (a3) { return a; } else { b = doSomething(); return b; } ?>   Command Line Structures/DropElseAfterReturn Analyzers Analyze ## Echo Or Print¶ Echo and print have the same functional use. <?= is also considered in this analysis. There seems to be a choice that is not enforced : one form is dominent, (> 90%) while the others are rare. The analyzed code has less than 10% of one of the three : for consistency reasons, it is recommended to make them all the same. It happens that print, echo or <?= are used depending on coding style and files. One file may be consistently using print, while the others are all using echo. <?php echo 'a'; echo 'b'; echo 'c'; echo 'd'; echo 'e'; echo 'f'; echo 'g'; echo 'h'; echo 'i'; echo 'j'; echo 'k'; // This should probably be written 'echo'; print 'l'; ?>   Command Line Structures/EchoPrintConsistance Analyzers Coding Conventions ## Echo With Concat¶ Optimize your echo’s by not concatenating at echo() time, but serving all argument separated. This will save PHP a memory copy. If values (literals and variables) are small enough, this won’t have impact. Otherwise, this is less work and less memory waste. <?php echo a, ' b ', c; ?>  instead of <?php echo a . ' b ' . c; echo a b c; ?>   Command Line Structures/EchoWithConcat clearPHP no-unnecessary-string-concatenation Analyzers Performances, Analyze ## Else If Versus Elseif¶ Always use elseif instead of else and if. “The keyword elseif SHOULD be used instead of else if so that all control keywords look like single words”. Quoted from the PHP-FIG documentation <?php // Using elseif if (a == 1) { doSomething(); } elseif (a == 2) { doSomethingElseIf(); } else { doSomethingElse(); } // Using else if if (a == 1) { doSomething(); } else if (a == 2) { doSomethingElseIf(); } else { doSomethingElse(); } // Using else if, no {} if (a == 1) doSomething(); else if (a == 2) doSomethingElseIf(); else doSomethingElse(); ?>  .  Command Line Structures/ElseIfElseif Analyzers Analyze ## Empty Blocks¶ The listed control structures are empty, or have one of the commanded block empty. It is recommended to remove those blocks, so as to reduce confusion in the code. <?php foreach(foo as bar) ; // This block seems erroneous foobar++; if (a === b) { doSomething(); } else { // Empty block. Remove this } // Blocks containing only empty expressions are also detected for(i = 0; i < 10; i++) { ; } // Although namespaces are not control structures, they are reported here namespace A; namespace B; ?>   Command Line Structures/EmptyBlocks Analyzers Analyze ## Empty Classes¶ List of empty classes. Classes that are directly derived from an exception are omited. <?php //Empty class class foo extends bar {} //Not an empty class class foo2 extends bar { const FOO = 2; } //Not an empty class, as derived from Exception class barException extends \Exception {} ?>   Command Line Classes/EmptyClass Analyzers Analyze ## Empty Function¶ Function or method whose body is empty. Such functions or methods are rarely useful. As a bare minimum, the function should return some useful value, even if constant. <?php // classic empty function function emptyFunction() {} class bar { // classic empty method function emptyMethod() {} // classic empty function function emptyMethodWithParent() {} } class barbar extends bar { // NOT an empty method : it overwrites the parent method function emptyMethodWithParent() {} } ?>   Command Line Functions/EmptyFunction Analyzers Analyze ## Empty Instructions¶ Empty instructions are part of the code that have no instructions. This may be trailing semi-colon or empty blocks for if-then structures. condition = 3;;;; if (condition) { }  Command Line Structures/EmptyLines Analyzers Dead code, Analyze ## Empty Interfaces¶ Empty interfaces. Interfaces should contains some function, and not be totally empty. <?php // an empty interface interface empty {} // an normal interface interface normal { public function i() ; } // an constant interface interface constantsOnly { const FOO = 1; } ?>   Command Line Interfaces/EmptyInterface Analyzers Analyze ## Empty List¶ Empty list() are not allowed anymore in PHP 7. There must be at least one variable in the list call. <?php //Not accepted since PHP 7.0 list() = array(1,2,3); //Still valid PHP code list(,x) = array(1,2,3); ?>   Command Line Php/EmptyList Analyzers Analyze, CompatibilityPHP70, CompatibilityPHP71 ## Empty Namespace¶ Declaring a namespace in the code and not using it for structure declarations (classes, interfaces, etc...) or global instructions is useless. Using simple style : <?php namespace X; // This is useless namespace Y; class foo {} ?>  Using bracket-style syntax : <?php namespace X { // This is useless } namespace Y { class foo {} } ?>   Command Line Namespaces/EmptyNamespace clearPHP no-empty-namespace Analyzers Analyze, Dead code ## Empty Slots In Arrays¶ PHP tolerates the last element of an array to be empty. <?php a = array( 1, 2, 3, ); b = [ 4, 5, ]; ?>   Command Line Arrays/EmptySlots Analyzers Coding Conventions ## Empty Traits¶ List of all empty trait defined in the code. <?php // empty trait trait t { } // Another empty trait trait t2 { use t; } ?>  Such traits may be reserved for future use. They may also be forgotten, and dead code.  Command Line Traits/EmptyTrait Analyzers Analyze ## Empty Try Catch¶ The code does try, then catch errors but do no act upon the error. <?php try { doSomething(); } catch ('Throwable e) { // simply ignore this } ?>  At worst, the error should be logged, so as to measure the actual usage of the catch expression. catch( Exception e) (PHP 5) or catch(‘Throwable e) with empty catch block should be banned, as they will simply ignore any error.  Command Line Structures/EmptyTryCatch Analyzers Analyze ## Empty With Expression¶ ‘empty() doesn’t accept expressions until PHP 5.5. Until then, it is necessary to store the result of the expression in a variable and then, test it with ‘empty(). <?php // PHP 5.5+ 'empty() usage if (empty(strtolower(b . c))) { doSomethingWithoutA(); } // Compatible 'empty() usage a = strtolower(b . c); if (empty(a)) { doSomethingWithoutA(); } ?>   Command Line Structures/EmptyWithExpression Analyzers CompatibilityPHP55, CompatibilityPHP70, CompatibilityPHP56, CompatibilityPHP71 ## Encoded Simple Letters¶ Some simple letters are written in escape sequence. Usually, escape sequences are made to encode unusual characters. Using escape sequences for simple characters, like letters or numbers is suspicious. <?php // This escape sequence makes eval hard to spot a = ev1l; a('php_info();'); // With a PHP 7.0 unicode code point sequence a = ev\u{41}l; a('php_info();'); // With a PHP 5.0+ hexadecimal sequence a = ev\x41l; a('php_info();'); ?>   Command Line Security/EncodedLetters Analyzers Security ## Error Messages¶ Error message when an error is reported in the code. Those messages will be read by whoever is triggering the error, and it has to be helpful. It is a good excercice to read the messages out of context, and try to understand what is about. <?php // Not so helpful messages 'die('Here be monsters'); 'exit('An error happened'); throw new Exception('Exception thrown at runtime'); ?>  Error messages are spotted via ‘die, ‘exit or exception.  Command Line Structures/ErrorMessages Analyzers ZendFramework ## Eval() Usage¶ Using ‘eval() is bad for performances (compilation time), for caches (it won’t be compiled), and for security (if it includes external data). <?php // Avoid using incoming data to build the 'eval() expression : any filtering error leads to PHP injection mathExpression = _GET['mathExpression']; mathExpression = preg_replace('#[^0-9+\-*/\(/)]#is', '', mathExpression); // expecting 1+2 literalCode = 'a = '.mathExpression.';'; eval(literalCode); echo a; // If eval'ed code is known at compile time, it is best to put it inline literalCode = ''phpinfo();'; eval(literalCode); ?>  Most of the time, it is possible to replace the code by some standard PHP, like variable variable for accessing a variable for which you have the name. At worse, including a pre-generated file will be faster. For PHP 7.0 and later, it is important to put ‘eval() in a try..catch expression.  Command Line Structures/EvalUsage clearPHP no-eval Analyzers Analyze, Performances ## Exception Order¶ When catching exception, the most specialized exceptions must be in the early catch, and the most general exceptions must be in the later catch. Otherwise, the general catches intercept the exception, and the more specialized will not be read. <?php class A extends \Exception {} class B extends A {} try { throw new A(); } catch(A a1) { } catch(B b2 ) { // Never reached, as previous Catch is catching the early worm } ?>   Command Line Exceptions/AlreadyCaught Analyzers Dead code ## Exit() Usage¶ Using ‘exit or ‘die() in the code makes the code untestable (it will ‘break unit tests). Morover, if there is no reason or string to display, it may take a long time to spot where the application is stuck. <?php // Throw an exception, that may be caught somewhere throw new \Exception('error'); // Dying with error message. 'die('error'); function foo() { //exiting the function but not dying if (somethingWrong()) { return true; } } ?>  Try exiting the function/class with return, or throw exception that may be caught later in the code.  Command Line Structures/ExitUsage clearPHP no-exit Analyzers Analyze, ZendFramework ## Exponent Usage¶ Usage of the ‘** operator or **=, to make exponents. <?php eight = 2 '** 3; sixteen = 4; sixteen \*\*\= 2; ?>   Command Line Php/ExponentUsage Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55 ## Failed Substr Comparison¶ The extracted string must be of the size of the compared string. This is also true for negative lengths. <?php // Possible comparison if (substr(a, 0, 3) === 'abc') { } if (substr(b, 4, 3) === 'abc') { } // Always failing if (substr(a, 0, 3) === 'ab') { } if (substr(a, 3, -3) === 'ab') { } // Omitted in this analysis if (substr(a, 0, 3) !== 'ab') { } ?>   Command Line Structures/FailingSubstrComparison Analyzers Analyze ## Fetch One Row Format¶ When reading results with ext/Sqlite3, it is recommended to explicitely request SQLITE3_NUM or SQLITE3_ASSOC, while avoiding the default value and SQLITE3_BOTH. <?php res = database->query(query); // Fastest version, but less readable row = res->fetchArray(\SQLITE3_NUM); // Almost the fastest version, and more readable row = res->fetchArray(\SQLITE3_ASSOC); // Default version. Quite slow row = res->fetchArray(); // Worse case row = res->fetchArray(\SQLITE3_BOTH); ?>  This is a micro-optimisation. The difference may be visible with 200k rows fetches, and measurable with 10k.  Command Line Performances/FetchOneRowFormat Analyzers Performances ## For Using Functioncall¶ It is recommended to avoid functioncall in the ‘for() statement. <?php // Fastest way nb = count(array); for(i = 0; i < nb; ++i) { doSomething(i); } // Same as above, but slow for(i = 0; i < count(array); ++i) { doSomething(i); } // Same as above, but slow foreach(portions as &portion) { // here, 'array_sum() doesn't depends on the grade. It should be out of the loop portion = portion / array_sum(portions); } total = array_sum(portion); foreach(portion as &portion) { portion = portion / total; } ?>  This is true with any kind of functioncall that returns the same value throughout the loop.  Command Line Structures/ForWithFunctioncall clearPHP no-functioncall-in-loop Analyzers Analyze, Performances ## Foreach Don’t Change Pointer¶ In PHP 7.0, the foreach loop won’t change the internal pointer of the array, but will work on a copy. So, applying array pointer’s functions such as ‘current() or ‘next() to the source array won’t have the same behavior than in PHP 5. This anly applies when a ‘foreach() by reference is used. <?php numbers = range(1, 10); next(numbers); foreach(numbers as &number){ print number; print current(numbers).\n; // Always } ?>   Command Line Php/ForeachDontChangePointer Analyzers CompatibilityPHP70, CompatibilityPHP71 ## Foreach Needs Reference Array¶ When using foreach with a reference as value, the source must be a referenced array, which is a variable (or array or property or static property). When the array is the result of an expression, the array is not kept in memory after the foreach loop, and any change made with & are lost. This will do nothing <?php foreach(array(1,2,3) as &value) { value *= 2; } ?>  This will have an actual effect <?php array = array(1,2,3); foreach(array as &value) { value *= 2; } ?>   Command Line Structures/ForeachNeedReferencedSource Analyzers Analyze ## Foreach Reference Is Not Modified¶ Foreach statement may loop using a reference, especially when the loop has to change values of the array it is looping on. In the spotted loop, reference are used but never modified. They may be removed.  Command Line Structures/ForeachReferenceIsNotModified Analyzers Analyze ## Foreach With list()¶ PHP 5.5 introduced the ability to use list in foreach loops. This was not possible in the earlier versions. <?php foreach(array as list(a, b)) { // do something } ?>  Previously, it was compulsory to extract the data from the blind array : <?php foreach(array as c) { list(a, b) = c; // do something } ?>   Command Line Structures/ForeachWithList Analyzers CompatibilityPHP53, CompatibilityPHP54 ## Forgotten Thrown¶ An exception is instantiated, but not thrown. <?php class MyException() extends \Exception { } if (error !== false) { // This looks like 'throw' was omitted new MyException(); } ?>   Command Line Exceptions/ForgottenThrown Analyzers Analyze ## Forgotten Visibility¶ Some classes elements (property, method, and constant in PHP 7.1) are missing their explicit visibility. By default, it is public. It should at least be mentioned as public, or may be reviewed as protected or private. final, static and abstract are not counted as visibility. Only public, private and protected. The PHP 4 var keyword is counted as undefined. Traits, classes and interfaces are checked. <?php // Explicit visibility class X { protected sconst NO_VISIBILITY_CONST = 1; // For PHP 7.2 and later private noVisibilityProperty = 2; public function Method() {} } // Missing visibility class X { const NO_VISIBILITY_CONST = 1; // For PHP 7.2 and later var noVisibilityProperty = 2; // Only with var function NoVisibilityForMethod() {} } ?>   Command Line Classes/NonPpp clearPHP always-have-visibility Analyzers Analyze ## Forgotten Whitespace¶ Those are white space that are at either end of a script : at the beginning or the end. <?php // This script has no forgotten whitespace, not at the beginning function foo() {} // This script has no forgotten whitespace, not at the end ?>  Usually, such white space are forgotten, and may end up summoning the infamous ‘headers already sent’ error. It is better to remove them.  Command Line Structures/ForgottenWhiteSpace Analyzers Analyze ## Fully Qualified Constants¶ Constants defined with their namespace. When defining constants with ‘define() function, it is possible to include the actual namespace : <?php define('a\b\c', 1); ?>  However, the name should be fully qualified without the initial . Here, abc constant will never be accessible as a namespace constant, though it will be accessible via the ‘constant() function. Also, the namespace will be absolute, and not a relative namespace of the current one.  Command Line Namespaces/ConstantFullyQualified Analyzers Analyze ## Function Subscripting¶ This is a new PHP 5.4 feature, where one may use the result of a method directly as an array, given that the method actually returns an array. <?php function foo() { return array(1 => 'a', 'b', 'c'); } echo foo()[1]; // displays 'a'; // Function subscripting, the old way function foo() { return array(1 => 'a', 'b', 'c'); } x = foo(); echo x[1]; // displays 'a'; ?>  This was not possible until PHP 5.4. Is used to be necessary to put the result in a variable, and then access the desired index.  Command Line Structures/FunctionSubscripting Analyzers CompatibilityPHP53 ## Function Subscripting, Old Style¶ Since PHP 5.4, it is now possible use function results as an array, and access directly its element : <?php function foo() { return array(1 => 'a', 'b', 'c'); } echo foo()[1]; // displays 'a'; // Function subscripting, the old way function foo() { return array(1 => 'a', 'b', 'c'); } x = foo(); echo x[1]; // displays 'a'; ?>   Command Line Structures/FunctionPreSubscripting Analyzers Analyze ## Functions Removed In PHP 5.4¶ Those functions were removed in PHP 5.4.  Command Line Php/Php54RemovedFunctions Analyzers Analyze, CompatibilityPHP54 ## Functions Removed In PHP 5.5¶ Those functions were removed in PHP 5.5.  Command Line Php/Php55RemovedFunctions Analyzers CompatibilityPHP55 ## Getting Last Element¶ Getting the last element of an array is done with ‘count() or ‘end(). <?php array = [1, 2, 3]; // Best solutions, just as quick as each other last = array[count(array) - 1]; last = end(array); // Bad solutions // popping, but restoring the value. last = array_pop(array); array[] = last; // array_unshift would be even worse // reversing array last = array_reverse(array)[0]; // slicing the array last = array_slice(array, -1)[0]', last = current(array_slice(array, -1)); ); ?>   Command Line Arrays/GettingLastElement Analyzers Performances ## Global Inside Loop¶ The global keyword must be out of loops. It is evaluated each loop, slowing the whole process. <?php // Good idea, global is used once global total; foreach(a as b) { total += b; } // Bad idea, this is slow. foreach(a as b) { global total; total += b; } ?>   Command Line Structures/GlobalOutsideLoop Analyzers Performances ## Global Usage¶ List usage of globals variables, with global keywords or direct access to GLOBALS. It is recommended to avoid using global variables, at it makes it very difficult to track changes in values across the whole application.  Command Line Structures/GlobalUsage clearPHP no-global Analyzers Analyze ## Group Use Declaration¶ The group use declaration is used in the code. <?php // Adapted from the RFC documentation // Pre PHP 7 code use some\name_space\ClassA; use some\name_space\ClassB; use some\name_space\ClassC as C; use function some\name_space\fn_a; use function some\name_space\fn_b; use function some\name_space\fn_c; use const some\name_space\ConstA; use const some\name_space\ConstB; use const some\name_space\ConstC; // PHP 7+ code use some\name_space\{ClassA, ClassB, ClassC as C}; use function some\name_space\{fn_a, fn_b, fn_c}; use const some\name_space\{ConstA, ConstB, ConstC}; ?>   Command Line Php/GroupUseDeclaration Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56 ## Hardcoded Passwords¶ Hardcoded passwords in the code. Hardcoding passwords is a bad idea. Not only it make the code difficult to change, but it is an information leak. It is better to hide this kind of information out of the code. <?php ftp_server = '300.1.2.3'; // conn_id = ftp_connect(ftp_server); // login with username and password login_result = ftp_login(conn_id, 'login', 'password'); ?>   Command Line Functions/HardcodedPasswords clearPHP no-hardcoded-credential Analyzers Analyze, Security ## Hash Algorithms¶ There is a long but limited list of hashing algorithm available to PHP. The one found below doesn’t seem to be existing.  Command Line Php/HashAlgos Analyzers Analyze ## Hash Algorithms Incompatible With PHP 5.3¶ List of hash algorithms incompatible with PHP 5.3. They were introduced in newer version, and, as such, are not available with older versions. fnv132, fnv164 and joaat were added in PHP 5.4. <?php // Valid in PHP 5.4 + hash('joaat', 'string'); // Valid in PHP all versions hash('crc32', 'string'); ?>   Command Line Php/HashAlgos53 Analyzers CompatibilityPHP53 ## Hash Algorithms Incompatible With PHP 5.4/5¶ List of hash algorithms incompatible with PHP 5.4 and 5.5. They were introduced in newer version, or removed in PHP 5.4. As such, they are not available with older versions.  Command Line Php/HashAlgos54 Analyzers CompatibilityPHP54 ## Hexadecimal In String¶ Mark strings that may be confused with hexadecimal.  Command Line Type/HexadecimalString Analyzers CompatibilityPHP70, CompatibilityPHP71, CompatibilityPHP72, CompatibilityPHP73 ## Hidden Use Expression¶ The use expression for namespaces should always be at te beginning of the namespace block. It is where everyone expect them, and it is less confusing than having them at various levels. <?php // This is visible use A; class B {} // This is hidden use C as D; class E extends D { use traitT; // This is a use for a trait function foo() { // This is a use for a closure return function (a) use (b) {} } } ?>   Command Line Namespaces/HiddenUse Analyzers Analyze ## Htmlentities Calls¶ ‘htmlentities() and ‘htmlspecialchars() are used to prevent injecting special characters in HTML code. As a bare minimum, they take a string and encode it for HTML. The second argument of the functions is the type of protection. The protection may apply to quotes or not, to HTML4 or 5, etc. It is highly recommended to set it explicitely. The third argument of the functions is the encoding of the string. In PHP 5.3, it as ‘ISO-8859-1’, in 5.4, was ‘UTF-8’, and in 5.6, it is now default_charset, a php.ini configuration that has the default value of ‘UTF-8’. It is highly recommended to set this argument too, to avoid distortions from the configuration. Also, note that arguments 2 and 3 are constants and string (respectively), and should be issued from the list of values available in the manual. Other values than those will make PHP use the default values.  Command Line Structures/Htmlentitiescall Analyzers Analyze ## Identical Conditions¶ These logical expressions contain members that are identical. This means those expressions may be simplified. <?php // twice a if (a || b || c || a) { } // Hiding is parenthesis is bad if ((a) ^ (a)) {} // expressions may be large if (a === 1 && 1 === a) {} ?>   Command Line Structures/IdenticalConditions Analyzers Analyze ## If With Same Conditions¶ Successive If / then structures that have the same condition may be either merged or have one of the condition changed. <?php if (a == 1) { doSomething(); } if (a == 1) { doSomethingElse(); } // May be replaced by if (a == 1) { doSomething(); doSomethingElse(); } ?>  Note that if the values used in the condition have been modified in the first if/then structure, the two distinct conditions may be needed. <?php // May not be merged if (a == 1) { // Check that this is really the situation a = checkSomething(); } if (a == 1) { doSomethingElse(); } ?>   Command Line Structures/IfWithSameConditions Analyzers Analyze ## Iffectations¶ Affectations that appears in a conditions. Iffectations are a way to do both a test and an affectations. They may also be typos, such as if (x = 3) { ... }, leading to a constant condition. <?php // an iffectation : assignation in a If condition if(connexion = mysql_connect(host, user, pass)) { res = mysql_query(connexion, query); } // Iffectation may happen in while too. while(row = mysql_fetch(res)) { store[] = row; } ?>   Command Line Structures/Iffectation Analyzers Analyze ## Illegal Name For Method¶ PHP has reserved usage of methods starting with __ for magic methods. It is recommended to avoid using this prefix, to prevent confusions. <?php class foo{ // Constructor function '__construct() {} // Constructor's typo function __constructor() {} // Illegal function name, even as private private function __bar() {} } ?>   Command Line Classes/WrongName Analyzers Analyze ## Implement Is For Interface¶ When deriving classes, implements should be used for interfaces, and extends with classes.  Command Line Classes/ImplementIsForInterface Analyzers Analyze ## Implemented Methods Are Public¶ Class methods that are defined in an interface must be public. They cannot be either private, nor protected. This error is not reported by lint, but is reported at execution time. <?php interface i { function foo(); } class X { // This method is defined in the interface : it must be public protected function foo() {} // other methods may be private private function bar() {} } ?>   Command Line Classes/ImplementedMethodsArePublic Analyzers Analyze ## Implicit Global¶ Global variables, that are used in local scope with global keyword, but are not declared as global in the global scope. They may be mistaken with distinct values, while, in PHP, variables in the global scope are truly global. <?php // This is implicitely global implicitGlobal = 1; global explicitGlobal; explicitGlobal = 2; foo(); echo explicitFunctionGlobal; function foo() { // This global is needed, but not the one in the global space global implicitGlobal, explicitGlobal, explicitFunctionGlobal; // This won't be a global, as it must be 'global' in a function scope notImplicitGlobal = 3; explicitFunctionGlobal = 3; } ?>   Command Line Structures/ImplicitGlobal Analyzers Analyze ## Incompilable Files¶ Files that cannot be compiled, and, as such, be run by PHP. Scripts are linted against PHP versions 5.2, 5.3, 5.4, 5.5, 5.6, 7.0-dev and 7.1. This is usually undesirable, as all code must compile before being executed. It may simply be that such files are not compilable because they are not yet ready for an upcoming PHP version. <?php // Can't compile this : Print only accepts one argument print a, b, c; ?>  Code that is incompilable with older PHP versions means that the code is breaking backward compatibility : good or bad is project decision.  Command Line Php/Incompilable clearPHP no-incompilable Analyzers Analyze ## Indices Are Int Or String¶ Indices in an array notation such as array[‘indice’] may only be integers or string. Boolean, Null or float will be converted to their integer or string equivalent. <?php a = [true => 1, 1.0 => 2, 1.2 => 3, 1 => 4, '1' => 5, 0.8 => 6, 0x1 => 7, 01 => 8, null => 1, '' => 2, false => 1, 0 => 2, '0.8' => 3, '01' => 4, '2a' => 5 ]; print_r(a); ?>:: Array ( [1] => 8 [0] => 2 [] => 2 [0.8] => 3 [01] => 4 [2a] => 5 )  Decimal numbers are rounded to the closest integer; Null is transtyped to ‘’ (empty string); true is 1 and false is 0; Integers in strings are transtyped, while partial numbers or decimals are not analyzed in strings. As a general rule of thumb, only use integers or strings that don’t look like integers. This analyzer may find constant definitions, when available.  Command Line Structures/IndicesAreIntOrString Analyzers Analyze ## Indirect Injection¶ Look for injections through indirect usage for GPRC values (_GET, _POST, _REQUEST, _COOKIE). <?php a = _GET['a']; echo a; ?>   Command Line Security/IndirectInjection Analyzers Security ## Instantiating Abstract Class¶ Those code will raise a PHP fatal error at execution time : ‘Cannot instantiate abstract class’. The classes are actually abstract classes, and should be derived into a concrete class to be instantiated.  Command Line Classes/InstantiatingAbstractClass Analyzers Analyze ## Interpolation¶ The following strings contain variables that are will be replaced. However, the following characters are ambiguous, and may lead to confusion. For example, “x[1]->b”.will be read by PHP as x[1].->b” and not like “{x[1]->b}”. It is advised to add curly brackets around those structures to make them non-ambiguous.  Command Line Type/StringInterpolation Analyzers Coding Conventions ## Invalid Constant Name¶ According to PHP’s manual, constant names, ‘ A valid constant name starts with a letter or underscore, followed by any number of letters, numbers, or underscores.’. Constant, when defined using ‘define() function, must follow this regex :: /[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/   Command Line Constants/InvalidName Analyzers Analyze ## Invalid Octal In String¶ Starting with PHP 7.1, any octal sequence inside a string can’t be beyong 7. Those will be a fatal error at parsing time. In PHP 7.0 and older, those sequences were silently adapted (divided by 0). <?php // Emit no error in PHP 7.1 echo 0; // @ // Emit an error in PHP 7.1 echo 0; // @ ?>   Command Line Type/OctalInString Analyzers CompatibilityPHP71, CompatibilityPHP72, CompatibilityPHP73 ## Is Zend Framework 1 Controller¶ Mark a class as being a Zend Framework Controller. <?php class AController extends Zend_Controller_Action { // Controller code } ?>   Command Line ZendF/IsController Analyzers ZendFramework ## Is Zend Framework 1 Helper¶ Mark a class as being a Zend Framework Helper. <?php class AnHelper extends Zend_View_Helper_Abstract { // Controller code } ?>   Command Line ZendF/IsHelper Analyzers ZendFramework ## Isset With Constant¶ Until PHP 7, it was possible to use arrays as constants, but it was not possible to test them with ‘isset. <?php const X = [1,2,3]; if ('isset(X[4])) {} ?>  This would yield an error : Fatal error: Cannot use ‘isset() on the result of an expression (you can use “null !== expression” instead) in test.php on line 7 This is a backward incompatibility.  Command Line Structures/IssetWithConstant Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56 ## Join file()¶ Applying ‘join() or ‘implode() to the result of ‘file() provides the same results than using ‘file_get_contents(), but at a higher cost of memory and processing. <?php // memory and CPU intensive content = join('', file('path/to/file.txt')); // memory intensive content = file_get_contents('path/to/file.txt'); // Consider reading the data line by line and processing it along the way, // to save memory fp = fopen('path/to/file.txt', 'r'); while(line = fget(fp)) { // process a line } fclose(fp); ?>  Always use ‘file_get_contents() to get the content of a file as a string.  Command Line Performances/JoinFile Analyzers Performances ## List Short Syntax¶ Usage of short syntax version of list(). <?php // PHP 7.1 short list syntax // PHP 7.1 may also use key => value structures with list [a, b, c] = ['2', 3, '4']; // PHP 7.0 list syntax list(a, b, c) = ['2', 3, '4']; ?>   Command Line Php/ListShortSyntax Analyzers CompatibilityPHP53, CompatibilityPHP70, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56 ## List With Appends¶ List() behavior has changed in PHP 7.0 and it has impact on the indexing when list is used with the [] operator. <?php x = array(); list(x[], x[], x[]) = [1, 2, 3]; print_r(x); ?>  In PHP 7.0, results are :: Array ( [0] => 1 [1] => 2 [2] => 3 )  In PHP 5.6, results are :: Array ( [0] => 3 [1] => 2 [2] => 1 )   Command Line Php/ListWithAppends Analyzers Analyze, CompatibilityPHP70, CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56, CompatibilityPHP71 ## List With Keys¶ Setting keys when using list() is a PHP 7.1 feature. <?php // PHP 7.1 and later only list('a' => a, 'b' => b) = ['b' => 1, 'c' => 2, 'a' => 3]; ?>   Command Line Php/ListWithKeys Analyzers CompatibilityPHP53, CompatibilityPHP70, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56 ## Locally Unused Property¶ Those properties are defined in a class, and this class doesn’t have any method that makes use of them. While this is syntacticly correct, it is unusual that defined ressources are used in a child class. It may be worth moving the definition to another class, or to move accessing methods to the class.  Command Line Classes/LocallyUnusedProperty Analyzers Analyze, Dead code ## Logical Mistakes¶ Spot logical mistakes within logical expressions. Sometimes, the logic is not what it seems. It is important to check the actual impact of every part of the logical expression. Do not hesitate to make a table with all possible cases. If those cases are too numerous, it may be time to rethink the whole expression. <?php // Always false if (a != 1 || a != 2) { } // a == 1 is useless if (a == 1 || a != 2) {} // Always false if (a == 1 && a == 2) {} // a != 2 is useless if (a == 1 && a != 2) {} ?>  Based on article from Andrey Karpov Logical Expressions in C/C++. Mistakes Made by Professionals  Command Line Structures/LogicalMistakes Analyzers Analyze ## Logical Should Use Symbolic Operators¶ Logical operators come in two flavors : and / &&, || / or, ^ / xor. However, they are not exchangeable, as && and and have different precedence. It is recommended to use the symbol operators, rather than the letter ones.  Command Line Php/LogicalInLetters clearPHP no-letter-logical Analyzers Analyze ## Lone Blocks¶ Blocks are compulsory when defining a structure, such as a class or a function. They are most often used with flow control instructions, like if then or switch. Blocks are also valid syntax that group several instructions together, though they have no effect at all, except confuse the reader. Most often, it is a ruin from a previous flow control instruction, whose condition was removed or commented. They should be removed. <?php //foreach(a as b) { b++; } ?>   Command Line Structures/LoneBlock Analyzers Analyze ## Long Arguments¶ Long arguments should be put in variable, to preserve readability. When literal arguments are too long, they ‘break the hosting structure by moving the next argument too far on the right. Whenever possible, long arguments should be set in a local variable to keep the readability. <?php // Now the call to foo() is easier to read. reallyBigNumber = <<<BIGNUMBER 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 BIGNUMBER foo(reallyBigNumber, 2, '12345678901234567890123456789012345678901234567890'); // where are the next arguments ? foo('123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890', 2, '123456789012345678901234567890123456789012345678901234567890'); // This is still difficult to read foo(<<<BIGNUMBER 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 BIGNUMBER , 2, '123456789012345678901234567890123456789012345678901234567890'); ?>  Literal strings and heredoc strings, including variables, that are over 50 chars longs are reported here.  Command Line Structures/LongArguments Analyzers Analyze ## Lost References¶ Either avoid references, or propagate them correctly. When assigning a referenced variable with another reference, the initial reference is lost, while the intend was to transfer the content. <?php function foo(&lostReference, &keptReference) { c = 'c'; // lostReference was a reference, but now, it is another lostReference =& c; // keptReference was a reference : now it contains the actual value keptReference = c; } bar = 'bar'; bar2 = 'bar'; foo(bar, bar2); //displays bar c, instead of bar bar print bar. ' '.bar2; ?>  Do not reassign a reference with another reference. Assign new content to the reference to change its value.  Command Line Variables/LostReferences Analyzers Analyze ## Magic Visibility¶ The class magic methods must have public visibility and cannot be static. <?php class foo{ // magic method must bt public and non-static public static function '__clone(name) { } // magic method can't be private private function '__get(name) { } // magic method can't be protected private function '__set(name, value) { } // magic method can't be static public static function '__isset(name) { } } ?>  See Magic methods.  Command Line Classes/toStringPss Analyzers Analyze, CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56, CompatibilityPHP70, CompatibilityPHP71, CompatibilityPHP72 ## Make Global A Property¶ Calling global (or GLOBALS) in methods is slower and less testable than setting the global to a property, and using this property. Using properties is slightly faster than calling global or GLOBALS, though the gain is not important. Setting the property in the constructor (or in a factory), makes the class easier to test, as there is now a simple point of configuration. <?php // Wrong way class fooBad { function x() { global a; a->do(); // Or GLOBALS['a']->do(); } } class fooGood { private bar = null; function '__construct() { global bar; this->bar = bar; // Even better, do this via arguments } function x() { this->a->do(); } } ?>   Command Line Classes/MakeGlobalAProperty Analyzers Analyze ## Make One Call With Array¶ Call preg_replace_call() and ‘str_replace() with an array. once with ‘preg_replace_callback_array(). Calling the same function to chain modifications tends to be slower than calling the same function with all the transformations at the same time. Some PHP functions accept scalars or arrays, and using the later is more efficient. <?php string = 'abcdef'; //'str_replace() accepts arrays as arguments string = str_replace( ['a', 'b', 'c'], ['A', 'B', 'C'], string); // Too many calls to str_replace string = str_replace( 'a', 'A', string); string = str_replace( 'b', 'B', string); string = str_replace( 'c', 'C', string); // Too many nested calls to str_replace string = str_replace( 'a', 'A', str_replace( 'b', 'B', str_replace( 'c', 'C', string))); ?>  Potential replacements : <?php subject = 'Aaaaaa Bbb'; //'preg_replace_callback_array() is better than multiple preg_replace_callback : preg_replace_callback_array( [ '~[a]+~i' => function (match) { echo strlen(match[0]), ' matches for a found', PHP_EOL; }, '~[b]+~i' => function (match) { echo strlen(match[0]), ' matches for b found', PHP_EOL; } ], subject ); result = preg_replace_callback('~[a]+~i', function (match) { echo strlen(match[0]), ' matches for a found', PHP_EOL; }, subject); result = preg_replace_callback('~[b]+~i', function (match) { echo strlen(match[0]), ' matches for b found', PHP_EOL; }, subject); //'str_replace() accepts arrays as arguments string = str_replace( ['a', 'b', 'c'], ['A', 'B', 'C'], string); // Too many calls to str_replace string = str_replace( 'a', 'A'); string = str_replace( 'b', 'B'); string = str_replace( 'c', 'C'); ?>   Command Line Performances/MakeOneCall Analyzers Performances ## Malformed Octal¶ Those numbers starts with a 0, so they are using the PHP octal convention. Therefore, one can’t use 8 or 9 figures in those numbers, as they don’t belong to the octal base. The resulting number will be truncated at the first erroneous figure. For example, 090 is actually 0, and 02689 is actually 22. <?php // A long way to write 0 in PHP 5 a = 0890; // A fatal error since PHP 7 ?>  Also, note that very large octal, usually with more than 21 figures, will be turned into a real number and undergo a reduction in precision.  Command Line Type/MalformedOctal Analyzers Analyze ## Methodcall On New¶ This was added in PHP 5.4+  Command Line Php/MethodCallOnNew Analyzers CompatibilityPHP53 ## Missing Cases In Switch¶ It seems that some cases are missing in this switch structure. When comparing two differents ‘switch() structures, it appears that some cases are missing in one of them. The set of cases are almost identical, but one of the values are missing. Switch() structures using strings as literals are compared in this analysis. When the discrepancy between two lists is below 25%, both switches are reported. <?php // This switch operates on a, b, c, d and default switch(a) { case 'a': doSomethingA(); 'break 1; case 'b': doSomethingB(); 'break 1; case 'c': doSomethingC(); 'break 1; case 'd': doSomethingD(); 'break 1; default: doNothing(); } // This switch operates on a, b, d and default switch(o->p) { case 'a': doSomethingA(); 'break 1; case 'b': doSomethingB(); 'break 1; case 'd': doSomethingD(); 'break 1; default: doNothing(); } ?>  In the example, one may argue that the ‘c’ case is actually handled by the ‘default’ case. Otherwise, business logic may request that omission.  Command Line Structures/MissingCases Analyzers Analyze ## Mixed Concat And Interpolation¶ Mixed usage of concatenation and string interpolation is error prone. It is harder to read, and leads to overlooking the concatenation or the interpolation. <?php // Concatenation string a = b . 'c' . d; // Interpolation strings a = {b}c{d}; // regular form a = {b}cd; // irregular form // Mixed Concatenation and Interpolation string a = {b}c . d; a = b . cd; a = b . c{d}; ?>  This issue doesn’t change the output. It makes code less error prone.  Command Line Structures/MixedConcatInterpolation Analyzers Coding Conventions, Analyze ## Mixed Keys Arrays¶ Avoid mixing constants and literals in array keys. When defining default values in arrays, it is recommended to avoid mixing constants and literals, as PHP may mistake them and overwrite the previous with the latter. Either switch to a newer version of PHP (5.5 or newer), or make sure the resulting array is the one you expect. If not, reorder the definitions. <?php const ONE = 1; a = [ 1 => 2, ONE => 3]; ?>   Command Line Arrays/MixedKeys Analyzers CompatibilityPHP53, CompatibilityPHP54 ## Modernize Empty With Expression¶ ‘empty() accept expressions since PHP 5.5. There is no need to store the expression in a variable before testing, unless it is reused later. <?php // PHP 5.5+ 'empty() usage if (empty(strtolower(b . c))) { doSomethingWithoutA(); } // Compatible 'empty() usage a = strtolower(b . c); if (empty(a)) { doSomethingWithoutA(); } // a2 is reused, storage is legit a2 = strtolower(b . c); if (empty(a2)) { doSomething(); } else { echo a2; } ?>   Command Line Structures/ModernEmpty Analyzers Analyze ## Multiple Alias Definitions¶ Some aliases are representing differents classes across the repository. This leads to potential confusion. Across an application, it is recommended to use the same namespace for one alias. Failing to do this lead to the same keyword to represent different values in different files, with different behavior. Those are hard to find bugs. <?php namespace A { use d\d; // aka D } // Those are usually in different files, rather than just different namespaces. namespace B { use b\c as D; // also D. This could be named something else } ?>   Command Line Namespaces/MultipleAliasDefinitions Analyzers Analyze ## Multiple Alias Definitions Per File¶ Avoid aliasing the same name with different aliases. This leads to confusion. <?php // first occurrence use name\space\ClasseName; // when this happens, several other uses are mentionned // name\space\ClasseName has now two names use name\space\ClasseName as anotherName; ?>  See also Multiple Alias Definitions.  Command Line Namespaces/MultipleAliasDefinitionPerFile Analyzers Analyze ## Multiple Class Declarations¶ It is possible to declare several times the same class in the code. PHP will not mention it until execution time, since declarations may be conditional. <?php a = 1; // Conditional declaration if (a == 1) { class foo { function method() { echo 'class 1';} } } else { class foo { function method() { echo 'class 2';} } } (new foo())->method(); ?>  It is recommended to avoid declaring several times the same class in the code. The best practice is to separate them with namespaces, they are for here for that purpose. In case those two classes are to be used interchangeably, the best is to use an abstract class or an interface.  Command Line Classes/MultipleDeclarations Analyzers Analyze ## Multiple Classes In One File¶ It is regarded as a bad practice to cram more than one class per file. This is usually done to make life of __autoload() easier. It is often difficult to find class foo in the bar.php file. This is also the case for interfaces and traits. One good reason to have multiple classes in one file is to reduce include time by providing everything into one nice include.  Command Line Classes/MultipleClassesInFile Analyzers Coding Conventions ## Multiple Constant Definition¶ Some constants are defined several times in your code. This will lead to a fatal error, if they are defined during the same execution.  Command Line Constants/MultipleConstantDefinition Analyzers Analyze ## Multiple Definition Of The Same Argument¶ A method’s signature is holding twice (or more) the same argument. For example, function x (a, a) { ... }. This is accepted as is by PHP 5, and the last parameter’s value will be assigned to the variable. PHP 7.0 and more recent has dropped this feature, and reports a fatal error when linting the code. <?php function x (a, a) { print a; }; x(1,2); => display 2 ?>  However, this is not common programming practise : all arguments should be named differently.  Command Line Functions/MultipleSameArguments clearPHP all-unique-arguments Analyzers Analyze, CompatibilityPHP70, CompatibilityPHP71 ## Multiple Exceptions Catch()¶ Starting with PHP 7.1, it is possible to have several distinct exceptions class caught by the same catch, preventing code repetition. <?php // PHP 7.1 and more recent try { throw new someException(); } catch (Single s) { doSomething(); } catch (oneType | anotherType s) { processIdentically(); } finally { } // PHP 7.0 and older try { throw new someException(); } catch (Single s) { doSomething(); } catch (oneType s) { processIdentically(); } catch (anotherType s) { processIdentically(); } finally { } ?>  This is a backward incompabitible feature of PHP 7.1.  Command Line Exceptions/MultipleCatch Analyzers CompatibilityPHP53, CompatibilityPHP70, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56 ## Multiple Identical Trait Or Interface¶ There is no need to use the same trait, or implements the same interface more than once. Up to PHP 7.1 (at least), this doesn’t raise any warning. Traits are only imported once, and interfaces may be implemented as many times as wanted. <?php class foo { use t3,t3,t3; } class bar implements i,i,i { } ?>   Command Line Classes/MultipleTraitOrInterface Analyzers Analyze ## Multiple Index Definition¶ Indexes that are defined multiple times in the same array. <?php // Multiple identical keys x = array(1 => 2, 2 => 3, 1 => 3); // Multiple identical keys (sneaky version) x = array(1 => 2, 1.1 => 3, true => 4); // Multiple identical keys (automated version) x = array(1 => 2, 3, // This will be index 2 2 => 4); // this index is overwritten ?>  They are indeed overwriting each other. This is most probably a typo.  Command Line Arrays/MultipleIdenticalKeys Analyzers Analyze ## Multiples Identical Case¶ Some cases are defined multiple times, but only one will be processed. Check the list of cases, and remove the extra one. Exakat tries to find the value of the case as much as possible, and ignore any dynamic cases (using variables). <?php case (x) { case 1 : 'break; case true: // This is a duplicate of the previous 'break; case 1 + 0: // This is a duplicate of the previous 'break; case 1.0 : // This is a duplicate of the previous 'break; case y : // This is not reported. 'break; default: } ?>   Command Line Structures/MultipleDefinedCase clearPHP no-duplicate-case Analyzers Analyze ## Multiply By One¶ Multiplying by 1 is useless. If it is used to type cast a value to number, then casting (integer) or (real) is clearer. This behavior may change with PHP 7.1, which has unified the behavior of all hidden casts. <?php // Still the same value than m, but now cast to integer or real m = m * 1; // Still the same value than m, but now cast to integer or real n *= 1; // make typecasting clear, and merge it with the producing call. n = (int) n; ?>   Command Line Structures/MultiplyByOne clearPHP no-useless-math Analyzers Analyze ## Must Return Methods¶ The following methods are expected to return a value that will be used later. Without return, they are useless. Methods that must return are : ‘__get(), ‘__isset(), ‘__sleep(), ‘__toString(), ‘__set_state(), ‘__invoke(), ‘__debugInfo(). Methods that may not return, but are often expected to : ‘__call(), ‘__callStatic(). <?php class foo { public function '__isset(a) { // returning something useful return 'isset(this->var[a]); } public function '__get(a) { this->a++; // not returning... } public function '__call(name, args) { this->name(...args); // not returning anything, but that's OK } } ?>   Command Line Functions/MustReturn Analyzers Analyze ## Negative Power¶ The power operator ‘** has higher precedence than the sign operators + and -. This means that -2 ‘** 2 == -4. It is in fact, -(2 ‘** 2). When using negative power, it is clearer to add parenthesis or to use the ‘pow() function, which has no such ambiguity : <?php // -2 to the power of 2 (a square) pow(-2, 2) == 4; // minus 2 to the power of 2 (a negative square) -2 '** 2 == -(2 '** 2) == 4; ?>   Command Line Structures/NegativePow Analyzers Analyze ## Nested Ifthen¶ Three levels of ifthen is too much. The method should be split into smaller functions. <?php function foo(a, b) { if (a == 1) { // Second level, possibly too much already if (b == 2) { } } } function bar(a, b, c) { if (a == 1) { // Second level. if (b == 2) { // Third level level. if (c == 3) { // Too much } } } } ?>   Command Line Structures/NestedIfthen Analyzers Analyze ## Nested Ternary¶ Ternary operators should not be nested too deep. They are a convenient instruction to apply some condition, and avoid a if() structure. It works best when it is simple, like in a one liner. However, ternary operators tends to make the syntax very difficult to read when they are nested. It is then recommended to use an if() structure, and make the whole code readable. <?php // Simple ternary expression echo (a == 1 ? b : c) ; // Nested ternary expressions echo (a === 1 ? d === 2 ? b : d : d === 3 ? e : c) ; echo (a === 1 ? d === 2 ? f ===4 ? g : h : d : d === 3 ? e : i === 5 ? j : k) ; //Previous expressions, written as a if / Then expression if (a === 1) { if (d === 2) { echo b; } else { echo d; } } else { if (d === 3) { echo e; } else { echo c; } } if (a === 1) { if (d === 2) { if (f === 4) { echo g; } else { echo h; } } else { echo d; } } else { if (d === 3) { echo e; } else { if (i === 5) { echo j; } else { echo k; } } } ?>   Command Line Structures/NestedTernary clearPHP no-nested-ternary Analyzers Analyze ## Never Used Properties¶ Properties that are never used. They are defined, but never actually used. <?php class foo { public usedProperty = 1; // Never used anywhere public unusedProperty = 2; function bar() { // Used internally ++this->usedProperty; } } class foo2 extends foo { function bar2() { // Used in child class ++this->usedProperty; } } // Used externally ++this->usedProperty; ?>   Command Line Classes/PropertyNeverUsed Analyzers Analyze ## New Constants In PHP 7.2¶ The following constants are now native in PHP 7.2. It is advised to avoid using such names for constant before moving to this new version. • PHP_OS_FAMILY • PHP_FLOAT_DIG • PHP_FLOAT_EPSILON • PHP_FLOAT_MAX • PHP_FLOAT_MIN • SQLITE3_DETERMINISTIC • CURLSSLOPT_NO_REVOKE • CURLOPT_DEFAULT_PROTOCOL • CURLOPT_STREAM_WEIGHT • CURLMOPT_PUSHFUNCTION • CURL_PUSH_OK • CURL_PUSH_DENY • CURL_HTTP_VERSION_2TLS • CURLOPT_TFTP_NO_OPTIONS • CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE • CURLOPT_CONNECT_TO • CURLOPT_TCP_FASTOPEN • DNS_CAA Note : PHP 7.2 is not out yet (2017-04-10). This list is currently temporary and may undergo changes until the final version is out.  Command Line Php/Php72NewConstants Analyzers CompatibilityPHP72, CompatibilityPHP73 ## New Functions In PHP 5.4¶ PHP introduced new functions in PHP 5.4. If you have already defined functions with such names, you will get a conflict when trying to upgrade. It is advised to change those functions’ name.  Command Line Php/Php54NewFunctions Analyzers CompatibilityPHP53, CompatibilityPHP71 ## New Functions In PHP 5.5¶ PHP introduced new functions in PHP 5.5. If you have already defined functions with such names, you will get a conflict when trying to upgrade. It is advised to change those functions’ name.  Command Line Php/Php55NewFunctions Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP71 ## New Functions In PHP 5.6¶ PHP introduced new functions in PHP 5.6. If you have already defined functions with such names, you will get a conflict when trying to upgrade. It is advised to change those functions’ name.  Command Line Php/Php56NewFunctions Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55 ## New Functions In PHP 7.0¶ The following functions are now native functions in PHP 7.0. It is advised to change them before moving to this new version. • get_resources • gc_mem_caches • preg_replace_callback_array • posix_setrlimit • random_bytes • random_int • intdiv • error_clear_last  Command Line Php/Php70NewFunctions Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56, CompatibilityPHP71 ## New Functions In PHP 7.1¶ The following functions are now native functions in PHP 7.1. It is advised to change them before moving to this new version. • curl_share_strerror() • curl_multi_errno() • curl_share_errno() • mb_ord() • mb_chr() • mb_scrub() • is_iterable()  Command Line Php/Php71NewFunctions Analyzers CompatibilityPHP71, CompatibilityPHP72, CompatibilityPHP73 ## New Functions In PHP 7.2¶ The following functions are now native functions in PHP 7.2. It is advised to change them before moving to this new version. • mb_ord() • mb_chr() • mb_scrub() • stream_isatty() • ‘proc_nice() (Windows only)  Command Line Php/Php72NewFunctions Analyzers CompatibilityPHP72, CompatibilityPHP73 ## No Boolean As Default¶ Default values should always be set up with constants. Class constants or constants improve readability when calling the methods. <?php const CASE_INSENSITIVE = true; const CASE_SENSITIVE = false; function foo(case_insensitive = true) { // doSomething() } // Readable code foo(CASE_INSENSITIVE); foo(CASE_SENSITIVE); // unreadable code : is true case insensitive or case sensitive ? foo(true); foo(false); ?>   Command Line Functions/NoBooleanAsDefault Analyzers Analyze ## No Choice¶ A conditional structure is being used, but both alternatives are the same, leading to the illusion of choice. Either the condition is useless, and may be removed, or the alternatives needs to be distinguished. <?php if (condition == 2) { doSomething(); } else { doSomething(); } condition == 2 ? doSomething() : doSomething(); ?>   Command Line Structures/NoChoice Analyzers Analyze ## No Class As Typehint¶ Avoid using whole classes as typehint. Always use interfaces, so that you may use different classes, or versions of classes. <?php class X { function foo() {} } interface i { function foo(); } // X is a class : any update in the code requires changing / subclassing X or the rest of the code. function bar(X x) { x->foo(); } // I is an interface : X may implements this interface without refactoring and pass // later, newer versions of X may get another name, but still implement I, and still pass function bar2(I x) { x->foo(); } ?>  See also _.  Command Line Functions/NoClassAsTypehint Analyzers Analyze ## No Class In Global¶ Avoid defining structures in Global namespace. Always prefer using a namespace. This will come handy later, either when publishing the code, or when importing a library, or even if PHP reclaims that name. <?php // Code prepared for later namespace Foo { class Bar {} } // Code that may conflict with other names. namespace { class Bar {} } ?>   Command Line Php/NoClassInGlobal Analyzers Analyze ## No Count With 0¶ Comparing ‘count() and strlen() to 0 is a waste of resources. There are three distinct situations situations. When comparing ‘count() with 0, with ===, ==, !==, !=, it is more efficient to use ‘empty(). Empty() is a language constructs that checks if a value is present, while ‘count() actually load the number of element. <?php // Checking if an array is empty if (count(array) == 0) { // doSomething(); } // This may be replaced with if (empty(array)) { // doSomething(); } ?>  When comparing ‘count() strictly with 0 (>) it is more efficient to use !(‘empty()) <?php // Checking if an array is empty if (count(array) > 0) { // doSomething(); } // This may be replaced with if (!empty(array)) { // doSomething(); } Of course comparing 'count() with negative values, or with >= is useless. <?php // Checking if an array is empty if (count(array) < 0) { // This never happens // doSomething(); } ?>  Comparing ‘count() and strlen() with other values than 0 cannot be replaced with a comparison with ‘empty(). Note that this is a micro-optimisation : since PHP keeps track of the number of elements in arrays (or number of chars in strings), the total computing time of both operations is often lower than a ms. However, both functions tends to be heavily used, and may even be used inside loops.  Command Line Performances/NotCountNull Analyzers Performances ## No Direct Call To Magic Method¶ PHP magic methods, such as ‘__get(), ‘__set(), ... are supposed to be used in an object environnement, and not with direct call. For example, <?php print x->'__get('a'); //should be written print x->a; ?>  Accessing those methods in a static way is also discouraged.  Command Line Classes/DirectCallToMagicMethod Analyzers Analyze ## No Direct Usage¶ The results of the following functions shouldn’t be used directly, but checked first. For example, ‘glob() returns an array, unless some error happens, in which case it returns a boolean (false). In such case, however rare it is, plugging ‘glob() directly in a ‘foreach() loops will yield errors. <?php // Used without check : foreach(glob('.') as file) { /* do Something */ }. // Used without check : files = glob('.'); if (!is_array(files)) { foreach(files as file) { /* do Something */ }. } ?>   Command Line Structures/NoDirectUsage Analyzers Analyze ## No Echo In Route Callable¶ Avoid using echo(), ‘print() or any printable PHP within the route callable method. echo() works, it is prevents the code from setting any status code. This leads to confusion when the code return the content, but fail to set the right HTTP codes. Slim 4.0 will require to only use the return method : the route callable is required to return a response. <?php app = new Slim\App(); // This works as expected, with or without status app->get('/', function (request, response, args) { return new MyResponseInterface ('content'); }); // This works, but only on surface app->get('/', function (request, response, args) { echo 'content'; }); ?>  See PSR7 and PSR 7 and Value Objects.  Command Line Slim/NoEchoInRouteCallable Analyzers Slim ## No Empty Regex¶ PHP regex don’t accept empty regex, nor regex with alphanumeric delimiter. Most of those errors happen at execution time, when the regex is build dynamically, but still may end empty. At compile time, such error are made when the code is not tested before commit. <?php // No empty regex preg_match('', string, r); // Delimiter must be non-alphanumerical preg_replace('1abc1', string, r); // Delimiter must be non-alphanumerical preg_replace('1'.regex.'1', string, r); ?>  See also PCRE and Delimiters.  Command Line Structures/NoEmptyRegex Analyzers Analyze ## No Global Modification¶ Avoid modifying directly Wordpress global variables. It is recommended to use the function API instead. <?php my_hook() { // Avoid changing those variables, as Wordpress handles them GLOBALS['is_safari'] = true; } ?>  See also Global Variables  Command Line Wordpress/NoGlobalModification Analyzers Wordpress ## No Hardcoded Hash¶ Hash should never be hardcoded. Hashes may be MD5, SHA1, SHA512, Bcrypt or any other. Such values must be easily changed, for security reasons, and the source code is not the safest place to hide it. <?php // Those strings may be sha512 hashes. // it is recomemdned to check if they are static or should be put into configuration init512 = array( // initial values for SHA512 '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1', ); ?>   Command Line Structures/NoHardcodedHash Analyzers Analyze, Security ## No Hardcoded Ip¶ Do not leave hard coded IP in your code. It is recommended to move such configuration in external files or databases, for each update. This may also come handy when testing. <?php // This IPv4 is hardcoded. ip = '183.207.224.50'; // This IPv6 is hardcoded. ip = '2001:0db8:85a3:0000:0000:8a2e:0370:7334'; // This looks like an IP thisIsNotAnIP = '213.187.99.50'; thisIsNotAnIP = '2133:1387:9393:5330'; ?>  127.0.0.1, ::1 and ::0 are omitted, and not considered as a violation.  Command Line Structures/NoHardcodedIp Analyzers Analyze, Security ## No Hardcoded Path¶ It is not recommended to have literals when accessing files. Either use ‘__FILE__ and ‘__DIR__ to make the path relative to the current file; use a DOC_ROOT as a configuration constant that will allow you to move your script later or rely on functions likes ‘sys_get_temp_dir(), to reach special folders. <?php // This depends on the current executed script file_get_contents('token.txt'); // Exotic protocols are ignored file_get_contents('jackalope://file.txt'); // Some protocols are ignored : http, https, ftp, ssh2, php (with memory) file_get_contents('http://www.php.net/'); file_get_contents('php://memory/'); // 'glob() with special chars * and ? are not reported glob('./*/foo/bar?.txt'); // 'glob() without special chars * and ? are reported glob('/foo/bar/'); ?>   Command Line Structures/NoHardcodedPath clearPHP no-hardcoded-path Analyzers Analyze ## No Hardcoded Port¶ When connecting to a remove serve, port is an important information. It is recommended to make this configurable (with constant or configuration), to as to be able to change this value without changing the code.  Command Line Structures/NoHardcodedPort Analyzers Analyze, Security ## No Implied If¶ It is possible to emulate a if/then structure by using the operators ‘and’ and ‘or’. Since optimizations will be applied to them : when the left operand of ‘and’ is false, the right one is not executed, as its result is useless; when the left operand of ‘or’ is true, the right one is not executed, as its result is useless; However, such structures are confusing. It is easy to misread them as conditions, and ignore an important logic step. <?php // Either connect, or 'die mysql_connect('localhost', user, pass) or 'die(); // Defines a constant if not found. defined('SOME_CONSTANT') and define('SOME_CONSTANT', 1); ?>  It is recommended to use a real ‘if then’ structures, to make the condition readable.  Command Line Structures/ImpliedIf clearPHP no-implied-if Analyzers Analyze ## No Isset With Empty¶ Empty() actually does the job of Isset() too. From the manual : No warning is generated if the variable does not exist. That means ‘empty() is essentially the concise equivalent to !’isset( <http://www.php.net/isset>_var) || var == false. <?php // Enough tests if (i!empty(a)) { doSomething(); } // Too many tests if ('isset(a) && !empty(a)) { doSomething(); } ?>   Command Line Structures/NoIssetWithEmpty Analyzers Analyze ## No List With String¶ list() can’t be used anymore to access particular offset in a string. This should be done with substr() or string[offset] syntax.  Command Line Php/NoListWithString Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56 ## No Need For Else¶ Else is not needed when the Then ends with a ‘break. A ‘break may be the following keywords : ‘break, ‘continue, return, goto. Any of these send the execution somewhere in the code. The else block is then executed as the main sequence, only if the condition fails. <?php function foo() { // Else may be in the main sequence. if (a1) { return a1; } else { a++; } // Same as above, but negate the condition : if (!a2) { return a2; } if (a2) { a++; } else { return a2; } // This is OK if (a3) { return; } // This has no 'break if (a4) { a++; } else { b++; } // This has no else if (a5) { a++; } } ?>  See also Object Calisthenics, rule number 2.  Command Line Structures/NoNeedForElse Analyzers Analyze ## No Parenthesis For Language Construct¶ Some PHP language constructs, such are include, print, echo don’t need parenthesis. They will handle parenthesis, but it is may lead to strange situations. It it better to avoid using parenthesis with echo, print, return, throw, include and require (and _once).  Command Line Structures/NoParenthesisForLanguageConstruct clearPHP no-parenthesis-for-language-construct Analyzers Analyze ## No Plus One¶ Incrementing a variable should be done with the ++ or – operators. Any other way, may be avoided. <?php // Best way to increment ++x; --y; // Second best way to increment, if the current value is needed : echo x++, y--; // Good but slow x += 1; x -= -1; y += -1; y -= 1; // even slower x = x + 1; y = y - 1; ?>   Command Line Structures/PlusEgalOne Analyzers Coding Conventions ## No Public Access¶ The properties below are declared with public access, but are never used publicly. They can be made protected or private. <?php class foo { public bar = 1; // Public, and used in public space public neverInPublic = 3; // Public, but never used in outside the class function bar() { neverInPublic++; } } x = new foo(); x->bar = 3; x->bar(); ?>   Command Line Classes/NoPublicAccess Analyzers Analyze ## No Real Comparison¶ Avoid comparing decimal numbers with ==, ===, !==, !=. Real numbers have an error margin which is random, and makes it very difficult to match even if the compared value is a literal. PHP uses an internal representation in base 2 : any number difficult to represent with this base (like 0.1 or 0.7) will have a margin of error. <?php a = 1/7; b = 2.0; // 7 * a is a real, not an integer var_dump( 7 * a === 1); // rounding error leads to wrong comparison var_dump( (0.1 + 0.7) * 10 == 8); // although var_dump( (0.1 + 0.7) * 10); // displays 8 // precision formula to use with reals. Adapt 0.0001 to your precision needs var_dump( abs(((0.1 + 0.7) * 10) - 8) < 0.0001); ?>  Use precision formulas with ‘abs() to approximate values with a given precision, or avoid reals altogether.  Command Line Type/NoRealComparison clearPHP no-real-comparison Analyzers Analyze ## No Return Used¶ The return value of the following functions are never used. The return argument may be dropped from the code, as it is dead code. This analysis supports functions and static methods, when a definition may be found. It doesn’t support method calls. <?php function foo(a = 1;) { return 1; } foo(); foo(); foo(); foo(); foo(); foo(); // This function doesn't return anything. function foo2() { } // The following function are used in an expression, thus the return is important function foo3() { return 1;} function foo4() { return 1;} function foo5() { return 1;} foo3() + 1; a = foo4(); foo(foo5()); ?>   Command Line Functions/NoReturnUsed Analyzers Analyze ## No Self Referencing Constant¶ It is not possible to use ‘self’ when defining a constant in a class. It will yield a fatal error at runtime. <?php class a { const C1 = 1; const C2 = self::C1; const C3 = a::C3; } ?>  The code needs to reference the full class’s name to do so, without using the current class’s name. <?php class a { const C1 = 1; const C2 = a::C1; } ?>   Command Line Classes/NoSelfReferencingConstant Analyzers Analyze ## No String With Append¶ PHP 7 doesn’t allow the usage of [] with strings. [] is an array-only oeprator. <?php string = 'abc'; // Not possible in PHP 7 string[] = 'd'; ?>  This was possible in PHP 5.*, but is now forbidden in PHP 7.  Command Line Php/NoStringWithAppend Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56 ## No Substr() One¶ Use array notation string[position] to reach a single byte in a string. There are two ways to access a byte in a string : substr() and v[pos]; The second one is more readable. It may be up to four times faster, though it is a micro-optimization. It is recommended to use it. PHP 7.1 also introduces the support of negative offsets as string index : negative offset are also reported here. <?php string = ab人cde; echo substr(string, pos, 1); echo string[pos]; echo mb_substr(string, pos, 1); // pos = 1 // bbb // pos = 2 // ??人 ?>  Beware that substr() and v[pos] are similar, while ‘mb_substr() is not. The first functions works on bytes, while the latter works on characters.  Command Line Structures/NoSubstrOne Analyzers Analyze, Performances, CompatibilityPHP71 ## No array_merge() In Loops¶ ‘array_merge() is memory intensive : every call will duplicate the arguments in memory, before merging them. Since arrays may be quite big, it is recommended to avoid using ‘array_merge() in a loop. Instead, one should use ‘array_merge() with as many arguments as possible, making the merge a on time call. <?php // Creating a large multidimensional array source = ['a' => ['a', 'b', /*...*/], 'b' => ['b', 'c', 'd', /*...*/], /*...*/ ]; // Slow way b = array(); foreach(source as key => values) { b = array_merge(b, values); } // Faster way b = array(); foreach(source as key => values) { //Collect in an array b[] = values; } // One call to array_merge b = call_user_func_array('array_merge', b); // or with variadic b = call_user_func('array_merge', ..b); // Fastest way (with above example, without checking nor data pulling) b = call_user_func_array('array_merge', array_values(source)) // or b = call_user_func('array_merge', ...array_values(source)) ?>  Note that ‘array_merge_recursive() and ‘file_put_contents() are also affected and reported.  Command Line Performances/ArrayMergeInLoops clearPHP no-array_merge-in-loop Analyzers Analyze, Performances ## Non Ascii Variables¶ PHP supports variables with certain characters. The variable name must only include letters, figures, underscores and ASCII characters from 128 to 255. In practice, letters outside the scope of a-zA-Z0-9 are rare, and require more care when editing the code or passing it from OS to OS. <?php class 人 { // An actual working class in PHP. public function '__construct() { echo '__CLASS__; } } people = new 人(); ?>  See also Variables.  Command Line Variables/VariableNonascii Analyzers Analyze ## Non Static Methods Called In A Static¶ Static methods have to be declared as such (using the static keyword). Then, one may call them without instantiating the object. However, PHP doesn’t check that a method is static or not : at any point, you may call one method statically : <?php class x { static public function sm( ) { echo '__METHOD__.\n; } public public sm( ) { echo '__METHOD__.\n; } } x::sm( ); // echo x::sm ?>  It is a bad idea to call non-static method statically. Such method may make use of special variable this, which will be undefined. PHP will not check those calls at compile time, nor at running time. It is recommended to update this situation : make the method actually static, or use it only in object context. Note that this analysis reports all static method call made on a non-static method, even within the same class or class hierarchy. PHP silently accepts static call to any in-family method. <?php class x { public function foo( ) { self::bar() } public function bar( ) { echo '__METHOD__.\n; } } ?>   Command Line Classes/NonStaticMethodsCalledStatic Analyzers Analyze, CompatibilityPHP56, CompatibilityPHP70, CompatibilityPHP71 ## Non-constant Index In Array¶ Undefined constants revert as strings in Arrays. They are also called barewords. In ‘array[index]’, PHP cannot find index as a constant, but, as a default behavior, turns it into the string ‘index’. This default behavior raise concerns when a corresponding constant is defined, either using ‘define() or the const keyword (outside a class). The definition of the index constant will modify the behavior of the index, as it will now use the constant definition, and not the ‘index’ string. <?php // assign 1 to the element index in array // index will fallback to string array[index] = 1; //PHP Notice: Use of undefined constant index - assumed 'index' echo array[index]; // display 1 and the above error echo array[index]; // display 1 echo array[index]; // Syntax error define('index', 2); // now 1 to the element 2 in array array[index] = 1; ?>  It is recommended to make index a real string (with ‘ or ”), or to define the corresponding constant to avoid any future surprise. Note that PHP 7.2 removes the support for this feature : PHP RFC: Deprecate and Remove Bareword (Unquoted) Strings.  Command Line Arrays/NonConstantArray Analyzers Analyze ## Non-lowercase Keywords¶ Usual convention is to write PHP keywords (like as, foreach, switch, case, ‘break, etc.) all in lowercase. <?php // usual PHP convention foreach(array as element) { echo element; } // unusual PHP conventions Foreach(array AS element) { eCHo element; } ?>  PHP do understand them in lowercase, UPPERCASE or WilDCase, so there is nothing compulsory here. Although, it will look strange to many.  Command Line Php/UpperCaseKeyword Analyzers Coding Conventions ## Nonce Creation¶ Mark the creation of nonce by Wordpress. Nonce may be created with the Wordpress functions wp_nonce_field(), wp_nonce_url() and wp_nonce_create(). <?php // Create an nonce for a link. nonce = wp_create_nonce( 'my-nonce' ); echo '<a href="myplugin.php?do_something=some_action&_wpnonce='.nonce.'">Do some action</a>'; ?>  See also Wordpress Nonce.  Command Line Wordpress/NonceCreation Analyzers Wordpress ## Not Definitions Only¶ Files should only include definitions (class, functions, traits, interfaces, constants), or global instructions, but not both. Within this context, globals, use, and namespaces instructions are not considered a warning.  Command Line Files/NotDefinitionsOnly Analyzers Analyze ## Not Not¶ Double not makes a boolean, not a true. This is a wrongly done casting to boolean. PHP supports (boolean) to do the same, faster and cleaner. <?php // Wrong type casting b = !!x; // Explicit code b = (boolean) x; ?>   Command Line Structures/NotNot clearPHP no-implied-cast Analyzers Analyze ## Null On New¶ Until PHP 7.0, some classes instantiation could yield null, instead of throwing an exception. After issuing a ‘new’ with those classes, it was important to check if the returned object were null or not. No exception were thrown. <?php // Example extracted from the wiki below mf = new MessageFormatter('en_US', '{this was made intentionally incorrect}'); if (mf === null) { echo 'Surprise!'; } ?>  This inconsistency has been cleaned in PHP 7 : see See Internal Constructor Behavior  Command Line Classes/NullOnNew Analyzers Analyze, CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56 ## Objects Don’t Need References¶ There is no need to create references for objects, as those are always passed by reference when used as arguments.  Command Line Structures/ObjectReferences clearPHP no-references-on-objects Analyzers Analyze ## Old Style Constructor¶ A long time ago, PHP classes used to have the method bearing the same name as the class acts as the constructor. <?php namespace { // Global namespace is important class foo { function foo() { // This acts as the old-style constructor, and is reported by PHP } } class bar { function '__construct() { } function bar() { // This doesn't act as constructor, as bar has a '__construct() method } } } namespace Foo\Bar{ class foo { function foo() { // This doesn't act as constructor, as bar is not in the global namespace } } } ?>  This is no more the case in PHP 5, which relies on ‘__construct() to do so. Having this old style constructor may bring in confusion, unless you are also supporting old time PHP 4. Note that classes with methods bearing the class name, but inside a namespace are not following this convention, as this is not breaking backward compatibility. Those are excluded from the analyze.  Command Line Classes/OldStyleConstructor clearPHP no-php4-class-syntax Analyzers Analyze ## Old Style __autoload()¶ Avoid __autoload(). Only use spl_register_autoload(). __autoload() will be deprecated in PHP 7.2 and possibly removed in later version. __autoload() may only be declared once, and cannot be modified later. This creates potential conflicts between libraries that try to set up their own autoloading schema. On the other hand, spl_register_autoload() allows registering and de-registering multiple autoloading functions or methods. <?php // Modern autoloading. function myAutoload(class){} spl_register_autoload('myAutoload'); // Old style autoloading. function __autoload(class){} ?>  Do not use the old __autoload() function, but rather the new spl_register_autoload() function. See also Autoloading Classe.  Command Line Php/oldAutoloadUsage clearPHP use-smart-autoload Analyzers Analyze ## One Letter Functions¶ One letter functions seems to be really short for a meaningful name. This may happens for very high usage functions, so as to keep code short, but such functions should be rare. <?php // One letter functions are rarely meaningful function f(a, b) { return a + b; } ?>   Command Line Functions/OneLetterFunctions Analyzers Analyze ## One Variable String¶ These strings only contains one variable or property or array. <?php a = 0; b = a; // This is a one-variable string // Better way to write the above b = (string) a; // Alternatives : b2 = a[1]; // This is a one-variable string b3 = a->b; // This is a one-variable string c = d; d = D; b4 = "{$$c}";
$b5 = "{$a->foo()}";

?>


If the goal is to convert it to a string, use the type casting (string) operator : it is then clearer to understand the conversion. It is also marginally faster, though very little.

 Command Line Type/OneVariableStrings Analyzers Analyze

## Only Variable Passed By Reference¶

When an argument is expected by reference, it is compulsory to provide a container. A container may be a variable, an array, a property or a static property.

This may be linted by PHP, when the function definition is in the same file as the function usage. This is silently linted if definition and usage are separated, if the call is dynamical or made as a method.

<?php

function foo(&$bar) { /'**/ } foo(strtolower($string));

?>


This analysis currently covers functioncalls and static methodcalls, but omits methodcalls.

 Command Line Functions/OnlyVariablePassedByReference Analyzers Analyze

## Only Variable Returned By Reference¶

Function can’t return literals by reference.

When a function returns a reference, it is only possible to return variables, properties or static properties.

Anything else, like literals or static expressions, yield a warning at execution time.

<?php

// Can't return a literal number
function &foo() {
return 3 + 'rand();
}

// bar must return values that are stored in a
function &bar() {
$a = 3 + 'rand(); return$a;
}

?>

 Command Line Structures/OnlyVariableReturnedByReference Analyzers Analyze

## Or Die¶

Classic old style failed error management.

<?php

// In case the connexion fails, this kills the current script
mysql_connect('localhost', $user,$pass) or 'die();

?>


Interrupting a script will leave the application with a blank page, will make your life miserable for testing. Just don’t do that.

 Command Line Structures/OrDie clearPHP no-implied-if Analyzers Analyze

Replacing the content of a variable by something different is prone to errors. For example, it is not obvious if the $text variable is plain text or HTML text. <?php // Confusing$text = htmlentities($text); // Better$textHTML = htmlentities($text); ?>  Besides, it is possible that the source is needed later, for extra processing. Note that accumulators, like += .= or [] etc., that are meant to collect lots of values with consistent type are OK.  Command Line Variables/Overwriting Analyzers Analyze ## Overwritten Exceptions¶ In catch blocks, it is good practice not to overwrite the incoming exception, as information about the exception will be lost.  Command Line Exceptions/OverwriteException Analyzers Analyze ## Overwritten Literals¶ The same variable is assigned a literal twice. It is possible that one of the assignation is too much. This analysis doesn’t take into account the distance between two assignations : it may report false positives when the variable is actually used for several purposes, and, as such, assigned twice with different values. <?php function foo() { // Two assignations in a short sequence : one is too many.$a = 1;
$a = 2; for($i = 0; $i < 10;$i++) {
$a +=$i;
}
$b =$a;

// New assignation. $a is now used as an array.$a = array(0);
}

?>

 Command Line Variables/OverwrittenLiterals Analyzers Analyze

## PHP 7.0 New Classes¶

Those classes are now declared natively in PHP 7.0 and should not be declared in custom code.

 Command Line Php/Php70NewClasses Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56, CompatibilityPHP71

## PHP 7.0 New Interfaces¶

The following interfaces are introduced in PHP 7.0. They shouldn’t be defined in custom code.

 Command Line Php/Php70NewInterfaces Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56, CompatibilityPHP71

## PHP 7.0 Removed Directives¶

List of directives that are removed in PHP 7.0.

 Command Line Php/Php70RemovedDirective Analyzers CompatibilityPHP70, CompatibilityPHP71

## PHP 7.1 Microseconds¶

PHP 7.1 supports microseconds in DateTime class and date_create() function.

In previous PHP versions, those dates only used seconds, leading to lazy comparisons :

<?php

$now = date_create(); usleep(10); // wait for 0.001 ms var_dump($now == date_create());

?>


This code displays true in PHP 7.0 and older, (unless the code was run too close from the next second). In PHP 7.1, this is always false.

This is also true with Datetime :

<?php

$now = new DateTime(); usleep(10); // wait for 0.001 ms var_dump((new DateTime())->format('u') ==$now->format('u'));

?>


This evolution impacts mostly exact comparisons (== and ===). Non-equality (!= and !==) will probably be always true, and should be reviewed.

 Command Line Php/Php71microseconds Analyzers CompatibilityPHP71, CompatibilityPHP72, CompatibilityPHP73

## PHP 7.1 Removed Directives¶

List of directives that are removed in PHP 7.1.

 Command Line Php/Php71RemovedDirective Analyzers CompatibilityPHP71, CompatibilityPHP72, CompatibilityPHP73

## PHP 7.2 Deprecations¶

PHP 7.2 deprecates several features of the language.

Deprecated functions and extensions are reported in a separate analysis.

 Command Line Php/Php72Deprecation Analyzers CompatibilityPHP72, CompatibilityPHP73

## PHP 7.2 Removed Functions¶

The following PHP native functions were removed in PHP 7.2.

• png2wbmp
• jpeg2wbmp
 Command Line Php/Php72RemovedFunctions Analyzers CompatibilityPHP72, CompatibilityPHP73

## PHP 70 Removed Functions¶

The following PHP native functions were removed in PHP 7.0.

• ereg
• ereg_replace
• eregi
• eregi_replace
• split
• spliti
• sql_regcase
• magic_quotes_runtime
• set_magic_quotes_runtime
• call_user_method
• call_user_method_array
• set_socket_blocking
• mcrypt_ecb
• mcrypt_cbc
• mcrypt_cfb
• mcrypt_ofb
• datefmt_set_timezone_id
• imagepsbbox
• imagepsencodefont
• imagepsextendfont
• imagepsfreefont
• imagepsslantfont
• imagepstext
 Command Line Php/Php70RemovedFunctions Analyzers CompatibilityPHP70, CompatibilityPHP71

## PHP Keywords As Names¶

PHP has a set of reserved keywords. It is recommended not to use those keywords for names structures.

PHP does check that a number of structures, such as classes, methods, interfaces... can’t be named or called using one of the keywords. However, in a few other situations, no check are enforced. Using keywords in such situation is confusing.

 Command Line Php/ReservedNames Analyzers Analyze, CompatibilityPHP71

## PHP5 Indirect Variable Expression¶

Indirect variable expressions changes between PHP 5 an 7.

The following structures are evaluated differently in PHP 5 and 7. It is recommended to review them or switch to a less ambiguous syntax.

<?php

// PHP 7
$foo = 'bar';$bar['bar']['baz'] = 'foobarbarbaz';
echo $$foo['bar']['baz']; echo ($$foo)['bar']['baz'];

// PHP 5
$foo['bar']['baz'] = 'bar';$bar = 'foobarbazbar';
return \strtolower($string); } ?>  Relay functions are typical of transition API, where an old API have to be preserved until it is fully migrated. Then, they may be removed, so as to reduce confusion, and unclutter the API.  Command Line Functions/RelayFunction Analyzers Analyze ## Repeated Regex¶ Repeated regex should be centralized. When a regex is repeatedly used in the code, it is getting harder to update. <?php // Regex used several times, at least twice. preg_match('/^abc_|^square$/i', $_GET['x']); //....... preg_match('/^abc_|^square$/i', $row['name']); // This regex is dynamically built, so it is not reported. preg_match('/^circle|^'.$x.'$/i',$string);

// This regex is used once, so it is not reported.
preg_match('/^circle|^square$/i',$string);

?>


Regex that are repeated at least once (aka, used twice or more) are reported. Regex that are dynamically build are not reported.

 Command Line Structures/RepeatedRegex Analyzers Analyze

## Repeated print()¶

Always merge several print or echo in one call.

It is recommended to use echo with multiple arguments, or a concatenation with print, instead of multiple calls to print echo, when outputting several blob of text.

<?php

//Write :
echo 'a', $b, 'c'; print 'a' .$b . 'c';

//Don't write :
print 'a';
print $b; print 'c'; ?>   Command Line Structures/RepeatedPrint clearPHP no-repeated-print Analyzers Analyze ## Reserved Keywords In PHP 7¶ Php reserved names for class/trait/interface. They won’t be available anymore in user space starting with PHP 7.  Command Line Php/ReservedKeywords7 Analyzers CompatibilityPHP70, CompatibilityPHP71 ## Results May Be Missing¶ preg_match() may return empty values, if the search fails. It is important to check for the existence of results before assigning them to another variable, or using it. <?php preg_match('/PHP ([0-9\.]+) /',$res, $r);$s = $r[1]; //$s may end up null if preg_match fails.
?>

 Command Line Structures/ResultMayBeMissing Analyzers Analyze

## Rethrown Exceptions¶

Throwing a caught exception is usually useless and dead code.

When exception are caught, they should be processed or transformed, but not rethrown.

Those issues often happen when a catch structure was positioned for debug purposes, but lost its usage later.

<?php

try {
doSomething();
} catch (Exception $e) { throw$e;
}

?>

 Command Line Exceptions/Rethrown Analyzers Dead code

## Return True False¶

These conditional expressions return true/false, depending on the condition. This may be simplified by dropping the control structure alltogether.

<?php

if (version_compare($a,$b) >= 0) {
return true;
} else {
return false;
}

?>


This may be simplified with :

<?php

return version_compare($a,$b) >= 0;

?>


This may be applied to assignations and ternary operators too.

<?php

if (version_compare($a,$b) >= 0) {
$a = true; } else {$a = false;
}

$a = version_compare($a, $b) >= 0 ? false : true; ?>   Command Line Structures/ReturnTrueFalse Analyzers Analyze ## Return With Parenthesis¶ PHP tolerates parenthesis for the argument of a return statement, but it is recommended not to use them.  Command Line Php/ReturnWithParenthesis Analyzers Coding Conventions ## Safe CurlOptions¶ It is advised to always use CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST when requesting a SSL connexion. With those tests (by default), the certificate is verified, and if it isn’t valided, the connexion fails : this is a safe behavior. <?php$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, https://www.php.net/); // To be safe, always set this to true curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);

curl_exec($ch); curl_close($ch);
?>

 Command Line Security/CurlOptions Analyzers Security

## Same Conditions¶

Several If then else structures are chained, and some conditions are identical. The latter will be ignored.

<?php

if ($a == 1) { doSomething(); } elseif ($b == 1) { doSomething(); }
elseif ($c == 1) { doSomething(); } elseif ($a == 1) { doSomething(); }
else {}

// Also works on if then else if chains
if ($a == 1) { doSomething(); } else if ($b == 1) { doSomething(); }
else if ($c == 1) { doSomething(); } else if ($a == 1) { doSomething(); }
else {}

?>

 Command Line Structures/SameConditions Analyzers Analyze

## Scalar Typehint Usage¶

Spot usage of scalar type hint : int, float, boolean and string.

 Command Line Php/ScalarTypehintUsage Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56

## Sequences In For¶

For() instructions allows several instructions in each of its parameters. Then, the instruction separator is comma ‘,’, not semi-colon, which is used for separating the 3 arguments.

<?php
for ($a = 0,$b = 0; $a < 10,$b < 20; $a++,$b += 3) {
// For loop
}
?>


This loop will simultaneously increment $a and$b. It will stop only when the last of the central sequence reach a value of false : here, when $b reach 20 and$a will be 6.

This structure is often unknown, and makes the for instruction quite difficult to read. It is also easy to oversee the multiples instructions, and omit one of them. It is recommended not to use it.

 Command Line Structures/SequenceInFor Analyzers Analyze

## Setlocale() Uses Constants¶

setlocal() don’t use strings.

The first argument of ‘setlocale() must be one of the valid constants, LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME, LC_MESSAGES.

<?php

// Use constantes for setlocale first argument
setlocale(LC_ALL, 'nl_NL');
setlocale(\LC_ALL, 'nl_NL');

// Don't use string for setlocale first argument
setlocale('LC_ALL', 'nl_NL');
setlocale('LC_'.'ALL', 'nl_NL');

?>


The PHP 5 usage of strings (same name as above, enclosed in ‘ or ”) is not legit anymore in PHP 7 and later.

 Command Line Structures/SetlocaleNeedsConstants Analyzers CompatibilityPHP70, CompatibilityPHP71

## Several Instructions On The Same Line¶

Usually, instructions do not share their line : one instruction, one line. This is good for readability, and help at understanding the code. This is especially important when fast-reading the code to find some special situation, where such double-meaning line way have an impact.

 Command Line Structures/OneLineTwoInstructions Analyzers Analyze

## Short Open Tags¶

Usage of short open tags is discouraged. The following files were found to be impacted by the short open tag directive at compilation time. They must be reviewed to ensure no &lt;? tags are found in the code.

 Command Line Php/ShortOpenTagRequired Analyzers Analyze

## Short Syntax For Arrays¶

Arrays written with the new PHP 5.4 short syntax.

PHP 5.4 introduced the new short syntax, with square brackets. The previous syntax, based on the array() keyword is still available.

<?php

// All PHP versions array
$a = array(1, 2, 3); // PHP 5.4+ arrays$a = [1, 2, 3];

?>


 Command Line Arrays/ArrayNSUsage Analyzers CompatibilityPHP53

## Should Be Single Quote¶

Use single quote for simple strings.

Static content inside a string, that has no single quotes nor escape sequence (such as n or t), should be using single quote delimiter, instead of double quote.

<?php

$a = abc; // This one is using a special sequence$b = cde\n;

// This one is using two special sequences
throw new Exception('Exception 2', 2, $e); // Chaining here. } ?>   Command Line Structures/ShouldChainException Analyzers Analyze ## Should Make Alias¶ Long names should be aliased. Aliased names are easy to read at the beginning of the script; they may be changed at one point, and update the whole code at the same time. Finally, short names makes the rest of the code readable. <?php namespace x\y\z; use a\b\c\d\e\f\g as Object; // long name, difficult to read, prone to change. new a\b\c\d\e\f\g(); // long name, difficult to read, prone to silent dead code if namespace change. if ($o 'instanceof a\b\c\d\e\f\g) {

}

// short names Easy to update all at once.
new Object();
if ($o 'instanceof Object) { } ?>   Command Line Namespaces/ShouldMakeAlias Analyzers Analyze, ZendFramework ## Should Make Ternary¶ Ternary operators are the best when assigning values to a variable. This way, they are less verbose, compatible with assignation and easier to read. <?php // verbose if then structure if ($a == 3) {
$b = 2; } else {$b = 3;
}

// compact ternary call
$b = ($a == 3) ? 2 : 3;

// verbose if then structure
// Works with short assignations and simple expressions
if ($a != 3) {$b += 2 - $a * 4; } else {$b += 3;
}

// compact ternary call
$b += ($a != 3) ? 2 - $a * 4 : 3; ?>   Command Line Structures/ShouldMakeTernary Analyzers Analyze ## Should Regenerate Session Id¶ No mention of ZendSession::regenerateId() method found. When using ZendSession, or PHP session, a session ID is assigned to the user. It is a random number, used to connect the user and its data on the server. Actually, anyone with the session ID may have access to the data. This is why those session ID are so long and complex. A good approach to protect the session ID is to reduce its lifespan : the shorter the time of use, the better. While changing the session ID at every hit on the page may no be possible, a more reasonable approach is to change the session id when an important action is about to take place. What important means is left to the application to decide. Based on this philopsophy, a code source that uses ZendSession but never uses ZendSession::regenerateId() has to be updated. <?php //Getting the session manager from the application$session = $e->getApplication() ->getServiceManager() ->get('Zend\Session\SessionManager'); ?>   Command Line ZendF/ShouldRegenerateSessionId Analyzers ZendFramework ## Should Typecast¶ When typecasting, it is better to use the casting operator, such as (int) or (bool). Functions such as ‘intval() or ‘settype() are always slower. <?php$int = intval($_GET['x']); // Quicker version$int = (int) $_GET['x']; ?>  This is a micro-optimisation, although such conversion may be use multiple time, leading to a larger performance increase.  Command Line Type/ShouldTypecast Analyzers Analyze ## Should Use Coalesce¶ PHP 7 introduced the ?? operator, that replaces longer structures to set default values when a variable is not set. <?php // Fetches the request parameter user and results in 'nobody' if it doesn't exist$username = $_GET['user'] ?? 'nobody'; // equivalent to:$username = 'isset($_GET['user']) ?$_GET['user'] : 'nobody';

// Calls a hypothetical model-getting function, and uses the provided default if it fails
$model = Model::get($id) ?? $default_model; // equivalent to: if (($model = Model::get($id)) === NULL) {$model = $default_model; } ?>  Sample extracted from PHP docs Isset Ternary  Command Line Php/ShouldUseCoalesce Analyzers Analyze ## Should Use Constants¶ The following functions have related constants that should be used as arguments, instead of scalar literals, such as integers or strings. For example,$lines = file(‘file.txt’, 2); is less readable than $lines = file(‘file.txt’, FILE_IGNORE_NEW_LINES)  Command Line Functions/ShouldUseConstants Analyzers Analyze ## Should Use Function Use¶ Functioncalls that fall back to global scope should be using ‘use function’ or be fully namespaced. PHP searches for functions in the local namespaces, and in case it fails, makes the same search in the global scope. Anytime a native function is referenced this way, the search (and fail) happens. This slows down the scripts. The speed bump range from 2 to 8 %, depending on the availability of functions in the local scope. The overall bump is about 1 µs per functioncall, which makes it a micro optimisation until a lot of function calls are made. Based on one of Marco Pivetta tweet and this blog post <?php namespace X { use function strtolower as strtolower_aliased; // PHP searches for strtolower in X, fails, then falls back to global scope, succeeds.$a = strtolower($b); // PHP searches for strtolower in global scope, succeeds.$a = \strtolower($b); // PHP searches for strtolower_aliased in global scope, succeeds.$a = \strtolower_aliased($b); } ?>   Command Line Php/ShouldUseFunction Analyzers Performances ## Should Use Local Class¶ Methods in a class should use the class, or be functions. Methods should use$this with another method or a property, or call parent::. Static methods should call another static method, or a static property. Methods which are overwritten by a child class are omitted : the parent class act as a default value for the children class, and this is correct.

<?php

class foo {
public function '__construct() {
// This method should do something locally, or be removed.
}
}

class bar extends foo {
private $a = 1; public function '__construct() { // Calling parent:: is sufficient parent::'__construct(); } public function barbar() { // This is acting on the local object$this->a++;
}

public function barfoo($b) { // This has no action on the local object. It could be a function or a closure where needed return 3 +$b;
}
}

?>


Note that a method using a class constant is not considered as using the local class, for this analyzer.

 Command Line Classes/ShouldUseThis clearPHP not-a-method Analyzers Analyze

## Should Use Prepared Statement¶

Modern databases provides support for prepared statement : it separates the query from the processed data and highten significantly the security.

Building queries with concatenations is not recommended, though not always avoidable. When possible, use prepared statements.

 Command Line Security/ShouldUsePreparedStatement Analyzers Analyze, Security

Use ‘setcookie() or ‘setrawcookie(). Avoid using ‘header() to do so, as the PHP native functions are more convenient and easier to spot during a refactoring.

‘setcookie() applies some encoding internally, for the value of the cookie and the date of expiration. Rarely, this encoding has to be skipped : then, use setrawencoding().

Both functions help by giving a checklist of important attributes to be used with the cookie.

<?php

// same as below

// same as above. Slots for path and domain are omitted, but should be used whenever possible

?>


## Should Use array_column()¶

Should use ‘array_column().

‘array_column() is a native PHP function, that extract a property or a index from a array of object, or a multidimensional array. This prevents the usage of foreach to collect those values.

<?php

$a = array(array('b' => 1), array('b' => 2, 'c' => 3), array( 'c' => 4)); // b doesn't always exists$bColumn = array_column($a, 'b'); // Slow and cumbersome code$bColumn = array();
foreach($a as$k => $v) { if ('isset($v['b'])) {
$bColumn[] =$v['b'];
}
}

?>


‘array_column() is faster than ‘foreach() (with or without the ‘isset() test) with 3 elements or more, and it is significantly faster beyond 5 elements. Memory consumption is the same.

 Command Line Php/ShouldUseArrayColumn Analyzers Analyze, Performances

## Should Use session_regenerateid()¶

session_regenerateid() should be used when sessions are used.

When using sessions, a session ID is assigned to the user. It is a random number, used to connect the user and its data on the server. Actually, anyone with the session ID may have access to the data. This is why those session ID are so long and complex.

A good approach to protect the session ID is to reduce its lifespan : the shorter the time of use, the better. While changing the session ID at every hit on the page may no be possible, a more reasonable approach is to change the session id when an important action is about to take place. What important means is left to the application to decide.

Based on this philopsophy, a code source that uses ZendSession but never uses ZendSession::regenerateId() has to be updated.

<?php

session_start();

$id = (int)$_SESSION['id'];
// no usage of session_regenerateid() anywhere triggers the analysis

// basic regeneration every 20 hits on the page.
if (++$_SESSION['count'] > 20) { session_regenerateid(); } ?>   Command Line Security/ShouldUseSessionRegenerateId Analyzers Security ## Silently Cast Integer¶ Those are integer literals that are cast to a float when running PHP. They are simply too big for the current PHP version, and PHP resorts to cast them into a float, which has a much larger capacity but a lower precision. Compare your literals to PHP_MAX_INT (typically 9223372036854775807) and PHP_MIN_INT (typically -9223372036854775808). This applies to binary (0b10101...), octals (0123123...) and hexadecimals (0xfffff...) too. <?php echo 0b1010101101010110101011010101011010101011010101011010101011010111; //6173123008118052203 echo 0b10101011010101101010110101010110101010110101010110101010110101111; //1.2346246016236E+19 echo 0123123123123123123123; //1498121094048818771 echo 01231231231231231231231; //1.1984968752391E+19 echo 0x12309812311230; //5119979279159856 echo 0x12309812311230fed; //2.0971435127439E+19 echo 9223372036854775807; //PHP_MAX_INT //9223372036854775807 echo 9223372036854775808; 9.2233720368548E+18 ?>   Command Line Type/SilentlyCastInteger Analyzers Analyze ## Simple Global Variable¶ The global keyword should only be used with simple variables. Since PHP 7, it cannot be used with complex or dynamic structures. <?php // Forbidden in PHP 7 global$normalGlobal;

// Forbidden in PHP 7
global $$variable->global ; // Tolerated in PHP 7 global {variable->global}; ?>   Command Line Php/GlobalWithoutSimpleVariable Analyzers CompatibilityPHP70, CompatibilityPHP71 ## Simplify Regex¶ PRCE regex are a powerful way to search inside strings, but they also come at the price of performance. When the query is simple enough, try using ‘strpos() or ‘stripos() instead. <?php // simple preg calls if (preg_match('/a/', string)) {} if (preg_match('/b/i', string)) {} // case insensitive // light replacements if( strpos('a', string)) {} if( stripos('b', string)) {} // case insensitive ?>   Command Line Structures/SimplePreg Analyzers Performances ## SlimPHP 1.0.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 1.0.0 of SlimPHP. SlimPHP 1.0.0 has 22 classes, no traits and no interfaces; See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp10 Analyzers Slim ## SlimPHP 1.1.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 1.1.0 of SlimPHP. SlimPHP 1.1.0 has 33 classes, no traits and no interfaces; 11 new classes. See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp11 Analyzers Slim ## SlimPHP 1.2.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 1.2.0 of SlimPHP. SlimPHP 1.2.0 has 35 classes, no traits and no interfaces; 14 new classes. 12 removed classes. See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp12 Analyzers Slim ## SlimPHP 1.3.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 1.3.0 of SlimPHP. SlimPHP 1.3.0 has 33 classes, no traits and no interfaces; 4 new classes. 6 removed classes. See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp13 Analyzers Slim ## SlimPHP 1.5.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 1.5.0 of SlimPHP. SlimPHP 1.5.0 has 33 classes, no traits and no interfaces; 1 new class. 1 removed class. See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp15 Analyzers Slim ## SlimPHP 1.6.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 1.6.0 of SlimPHP. SlimPHP 1.6.0 has 45 classes, no traits and no interfaces; 25 new classes. 13 removed classes. See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp16 Analyzers Slim ## SlimPHP 2.0.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 2.0.0 of SlimPHP. SlimPHP 2.0.0 has 44 classes, no traits and no interfaces; 21 new classes. 22 removed classes. See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp20 Analyzers Slim ## SlimPHP 2.1.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 2.1.0 of SlimPHP. SlimPHP 2.1.0 has 44 classes, no traits and no interfaces; See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp21 Analyzers Slim ## SlimPHP 2.2.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 2.2.0 of SlimPHP. SlimPHP 2.2.0 has 45 classes, no traits and no interfaces; 2 new classes. 1 removed class. See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp22 Analyzers Slim ## SlimPHP 2.3.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 2.3.0 of SlimPHP. SlimPHP 2.3.0 has 48 classes, no traits and no interfaces; 5 new classes. 2 removed classes. See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp23 Analyzers Slim ## SlimPHP 2.4.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 2.4.0 of SlimPHP. SlimPHP 2.4.0 has 48 classes, no traits and no interfaces; See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp24 Analyzers Slim ## SlimPHP 2.5.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 2.5.0 of SlimPHP. SlimPHP 2.5.0 has 50 classes, no traits and no interfaces; 2 new classes. See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp25 Analyzers Slim ## SlimPHP 2.6.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 2.6.0 of SlimPHP. SlimPHP 2.6.0 has 50 classes, no traits and no interfaces; See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp26 Analyzers Slim ## SlimPHP 3.0.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 3.0.0 of SlimPHP. SlimPHP 3.0.0 has 55 classes, 2 traits and 9 interfaces; 49 new classes, 9 new interfaces, 2 new traits. 44 removed classes. See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp30 Analyzers Slim ## SlimPHP 3.1.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 3.1.0 of SlimPHP. SlimPHP 3.1.0 has 55 classes, 2 traits and 9 interfaces; See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp31 Analyzers Slim ## SlimPHP 3.2.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 3.2.0 of SlimPHP. SlimPHP 3.2.0 has 59 classes, 2 traits and 9 interfaces; 4 new classes. See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp32 Analyzers Slim ## SlimPHP 3.3.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 3.3.0 of SlimPHP. SlimPHP 3.3.0 has 60 classes, 2 traits and 9 interfaces; 1 new classe. See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp33 Analyzers Slim ## SlimPHP 3.4.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 3.4.0 of SlimPHP. SlimPHP 3.4.0 has 64 classes, 2 traits and 9 interfaces; 4 new classes. See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp34 Analyzers Slim ## SlimPHP 3.5.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 3.5.0 of SlimPHP. SlimPHP 3.5.0 has 67 classes, 2 traits and 9 interfaces; 3 new classes. See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp35 Analyzers Slim ## SlimPHP 3.6.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 3.6.0 of SlimPHP. SlimPHP 3.6.0 has 67 classes, 2 traits and 9 interfaces; See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp36 Analyzers Slim ## SlimPHP 3.7.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 3.7.0 of SlimPHP. SlimPHP 3.7.0 has 67 classes, 2 traits and 9 interfaces; See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp37 Analyzers Slim ## SlimPHP 3.8.0 Undefined Classes¶ SlimPHP classes, interfaces and traits that are not defined in version 3.8.0 of SlimPHP. SlimPHP 3.8.0 has 68 classes, 2 traits and 9 interfaces; 1 new classe. See also : SlimPHP and SlimPHP/slim.  Command Line Slim/Slimphp38 Analyzers Slim ## Slow Functions¶ Avoid using those slow native PHP functions, and replace them with alternatives. <?php array = source(); // Slow extraction of distinct values array = array_unique(array); // Much faster extraction of distinct values array = array_keys(array_count_values(array)); ?>   Slow Function Faster ‘array_diff() ‘array_intersect() ‘array_key_exists() ‘array_map() ‘array_search() ‘array_udiff() ‘array_uintersect() ‘array_unique() ‘array_unshift() ‘array_walk() ‘in_array() ‘preg_replace() ‘strstr() ‘uasort() ‘uksort() ‘usort() ‘foreach() ‘foreach() ‘isset() ‘foreach() ‘array_flip() and ‘isset() Use another way Use another way ‘array_keys() and ‘array_count_values() Use another way ‘foreach() ‘isset() ‘strpos() ‘strpos() Use another way Use another way Use another way  Command Line Performances/SlowFunctions clearPHP avoid-those-slow-functions Analyzers Performances ## Static Loop¶ Static loop may be preprocessed. It looks like the following loops are static : the same code is executed each time, without taking into account loop variables. <?php // Static loop total = 0; for(i = 0; i < 10; i++) { total += i; } // Non-Static loop (the loop depends on the size of the array) n = count(array); for(i = 0; i < n; i++) { total += i; } ?>  It is possible to create loops that don’t use any blind variables, though this is fairly rare.  Command Line Structures/StaticLoop Analyzers Analyze ## Static Methods Called From Object¶ Static methods may be called without instantiating an object. As such, they never interact with the special variable ‘this’, as they do not depend on object existence. Besides this, static methods are normal methods that may be called directly from object context, to perform some utility task. To maintain code readability, it is recommended to call static method in a static way, rather than within object context. <?php class x { static function y( ) {} } z = new x( ); z->y( ); // Readability : no one knows it is a static call x::y( ); // Readability : here we know ?>   Command Line Classes/StaticMethodsCalledFromObject Analyzers Analyze ## Static Methods Can’t Contain this¶ Static methods are also called ‘class methods’ : they may be called even if the class has no instantiated object. Thus, the local variable this won’t exist, PHP will set it to NULL as usual. <?php class foo { // Static method may access other static methods, or property, or none. static function staticBar() { // This is not possible in a static method return self::otherStaticBar() . static::staticProperty; } static function bar() { // This is not possible in a static method return this->property; } } ?>  Either, this is not a static method (simply remove the static keyword), or replace all this mention by static properties Class::property.  Command Line Classes/StaticContainsThis clearPHP no-static-this Analyzers Analyze ## Strange Name For Constants¶ Those constants looks like a typo from other names. <?php // This code looks OK : DIRECTORY_SEPARATOR is a native PHP constant path = path . DIRECTORY_SEPARATOR . file; // Strange name DIRECOTRY_SEPARATOR path = path . DIRECOTRY_SEPARATOR . file; ?>   Command Line Constants/StrangeName Analyzers none ## Strange Name For Variables¶ Those variables looks like a typo from other names. <?php class foo { function bar() { // Strange name tihs return tihs; } } ?>   Command Line Variables/StrangeName Analyzers Wordpress, Analyze, Analyze ## Strange Names For Methods¶ Those methods should have another name. Ever wondered why the ‘__constructor’ is never called? Or the ‘__consturct’ ? Those errors most often originate from typos, or quick fixes that ‘don’t require testing’. Some other times, they were badly chosen, or ran into PHP’s own reservations. <?php class foo { // The real constructor function '__construct() {} // The fake constructor function __constructor() {} // The 'typo'ed' constructor function __consturct() {} // This doesn't clone function clone() {} } ?>   Command Line Classes/StrangeName Analyzers none ## Strict Comparison With Booleans¶ Booleans may be easily mistaken with other values, especially when the function may return integer or boolean as a normal course of action. It is encouraged to use strict comparison === or !== when booleans are involved in a comparison.  Command Line Structures/BooleanStrictComparison Analyzers Analyze ## String May Hold A Variable¶ Those strings looks like holding a variable. Single quotes and Nowdoc syntax may include  signs that are treated as literals, and not replaced with a variable value. However, there are some potential variables in those strings, making it possible for an error : the variable was forgotten and will be published as such. It is worth checking the content and make sure those strings are not variables. <?php a = 2; // Explicit variable, but literal effect is needed echo 'a is '.a; // One of the variable has been forgotten echo 'a is a'; // CAD is not a variable, rather a currency unit total = 12; echo total.' CAD'; // CAD is not a variable, rather a currency unit total = 12; // Here, total has been forgotten echo <<<'TEXT' total CAD TEXT; ?>   Command Line Type/StringHoldAVariable Analyzers Analyze ## Strings With Strange Space¶ An invisible space may be mistaken for a normal space. However, PHP does straight comparisons, and may fail at recognizing. This analysis reports when it finds such strange spaces inside strings. PHP doesn’t mistake space and tables for whitespace when tokenizing the code. This analysis doesn’t report Unicode Codepoint Notation : those are clearly visible in the code. <?php // PHP 7 notation, a = \u{3000}; b = ; // Displays false var_dump(a === b); ?>   Command Line Type/StringWithStrangeSpace Analyzers Analyze ## Strpos Comparison¶ ‘strpos() returns a string position, starting at 0, or false, in case of failure. <?php // This is the best comparison if (strpos(string, 'a') === false) { } // This is OK, as 2 won't be mistaken with false if (strpos(string, 'a') == 2) { } // strpos is one of the 26 functions that may behave this way if (preg_match(regex, string)) { } // This works like above, catching the value for later reuse if (a = strpos(string, 'a')) { } // This misses the case where 'a' is the first char of the string if (strpos(string, 'a')) { } // This misses the case where 'a' is the first char of the string, just like above if (strpos(string, 'a') == 0) { } ?>  It is recommended to check the reslt of strpos with === or !==, so as to avoid confusing 0 and false. This analyzer list all the ‘strpos() function that are directly compared with == or !=.  Command Line Structures/StrposCompare clearPHP strict-comparisons Analyzers Analyze ## Structures/NoReferenceOnLeft¶ Do not use references as the right element in an assignation. <?php b = 2; c = 3; a = &b + c; // a === 2 === b; a = b + c; // a === 5 ?>  This is the case for most situations : addition, multiplication, bitshift, logical, power, concatenation. Note that PHP won’t compile the code if the operator is a short operator (+=, .=, etc.), nor if the & is on the right side of the operator.  Command Line Structures/NoReferenceOnLeft Analyzers Analyze ## Suspicious Comparison¶ The comparison seems to be misplaced. A comparison happens in the the last argument, while the actual function expect another type : this may be the case of a badly placed parenthesis. <?php // trim expect a string, a boolean is given. if (trim(str === '')){ } // Just move the first closing parenthesis to give back its actual meaning if (trim(str === '')){ } ?>  Original idea by Vladimir Reznichenko.  Command Line Structures/SuspiciousComparison Analyzers Analyze ## Switch To Switch¶ The following structures are based on if / elseif / else. Since they have more than three conditions (not withstanding the final else), it is recommended to use the switch structure, so as to make this more readable. On the other hand, ‘switch() structures will less than 3 elements should be expressed as a if / else structure. Note that if condition that uses strict typing (=== or !==) can’t be converted to ‘switch() as the latter only performs == or != comparisons. <?php if (a == 1) { } elseif (a == 2) { } elseif (a == 3) { } elseif (a == 4) { } else { } // Better way to write long if/else lists switch (a) { case 1 : doSomething(1); 'break 1; case 2 : doSomething(2); 'break 1; case 3 : doSomething(3); 'break 1; case 4 : doSomething(4); 'break 1; default : doSomething(); 'break 1; } ?>   Command Line Structures/SwitchToSwitch Analyzers Analyze ## Switch With Too Many Default¶ Switch statements should only hold one default, not more. Check the code and remove the extra default. PHP 7.0 won’t compile a script that allows for several default cases. Multiple default happens often with large ‘switch(). <?php switch(a) { case 1 : 'break; default : 'break; case 2 : 'break; default : // This default is never reached 'break; } ?>   Command Line Structures/SwitchWithMultipleDefault Analyzers Analyze ## Switch Without Default¶ Always use a default statement in ‘switch(). Switch statements hold a number of ‘case’ that cover all known situations, and a ‘default’ one which is executed when all other options are exhausted. <?php // Missing default switch(format) { case 'gif' : processGif(); 'break 1; case 'jpeg' : processJpeg(); 'break 1; case 'bmp' : throw new UnsupportedFormat(format); } // In case format is not known, then switch is ignored and no processing happens, leading to preparation errors // switch with default switch(format) { case 'text' : processText(); 'break 1; case 'jpeg' : processJpeg(); 'break 1; case 'rtf' : throw new UnsupportedFormat(format); default : throw new UnknownFileFormat(format); } // In case format is not known, an exception is thrown for processing ?>  Most of the time, ‘switch() do need a default case, so as to catch the odd situation where the ‘value is not what it was expected’. This is a good place to catch unexpected values, to set a default behavior.  Command Line Structures/SwitchWithoutDefault clearPHP no-switch-without-default Analyzers Analyze ## Ternary In Concat¶ Ternary operator has higher priority than dot ‘.’ for concatenation. This means that : <?php print 'B'.b.'C'. b > 1 ? 'D' : 'E'; ?>  prints actually ‘E’, instead of the awaited ‘B0CE’. To be safe, always add parenthesis when using ternary operator with concatenation.  Command Line Structures/TernaryInConcat Analyzers Analyze ## Throw Functioncall¶ The throw keyword is excepted to use an exception. Calling a function to prepare that exception before throwing it is possible, but forgetting the new keyword is also possible. <?php // Forgotten new throw \RuntimeException('error!'); // Code is OK, function returns an exception throw getException(ERROR_TYPE, 'error!'); function getException(ERROR_TYPE, message) { return new \RuntimeException(messsage); } ?>  When the new keyword is forgotten, then the class construtor is used as a functionname, and now exception is emited, but an ‘Undefined function’ fatal error is emited.  Command Line Exceptions/ThrowFunctioncall Analyzers Analyze ## Throw In Destruct¶ According to the manual, ‘Attempting to throw an exception from a destructor (called in the time of script termination) causes a fatal error.’ The destructor may be called during the lifespan of the script, but it is not certain. If the exception is thrown later, the script may end up with a fatal error. Thus, it is recommended to avoid throwing exceptions within the ‘__destruct method of a class. <?php // No exception thrown class Bar { function '__construct() { throw new Exception(''__construct'); } function '__destruct() { this->cleanObject(); } } // Potential crash class Foo { function '__destruct() { throw new Exception(''__destruct'); } } ?>   Command Line Classes/ThrowInDestruct Analyzers Analyze ## Thrown Exceptions¶ All Zend Framework thrown exceptions. <?php //All directly thrown exceptions are reported throw new \RuntimeException('Error while processing'); // Zend exceptions are also reported, thrown or not w = new \Zend\Filter\Exception\ExtensionNotLoadedException(); throw w; ?>   Command Line ZendF/ThrownExceptions Analyzers ZendFramework ## Throws An Assignement¶ It is possible to throw an exception, and, in the same time, assign this exception to a variable. <?php // e is useful, though not by much e = new() Exception(); throw e; // e is useless throw e = new() Exception(); ?>  However, e will never be used, as the exception is thrown, and any following code is not executed. The assignement should be removed.  Command Line Structures/ThrowsAndAssign Analyzers Analyze ## Timestamp Difference¶ time() and ‘microtime() shouldn’t be used to calculate duration or with durations. time() and ‘microtime() are subject to variations, depending on system clock variations, such as daylight saving time difference (every spring and fall, one hour variation), or leap seconds, happening on June, 30th or december 31th, as announcec by IERS. <?php // Calculating tomorow, same hour, the wrong way // tomorrow is not always in 86400s, especially in countries with daylight saving tomorrow = time() + 86400; // Good way to calculate tomorrow datetime = new DateTime('tomorrow'); ?>  When the difference may be rounded to a larger time unit (rounding the difference to days, or several hours), the variation may be ignored safely. When the difference is very small, it requires a better way to mesure time difference, such as ticks, ext/hrtime, or including a check on the actual time zone (‘ini_get() with ‘date.timezone’).  Command Line Structures/TimestampDifference Analyzers Analyze ## Too Many Finds¶ Too many methods called ‘find*’ in this class. It is may be time to consider the Specification pattern. <?php // quite a fishy interface interface UserInterface { public function findByEmail(email); public function findByUsername(username); public function findByFirstName(firstname); public function findByLastName(lastname); public function findByName(name); public function findById(id); public function insert(user); public function update(user); } ?>   Command Line Classes/TooManyFinds Analyzers Analyze ## Too Many Injections¶ When a class is constructed with more than four dependencies, it should be split into smaller classes. <?php // This class relies on 5 other instances. // It is probably doing too much. class Foo { public function '__construct( A a, B b, C c, D d E e ) { this->a = a; this->b = b; this->d = d; this->d = d; this->e = e; } } ?>  See also Dependency Injection Smells.  Command Line Classes/TooManyInjections Analyzers Analyze ## Too Many Local Variables¶ Too many local variables were found in the methods. When over 15 variables are found in such a method, a violation is reported. Local variables exclude globals (imported with global) and arguments. When too many variables are used in a function, it is a code smells. The function is trying to do too much and needs extra space for juggling. Beyond 15 variables, it becomes difficult to keep track of their name and usage, leading to confusion, overwritting or hijacking. <?php // This function is OK : 3 vars are arguments, 3 others are globals. function a20a3g3(a1, a2, a3) { global a4, a5, a6; a1 = 1; a2 = 2; a3 = 3 ; a4 = 4 ; a5 = 5 ; a6 = 6 ; a7 = 7 ; a8 = 8 ; a9 = 9 ; a10 = 10; a11 = 11; a12 = 12; a13 = 13 ; a14 = 14 ; a15 = 15 ; a16 = 16 ; a17 = 17 ; a18 = 18 ; a19 = 19 ; a20 = 20; } // This function has too many variables function a20() { a1 = 1; a2 = 2; a3 = 3 ; a4 = 4 ; a5 = 5 ; a6 = 6 ; a7 = 7 ; a8 = 8 ; a9 = 9 ; a10 = 10; a11 = 11; a12 = 12; a13 = 13 ; a14 = 14 ; a15 = 15 ; a16 = 16 ; a17 = 17 ; a18 = 18 ; a19 = 19 ; a20 = 20; } ?>   Command Line Functions/TooManyLocalVariables Analyzers Analyze ## Uncaught Exceptions¶ The following exceptions are thrown in the code, but are never caught. Either they will lead to a fatal error, or they have to be caught by a larger application.  Command Line Exceptions/UncaughtExceptions Analyzers Analyze ## Unchecked Resources¶ Resources are created, but never checked before being used. This is not safe. Always check that resources are correctly created before using them <?php // always check that the resource is created correctly fp = fopen(d,'r'); if (fp === false) { throw new Exception('File not found'); } firstLine = fread(fp); // This directory is not checked : the path may not exist and return false uncheckedDir = opendir(pathToDir); while(readdir(uncheckedDir)) { // do something() } // This file is not checked : the path may not exist or be unreadable and return false fp = fopen(pathToFile); while(line = freads(fp)) { text .= line; } // quick unsafe one-liner : using bzclose on an unchecked resource bzclose(bzopen('file')); ?>   Command Line Structures/UncheckedResources clearPHP no-unchecked-resources Analyzers Analyze ## Undefined Caught Exceptions¶ Those are exceptions that are caught in the code, but are not defined in the application. They may be externally defined, such as in core PHP, extensions or libraries. Make sure those exceptions are usefull to your application : otherwise, they are dead code. <?php try { library_function(some, args); } catch (LibraryException e) { // This exception is not defined, and probably belongs to Library print Library failed\n; } catch (OtherLibraryException e) { // This exception is not defined, and probably do not belongs to this code print Library failed\n; } catch (\Exception e) { // This exception is a PHP standard exception print Something went wrong, but not at Libary level\n; } ?>   Command Line Exceptions/CaughtButNotThrown Analyzers Dead code ## Undefined Class 2.0¶ Mark classes, interfaces and traits when they are not available in Zend Framework 2.0. <?php // 2.0 only class a = new Zend\Authentication\Adapter\Digest(); // Not a 2.0 class (2.1+) b = d 'instanceof Zend\Authentication\Adapter\Callback; ?>   Command Line ZendF/UndefinedClass20 Analyzers ZendFramework ## Undefined Class 2.1¶ Mark classes, interfaces and traits when they are not available in Zend Framework 2.0. <?php // 2.0 only class a = new Zend\Authentication\Adapter\Digest(); // Not a 2.0 class (2.1+) b = d 'instanceof Zend\Authentication\Adapter\Callback; ?>   Command Line ZendF/UndefinedClass21 Analyzers ZendFramework ## Undefined Class 2.2¶ Mark classes, interfaces and traits when they are not available in Zend Framework 2.2. <?php // 2.2 class (may be other versions) a = new Zend\Authentication\Adapter\DbTable\AbstractAdapter(); // Not a 2.2 class (2.2+) b = d 'instanceof Zend\Authentication\Adapter\Callback; ?>   Command Line ZendF/UndefinedClass22 Analyzers ZendFramework ## Undefined Class 2.3¶ Mark classes, interfaces and traits when they are not available in Zend Framework 2.3. <?php // 2.3 class a = new Zend\Authentication\Adapter\DbTable\CredentialTreatmentAdapter(); // Not a 2.3 class b = d 'instanceof Zend\Cache\Module; ?>   Command Line ZendF/UndefinedClass23 Analyzers ZendFramework ## Undefined Class 2.4¶ Mark classes, interfaces and traits when they are not available in Zend Framework 2.4. <?php // 2.4 class a = new Zend\Authentication\Adapter\DbTable\AbstractAdapter(); // Not a 2.4 class b = d 'instanceof Zend\Cache\Service\StorageAdapterPluginManagerFactory; ?>   Command Line ZendF/UndefinedClass24 Analyzers ZendFramework ## Undefined Class 2.5¶ Mark classes, interfaces and traits when they are not available in Zend Framework 2.5. <?php // 2.5 class a = new Zend\Authentication\Adapter\DbTable\AbstractAdapter(); // Not a 2.5 class b = d 'instanceof Zend\Cache\Service\PatternPluginManagerFactory; ?>   Command Line ZendF/UndefinedClass25 Analyzers ZendFramework ## Undefined Class 3.0¶ Mark classes, interfaces and traits when they are not available in Zend Framework 2.5. <?php // 3.0 class a = new Zend\Authentication\Adapter\DbTable\CallbackCheckAdapter(); // Not a 3.0 class b = d 'instanceof Zend\EventManager\GlobalEventManager; ?>   Command Line ZendF/UndefinedClass30 Analyzers ZendFramework ## Undefined Class Constants¶ Class constants that are used, but never defined. This should yield a fatal error upon execution, but no feedback at compile level. <?php class foo { const A = 1; define('B', 2); } // here, C is not defined in the code and is reported echo foo::A.foo::B.foo::C; ?>   Command Line Classes/UndefinedConstants Analyzers Analyze, Analyze ## Undefined Classes¶ Those classes are used in the code, but there are no definition for them. This may happens under normal conditions, if the application makes use of an unsupported extension, that defines extra classes; or if some external libraries, such as PEAR, are not provided during the analysis. <?php // FPDF is a classic PDF class, that is usually omitted by Exakat. o = new FPDF(); // Exakat reports undefined classes in 'instanceof // PHP ignores them if (o 'instanceof SomeClass) { // doSomething(); } // Classes may be used in typehint too function foo(TypeHintClass x) { // doSomething(); } ?>   Command Line Classes/UndefinedClasses Analyzers Analyze ## Undefined Constants¶ Constants definition can’t be located. Those constants are not defined in the code, and will raise errors, or use the fallback mechanism of being treated like a string. <?php const A = 1; define('B', 2); // here, C is not defined in the code and is reported echo A.B.C; ?>  It is recommended to define them all, or to avoid using them.  Command Line Constants/UndefinedConstants Analyzers none ## Undefined Functions¶ Those functions are not defined in the code. This means that the functions are probably defined in a missing library, or in an extension. If not, this will yield a Fatal error at execution. <?php // Undefined function foo(a); // valid function, as it belongs to the ext/yaml extension parsed = yaml_parse(yaml); // This function is not defined in the a\b\c namespace, nor in the global namespace a\b\c\foo(); ?>   Command Line Functions/UndefinedFunctions Analyzers Analyze ## Undefined Interfaces¶ Typehint or ‘instanceof that are relying on undefined interfaces (or classes) : they will always return false. Any condition based upon them are dead code. <?php class var implements undefinedInterface { // If undefinedInterface is undefined, this code lints but doesn't run } if (o 'instanceof undefinedInterface) { // This is silent dead code } function foo(undefinedInterface a) { // This is dead code // it will probably be discovered at execution } ?>   Command Line Interfaces/UndefinedInterfaces Analyzers Analyze ## Undefined Parent¶ List of properties and methods that are accessed using ‘parent’ keyword but are not defined in the parent class. This will be compilable but will yield a fatal error during execution. Note that if the parent is defined (extends someClass) but someClass is not available in the tested code (it may be in composer, another dependency, or just not there) it will not be reported.  Command Line Classes/UndefinedParentMP Analyzers Analyze ## Undefined Properties¶ List of properties that are not explicitely defined in the class, its parents or traits.  Command Line Classes/UndefinedProperty clearPHP no-undefined-properties Analyzers Analyze ## Undefined Trait¶ Those traits are undefined. When the using class or trait is instantiated, PHP emits a a fatal error. <?php use Composer/Component/someTrait as externalTrait; trait t { function foo() {} } // This class uses trait that are all known class hasOnlyDefinedTrait { use t, externalTrait; } // This class uses trait that are unknown class hasUndefinedTrait { use unknownTrait, t, externalTrait; } ?>   Command Line Traits/UndefinedTrait Analyzers Analyze ## Undefined Zend 1.10¶ List of undefined classes or interfaces in Zend 1.10.  Command Line ZendF/UndefinedClass110 Analyzers ZendFramework ## Undefined Zend 1.11¶ List of undefined classes or interfaces in Zend 1.11  Command Line ZendF/UndefinedClass111 Analyzers ZendFramework ## Undefined Zend 1.12¶ List of undefined classes or interfaces in Zend 1.12.  Command Line ZendF/UndefinedClass112 Analyzers ZendFramework ## Undefined Zend 1.8¶ List of undefined classes or interfaces in Zend 1.8.  Command Line ZendF/UndefinedClass18 Analyzers ZendFramework ## Undefined Zend 1.9¶ List of undefined classes or interfaces in Zend 1.9.  Command Line ZendF/UndefinedClass19 Analyzers ZendFramework ## Undefined static:: Or self::¶ List of all undefined static and self properties and methods.  Command Line Classes/UndefinedStaticMP Analyzers Analyze ## Unescaped Variables In Templates¶ Whenever variables are emitted, they are reported as long as they are not escaped. While this is quite a strict rule, it is good to know when variables are not protected at echo time. <?php echo unescapedVariable; echo esc_html(escapedVariable); ?>   Command Line Wordpress/UnescapedVariables Analyzers Wordpress ## Unicode Escape Partial¶ PHP 7 introduces a new escape sequence for strings : u{hex}. It is backward incompatible with previous PHP versions for two reasons : PHP 7 will recognize en replace those sequences, while PHP 5 keep them intact. PHP 7 will halt on partial Unicode Sequences, as it tries to understand them, but may fail. <?php echo \u{1F418}\n; // PHP 5 displays the same string // PHP 7 displays : an elephant echo \u{NOT A UNICODE CODEPOINT}\n; // PHP 5 displays the same string // PHP 7 emits a fatal error ?>  Is is recommended to check all those strings, and make sure they will behave correctly in PHP 7.  Command Line Php/UnicodeEscapePartial Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56 ## Unicode Escape Syntax¶ Usage of the Unicode Escape syntax, with the u{xxxxx} format, available since PHP 7.0. <?php // Produce an elephant icon in PHP 7.0+ echo \u{1F418}; // Produce the raw sequence in PHP 5.0 echo \u{1F418}; ?>   Command Line Php/UnicodeEscapeSyntax Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56 ## Unitialized Properties¶ Properties that are not initialized in the constructor, nor at definition. <?php class X { private i1 = 1, i2; protected u1, u2; function '__construct() { this->i2 = 1 + this->u2; } function m() { echo this->i1, this->i2, this->u1, this->u2; } } ?>  With the above class, when m() is accessed right after instantiation, there will be a missing property. Using default values at property definition, or setting default values in the constructor ensures that the created object is consistent.  Command Line Classes/UnitializedProperties Analyzers Analyze ## Unknown Directive Name¶ Unknown directives names used in the code. The following list has directive mentionned in the code, that are not known from PHP or any extension. If this is due to a mistake, the directive must be fixed to be actually useful. <?php // non-existing directive reporting_error = ini_get('reporting_error'); error_reporting = ini_get('error_reproting'); // Note the inversion if (ini_set('dump_globals')) { // doSomething() } // Correct directives error_reporting = ini_get('reporting_error'); if (ini_set('xdebug.dump_globals')) { // doSomething() } ?>   Command Line Php/DirectiveName Analyzers Analyze ## Unkown Regex Options¶ PHP’s regex support the following list of options : eimsuxADJSUX. They are detailled in the manual : [http://php.net/manual/en/reference.pcre.pattern.modifiers.php](http://php.net/manual/en/reference.pcre.pattern.modifiers.php). All other options are not supported, may be ignored or raise an error. <?php // all options are available if (preg_match('/\d+/isA', string, results)) { } // p and h are not regex options, p is double if (preg_match('/\d+/php', string, results)) { } ?>   Command Line Structures/UnknownPregOption Analyzers Analyze ## Unpreprocessed Values¶ Preprocessing values is the preparation of values before PHP executes the code. There is no macro language in PHP, that prepares the code before compilation, bringing some confort and short syntax. Most of the time, one uses PHP itself to preprocess data. For example : <?php days_en = 'monday,tuesday,wednesday,thursday,friday,saturday,sunday'; days_zh = '星期－,星期二,星期三,星期四,星期五,星期六,星期日'; days = explode(',', lang === 'en' ? days_en : days_zh); ?>  could be written <?php if (lang === 'en') { days = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']; } else { days = ['星期－', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']; } ?>  and avoid preprocessing the string into an array first. Preprocessing could be done anytime the script includes all the needed values to process the expression.  Command Line Structures/Unpreprocessed clearPHP always-preprocess Analyzers Analyze ## Unreachable Code¶ Code may be unreachable, because other instructions prevent its reaching. For example, it be located after throw, return, ‘exit(), ‘die(), goto, ‘break or ‘continue : this way, it cannot be reached, as the previous instruction will divert the engine to another part of the code. <?php function foo() { a++; return a; b++; // b++ can't be reached; } function bar() { if (a) { return a; } else { return b; } b++; // b++ can't be reached; } foreach(a as b) { c += b; if (c > 10) { 'continue 1; } else { c--; 'continue; } d += e; // this can't be reached } a = 1; goto B; class foo {} // Definitions are accessible, but not functioncalls B: echo a; ?>  This is dead code, that may be removed.  Command Line Structures/UnreachableCode clearPHP no-dead-code Analyzers Analyze, Dead code ## Unresolved Catch¶ Catch clauses do not check for Exception existence. Catch clauses check that the emitted expression is of the requested Class, but if that class doesn’t exist in the code, the catch clause is always false. This is dead code. <?php try { // doSomething() } catch {TypoedExxeption e) { // Do not exist Exception // Fix this exception } catch {Stdclass e) { // Exists, but is not an exception // Fix this exception } catch {Exception e) { // Actual and effective catch // Fix this exception } ?>   Command Line Classes/UnresolvedCatch clearPHP no-unresolved-catch Analyzers Dead code ## Unresolved Classes¶ The following classes are instantiated in the code, but their definition couldn’t be found. Check for namespaces and aliases and make sure they are correctly configured. <?php class Foo extends Bar { private function foobar() { // here, parent is not resolved, as Bar is not defined in the code. return parent::prop; } } ?>   Command Line Classes/UnresolvedClasses Analyzers Analyze ## Unresolved Instanceof¶ ‘instanceof doesn’t check if compared class exists. It checks if an variable is of a specific class. However, if the referenced class doesn’t exist, because of a bug, a missed inclusion or a typo, the operator always fails, without a warning. <?php namespace X { class C {} // This is OK, as C is defined in X if (o 'instanceof C) { } // This is not OK, as C is not defined in global // 'instanceof respects namespaces and use expressions if (o 'instanceof \C) { } // This is not OK, as undefinedClass if (o 'instanceof undefinedClass) { } // This is not OK, as class is now a full namespace. It actually refers to \c, which doesn't exist class = 'C'; if (o 'instanceof class) { } } ?>  Make sure the following classes are well defined.  Command Line Classes/UnresolvedInstanceof clearPHP no-unresolved-instanceof Analyzers Analyze, Dead code ## Unresolved Use¶ The following use instructions cannot be resolved to a class or a namespace. They should be dropped or fixed.  Command Line Namespaces/UnresolvedUse clearPHP no-unresolved-use Analyzers Analyze ## Unserialize Second Arg¶ Since PHP 7, ‘unserialize() function has a second argument that limits the classes that may be unserialized. In case of a breach, this is limiting the classes accessible from ‘unserialize(). On way to exploit unserialize, is to make PHP unserialized the data to an available class, may be one that may be auto-loaded. <?php // expected Database object var = unserialize('O:7:dbClass:0:{}'); // unexpected load of debugClass object var = unserialize('O:10:debugClass:0:{}'); // Using the unserialized object var->connect(); ?>   Command Line Security/UnserializeSecondArg Analyzers Security ## Unset In Foreach¶ Unset applied to the variables of a foreach loop are useless, as they are copies and not the actual value. Even if the value is a reference, unsetting it will not have effect on the original array : the only effect may be on values inside an array, or on properties inside an object. <?php // When unset is useless array = [1, 2, 3]; foreach(array as a) { unset(a); } print_r(array); // still [1, 2, 3] foreach(array as b => &a) { unset(a); } print_r(array); // still [1, 2, 3] // When unset is useful array = [ [ 'c' => 1] ]; // Array in array foreach(array as &a) { unset(&a['c']); } print_r(array); // now [ ['c' => null] ] ?>   Command Line Structures/UnsetInForeach Analyzers Dead code, Analyze ## Unthrown Exception¶ These are exceptions that are defined in the code but never thrown.  Command Line Exceptions/Unthrown clearPHP no-unthrown-exceptions Analyzers Analyze, Dead code ## Unused Arguments¶ Those arguments are not used in the method or function. Unused arguments should be removed in functions : they are just dead code. Unused argument may have to stay in methods, as the signature is actually defined in the parent class. <?php // unused is in the signature, but not used. function foo(unused, b, c) { return b + c; } ?>   Command Line Functions/UnusedArguments Analyzers Analyze ## Unused Classes¶ The following classes are never explicitely used in the code. Note that this may be valid in case the current code is a library or framework, since it defines classes that are used by other (unprovided) codes. Also, this analyzer may find classes that are, in fact, dynamically loaded.  Command Line Classes/UnusedClass Analyzers Analyze, Dead code ## Unused Constants¶ Those constants are defined in the code but never used. Defining unused constants will slow down the application, has they are executed and stored in PHP hashtables. It is recommended to comment them out, and only define them when it is necessary.  Command Line Constants/UnusedConstants Analyzers Analyze, Dead code ## Unused Functions¶ The functions below are unused. They look like deadcode.  Command Line Functions/UnusedFunctions Analyzers Analyze, Dead code ## Unused Global¶ List of global keyword, used in various functions but not actually used in the code. for example : <?php function foo() { global bar; return 1; } ?>   Command Line Structures/UnusedGlobal Analyzers Analyze ## Unused Interfaces¶ Some interfaces are defined but not used. They should be removed, as they are probably dead code. <?php interface used {} interface unused {} // Used by implementation class c implements used {} // Used by extension interface j implements used {} x = new c; // Used in a 'instanceof var_dump(x 'instanceof used); // Used in a typehint function foo(Used x) {} ?>  See also Used Interfaces_.  Command Line Interfaces/UnusedInterfaces Analyzers Analyze, Dead code ## Unused Label¶ Some labels have been defined in the code, but they are not used. They may be removed as they are dead code. <?php a = 0; A: ++a; // A loop. A: is used if (a < 10) { goto A; } // B is never called explicitely. This is useless. B: ?>  There is no analysis for undefined goto call, as PHP checks that goto has a destination label at compile time : See also Goto.  Command Line Structures/UnusedLabel Analyzers Dead code, Analyze ## Unused Methods¶ The following methods are never called as methods. They are probably dead code.  Command Line Classes/UnusedMethods Analyzers Analyze, Dead code ## Unused Private Properties¶ List of all static properties that are not used. They look like dead code. <?php class foo { // This is a used property (see bar method) private used = 1; // This is an unused property private unused = 2; function bar(a) { this->used += a; return this->used; } } ?>   Command Line Classes/UnusedPrivateProperty Analyzers Analyze, Dead code ## Unused Protected Methods¶ The following methods are protected, and may be used in the current class or any of its children. <?php class foo { // This method is not used protected function unusedBar() {} protected function usedInFoo() {} protected function usedInFooFoo() {} public function bar2() { // some code this->usedInFoo(); } } class foofoo extends foo { protected function bar() {} public function bar2() { // some code this->usedInFooFoo(); } } class someOtherClass { protected function bar() { // This is not related to foo. this->unusedbar(); } } ?>  No usage of those methods were found. This analysis is impacted by dynamic method calls.  Command Line Classes/UnusedProtectedMethods Analyzers Dead code ## Unused Returned Value¶ The function called returns a value, which is ignored. Usually, this is a sign of dead code, or a missed check on the results of the functioncall. At times, it may be a valid call if the function has voluntarily no return value. It is recommended to add a check on the return value, or remove the call. <?php // simplest form function foo() { return 1; } foo(); // In case of multiple return, any one that returns something means that return value is meaningful function bar() { if (rand(0, 1)) { return 1; } else { return ; } } bar(); ?>  Note that this analysis ignores functions that return void (same meaning that PHP 7.1 : return ; or no return in the function body).  Command Line Functions/UnusedReturnedValue Analyzers Analyze, Dead code ## Unused Static Methods¶ List of all static methods that are not used. This looks like dead code.  Command Line Classes/UnusedPrivateMethod Analyzers Analyze, Dead code ## Unused Traits¶ Those traits are not used in a class or another trait. They may be dead code. <?php // unused trait trait unusedTrait { /'**/ } // used trait trait tUsedInTrait { /'**/ } trait tUsedInClass { use tUsedInTrait; /'**/ } class foo { use tUsedInClass; } ?>   Command Line Traits/UnusedTrait Analyzers Analyze ## Unused Use¶ Unused use statements. They may be removed, as they clutter the code and slows PHP by forcing it to search in this list for nothing. <?php use A as B; // Used in a new call. use Unused; // Never used. May be removed a = new B(); ?>   Command Line Namespaces/UnusedUse clearPHP no-useless-use Analyzers Analyze, Dead code ## Unusual Case For PHP Functions¶ Usually, PHP functions are written all in lower case.  Command Line Php/UpperCaseFunction Analyzers Coding Conventions ## Unverified Nonce¶ Those nonces are never checked. Nonces were created in the code with wp_nonce_field(), wp_nonce_url() and wp_nonce_create() functions, but they are not verified with wp_verify_nonce() nor check_ajax_referer() <?php nonce = wp_create_nonce( 'my-nonce' ); if ( ! wp_verify_nonce( nonce, 'my-other-nonce' ) ) { } else { } ?>   Command Line Wordpress/UnverifiedNonce Analyzers Wordpress ## Use wpdb Api¶ It is recommended to use the Wordpress Database API, instead of using query. This is especially true for UPDATE, REPLACE, INSERT and DELETE queries. <?php // Generic query wpdb->query('DELETE FROM ' . table . ' WHERE id=' . id . ' LIMIT 1'); // Wordpress query wpdb->delete( table, array( 'id' => id ), array('id' => '%d')); ?>   Command Line Wordpress/UseWpdbApi Analyzers Wordpress ## Use === null¶ It is faster to use === null instead of ‘is_null(). <?php // Operator === is fast if (a === null) { } // Function call is slow if (is_null(a)) { } ?>   Command Line Php/IsnullVsEqualNull clearPHP avoid-those-slow-functions Analyzers Analyze ## Use Class Operator¶ Use ::class to hardcode class names, instead of strings. This is actually faster than strings, which are parsed at executio time, while ::class is compiled, making it faster to execute. It is also capable to handle aliases, making the code easier to maintain. <?php namespace foo\bar; use foo\bar\X as B; class X {} className = '\foo\bar\X'; className = foo\bar\X::class; className = B\X; object = new className; ?>  This is not possible when building the name of the class with concatenation. This is a micro-optimization.  Command Line Classes/UseClassOperator Analyzers Analyze, Performances ## Use Const And Functions¶ Since PHP 5.6 it is possible to import specific functions or constants from other namespaces.  Command Line Namespaces/UseFunctionsConstants Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55 ## Use Constant As Arguments¶ Some methods and functions are defined to be used with constants as arguments. Those constants are made to be meaningful and readable, keeping the code maintenable. It is recommended to use such constants as soon as they are documented.  Command Line Functions/UseConstantAsArguments Analyzers Analyze ## Use Instanceof¶ The ‘instanceof operator is a faster alternative to ‘is_object(). ‘instanceof checks for an variable to be of a class or its parents or the interfaces it implements. Once ‘instanceof has been used, the actual attributes available (properties, constants, methods) are known, unlike with ‘is_object(). Last, ‘instanceof may be upgraded to Typehint, by moving it to the method signature. <?php class Foo { // Don't use is_object public function bar(o) { if (!is_object(o)) { return false; } // Classic argument check return o->method(); } // use 'instanceof public function bar(o) { if (o 'instanceof myClass) { // Now, we know which methods are available return o->method(); } return false; } // Default behavior } // use of typehinting // in case o is not of the right type, exception is raised automatically public function bar(myClass o) { return o->method(); } } ?>  ‘instanceof and ‘is_object() may not be always interchangeable. Consider using ‘isset on a known property for a simple check on object. You may also consider ‘is_string(), ‘is_integer() or ‘is_scalar(), in particular instead of !’is_object() <http://www.php.net/is_object>_. The ‘instanceof operator is also faster than the ‘is_object() functioncall.  Command Line Classes/UseInstanceof Analyzers Analyze, Analyze ## Use Lower Case For Parent, Static And Self¶ Until PHP 5.5, the special Parent, Static and Self keywords needed to be lowercase to be useable. Otherwise, they would yield a ‘PHP Fatal error: Class ‘PARENT’ not found’. parent, static and self are traditionally written in lowercase only. Mixed case and Upper case are both valid, though. <?php class foo { const aConstante = 233; function method() { // Wrong case, error with PHP 5.4.* and older echo SELF::aConstante; // Always right. echo self::aConstante; } } ?>  Until PHP 5.5, non-lowercase version of those keywords are generating a bug.  Command Line Php/CaseForPSS Analyzers Analyze, CompatibilityPHP54, CompatibilityPHP53 ## Use Nullable Type¶ The code uses nullable type, available since PHP 7.1. <?php function foo(?string a = abc) : ?string { return a.b; } ?>   Command Line Php/UseNullableType Analyzers CompatibilityPHP71, CompatibilityPHP72 ## Use Object Api¶ When PHP offers the alternative between procedural and OOP api for the same features, it is recommended to use the OOP API. Often, this least to more compact code, as methods are shorter, and there is no need to bring the resource around. Lots of new extensions are directly written in OOP form too. OOP / procedural alternatives are available for mysqli, tidy, cairo, ‘finfo <http://php.net/manual/en/book.fileinfo.php>_, and some others. <?php /// OOP version mysqli = new mysqli(localhost, my_user, my_password, world); /* check connection */ if (mysqli->connect_errno) { printf(Connect failed: %s\n, mysqli->connect_error); 'exit(); } /* Create table doesn't return a resultset */ if (mysqli->query(CREATE TEMPORARY TABLE myCity LIKE City) === TRUE) { printf(Table myCity successfully created.\n); } /* Select queries return a resultset */ if (result = mysqli->query(SELECT Name FROM City LIMIT 10)) { printf(Select returned %d rows.\n, result->num_rows); /* free result set */ result->close(); } ?>  <?php /// Procedural version link = mysqli_connect(localhost, my_user, my_password, world); /* check connection */ if (mysqli_connect_errno()) { printf(Connect failed: %s\n, mysqli_connect_error()); 'exit(); } /* Create table doesn't return a resultset */ if (mysqli_query(link, CREATE TEMPORARY TABLE myCity LIKE City) === TRUE) { printf(Table myCity successfully created.\n); } ?>   Command Line Php/UseObjectApi clearPHP use-object-api Analyzers Analyze ## Use Pathinfo¶ Use ‘pathinfo() function instead of string manipulations. ‘pathinfo() is more efficient and readable and string functions. <?php filename = '/path/to/file.php'; // With 'pathinfo(); details = pathinfo(filename); print details['extension']; // also capture php // With string functions (other solutions possible) ext = substr(filename, - strpos(strreverse(filename), '.')); // Capture php ?>  When the path contains UTF-8 characters, ‘pathinfo() may strip them. There, string functions are necessary.  Command Line Php/UsePathinfo Analyzers Analyze ## Use Positive Condition¶ Whenever possible, use a positive condition. Positive conditions are easier to understand, and lead to less understanding problems. Negative conditions are not reported when else is not present. <?php // This is a positive condition if (a == 'b') { doSomething(); } else { doSomethingElse(); } if (!empty(a)) { doSomething(); } else { doSomethingElse(); } // This is a negative condition if (a == 'b') { doSomethingElse(); } else { doSomething(); } // No need to force a == 'b' with empty else if (a != 'b') { doSomethingElse(); } ?>   Command Line Structures/UsePositiveCondition Analyzers Analyze ## Use Slim¶ This code uses the slim framework. Some classes, traits or interfaces where detected in the code.  Command Line Slim/UseSlim Analyzers Slim ## Use System Tmp¶ It is recommended to avoid hardcoding the tmp file. It is better to rely on the system’s tmp folder, which is accessible with ‘sys_get_temp_dir(). <?php // Where the tmp is : file_put_contents('sys_get_temp_dir().'/tempFile.txt', content); // Avoid hard-coding tmp folder : // On Linux-like systems file_put_contents('/tmp/tempFile.txt', content); // On Windows systems file_put_contents('C:\WINDOWS\TEMP\tempFile.txt', content); ?>   Command Line Structures/UseSystemTmp Analyzers Analyze ## Use With Fully Qualified Name¶ Use statement doesn’t require a fully qualified name. PHP manual recommends not to use fully qualified name (starting with ) when using the ‘use’ statement : they are “the leading backslash is unnecessary and not recommended, as import names must be fully qualified, and are not processed relative to the current namespace”. <?php // Recommended way to write a use statement. use A\B\C\D as E; // No need to use the initial \ use \A\B\C\D as F; ?>   Command Line Namespaces/UseWithFullyQualifiedNS Analyzers Analyze, Coding Conventions ## Use Wordpress Functions¶ Always use Wordpress functions instead of native PHP ones. Wordpress provides a lot of functions, that replace PHP natives one. It is recommended to used them. Here is a table of conversion :  PHP Wordpress ‘mail() ‘header() ‘header() ‘exit() ‘die() ‘rand() ‘mt_rand() wp_mail() wp_redirect() wp_safe_redirect() wp_die() wp_die() wp_rand() wp_rand() <?php // use Wordpress Mail wp_mail('to@exakat.io', 'Mail subject', 'Mail message'); // do not use PHP mail mail('to@exakat.io', 'Mail subject', 'Mail message'); ?>   Command Line Wordpress/UseWpFunctions Analyzers Wordpress ## Use const¶ The const keyword may be used to define constant, just like the ‘define() function. When defining a constant, it is recommended to use ‘const’ when the features of the constant are not dynamical (name or value are known at compile time). This way, constant will be defined at compile time, and not at execution time. <?php //Do const A = 1; // Don't define('A', 1); ?>  ‘define() function is useful when the constant is not known at compile time, or when case sensitivity is necessary. <?php // Read a in database or config file define('A', a); // Read a in database or config file define('B', 1, true); echo b; ?>   Command Line Constants/ConstRecommended Analyzers Analyze, Coding Conventions ## Use password_hash()¶ PHP 5.5 introduced ‘password_hash() and password_check() to replace the use of ‘crypt() to check password.  Command Line Php/Password55 Analyzers CompatibilityPHP55, CompatibilityPHP70, CompatibilityPHP56, CompatibilityPHP71 ## Use random_int()¶ ‘rand() and ‘mt_rand() should be replaced with random_int(). At worse, ‘rand() should be replaced with ‘mt_rand(), which is a drop-in replacement and ‘srand() by ‘mt_srand(). random_int() replaces ‘rand(), and has no seeding function like ‘srand(). <?php // Avoid using this random = rand(0, 10); // Drop-in replacement random = mt_rand(0, 10); // Even better but different : // valid with PHP 7.0+ try { random = random_int(0, 10); } catch (\Exception e) { // process case of not enoug random values } ?>  Since PHP 7, random_int() along with random_bytes(), provides cryptographically secure pseudo-random bytes, which are good to be used when security is involved. openssl_random_pseudo_bytes() may be used when the OpenSSL extension is available.  Command Line Php/BetterRand Analyzers Analyze, Security, CompatibilityPHP71, CompatibilityPHP72, CompatibilityPHP73 ## Used Once Property¶ Property used once in their defining class. Properties used in one method only may be used several times, and read only. This may be a class constant. Such properties are meant to be overwritten by an extending class, and that’s possible with class constants. Setting properties with default values is a good way to avoid literring the code with literal values, and provide a single point of update (by extension, or by hardcoding) for all those situations. A constant is definitely better suited for this task. <?php class foo { private defaultCols = '*'; cont DEFAULT_COLUMNS = '*'; // this->defaultCols holds a default value. Should be a constant. function bar(table, cols) { // This is necessary to activate usage of default values if (empty(cols)) { cols = this->defaultCols; } res = this->query('SELECT '.cols.' FROM '.table); // .... } // Upgraded version of bar, with default values function bar2(table, cols = self::DEFAULT_COLUMNS) { res = this->query('SELECT '.cols.' FROM '.table); // ..... } } ?>   Command Line Classes/UsedOnceProperty Analyzers Analyze ## Used Once Variables¶ This is the list of used once variables. <?php // The variables below never appear again in the code writtenOnce = 1; foo(readOnce); ?>  Such variables are useless. Variables must be used at least twice : once for writing, once for reading, at least. It is recommended to remove them. In special situations, variables may be used once : • PHP predefined variables, as they are already initialized. They are omitted in this analyze. • Interface function’s arguments, since the function has no body; They are omitted in this analyze. • Dynamically created variables ($$x, ${$this->y} or also using extract), as they are runtime values and can’t be determined at static code time. They are reported for manual review.
• Dynamically included files will provide in-scope extra variables.

The current analyzer count variables at the application level, and not at a method scope level.

 Command Line Variables/VariableUsedOnce Analyzers Analyze

## Used Once Variables (In Scope)¶

This is the list of used once variables, scope by scope. Those variables are used once in a function, a method, a class or a namespace. In any case, this means the variable is read or written, while it should be used at least twice.

<?php

function foo() {
// The variables below never appear twice, inside foo()
$writtenOnce = 1; foo($readOnce);
// They do appear again in other functions, or in global space.
}

function bar() {
$writtenOnce = 1; foo($readOnce);
}

?>

 Command Line Variables/VariableUsedOnceByContext Analyzers Analyze

## Used Protected Method¶

Marks methods being used in the current class or its children classes.

 Command Line Classes/UsedProtectedMethod Analyzers Dead code

## Used Routes¶

List of all routes used in the application.

<?php

$app->get('/admin/', function ($x) { /* do something(); */ });

// '/contact/'.$email is a dynamic route.$app->post('/contact/'.$email.'/{id}, function ($x) { /* do something(); */ });

?>


 Command Line Slim/UsedRoutes Analyzers Slim

## Useless Abstract Class¶

Those classes are marked ‘abstract’ and they are never extended. This way, they won’t be instantiated nor used.

Abstract classes that have only static methods are omitted here : one usage of such classes are Utilities classes, which only offer static methods.

<?php

// Never extended class : this is useless
abstract class foo {}

// Extended class
abstract class bar {
public function barbar() {}
}

class bar2 extends bar {}

// Utility class : omitted here
abstract class bar {
public static function barbar() {}
}

?>

 Command Line Classes/UselessAbstract Analyzers Analyze

## Useless Brackets¶

Those brackets have no use here.

They may be a left over of an old instruction, or a misunderstanding of the alternative syntax.

<?php

// The following brackets are useless : they are a leftover from an older instruction
// if (DEBUG)
{
$a = 1; } // Here, the extra brackets are useless for($a = 2; $a < 5;$a++) : {
$b++; } endfor; ?>   Command Line Structures/UselessBrackets Analyzers Analyze ## Useless Casting¶ There is no need to overcast returned values. <?php // trim always returns a string : cast is useless$a = (string) trim($b); // strpos doesn't always returns an integer : cast is useful$a = (boolean) strpos($b,$c);

// comparison don't need casting, nor parenthesis
$c = (bool) ($b > 2);

?>

 Command Line Structures/UselessCasting Analyzers Analyze

## Useless Check¶

Situation where the condition is useless.

<?php

// Checking for type is good.
if (is_array($array)) { foreach($array as $a) { doSomething($a);
}
}

// Foreach on empty arrays doesn't start. Checking is useless
if (!empty($array)) { foreach($array as $a) { doSomething($a);
}
}

?>

 Command Line Structures/UselessCheck Analyzers Analyze

## Useless Constructor¶

Class constructor that have empty bodies are useless. They may be removed.

 Command Line Classes/UselessConstructor Analyzers Analyze

## Useless Final¶

When a class is declared final, all of its methods are also final by default.

There is no need to declare them individually final.

<?php

final class foo {
// Useless final, as the whole class is final
final function method() { }
}

class bar {
// Useful final, as the whole class is not final
final function method() { }
}

?>


 Command Line Classes/UselessFinal clearPHP no-useless-final Analyzers Analyze

## Useless Global¶

Global are useless in two cases. First, on super-globals, which are always globals, like $_GET. Secondly, on variables that are not used. <?php //$_POST is already a global : it is in fact a global everywhere
global $_POST; //$unused is useless
function foo() {
global $used,$unused;

++$used; } ?>  Also, PHP has superglobals, a special team of variables that are always available, whatever the context. They are :$GLOBALS, $_SERVER,$_GET, $_POST,$_FILES, $_COOKIE,$_SESSION, $_REQUEST and$_ENV.

 Command Line Structures/UselessGlobal Analyzers Analyze

## Useless Instructions¶

Those instructions are useless, or contains useless parts.

For example, running ‘&lt;?php 1 + 1; ?&gt;’ does nothing : the addition is actually performed, but not used : not displayed, not stored, not set. Just plain lost.

Here the useless instructions that are spotted :

<?php

// This is a typo, that PHP turns into a constant, then a string.
conitnue;

// Empty string in a concatenation
$a = 'abc' . ''; // Returning expression, whose result is not used (additions, comparisons, properties, closures, new without =, ...) 1 + 2; // Returning post-incrementation function foo($a) {
return $a++; } // 'array_replace() with only one argument$replaced = array_replace($array); // 'array_replace() is OK with ...$replaced = array_replace(...$array); // @ operator on source array, in foreach, or when assigning literals$array = @array(1,2,3);

// Multiple comparisons in a for loop : only the last is actually used.
for($i = 0;$j = 0; $j < 10,$i < 20; ++$j, ++$i) {
print $i.' '.$j.PHP_EOL;
}

?>

 Command Line Structures/UselessInstruction clearPHP no-useless-instruction Analyzers Analyze

## Useless Interfaces¶

The interfaces below are defined and are implemented by some classes. However, they are never used to enforce objects’s class in the code, using ‘instanceof or a typehint. As they are currently used, those interfaces may be removed without change in behavior.

<?php
// only defined interface but never enforced
interface i {};
class c implements i {}
?>


Interfaces should be used in Typehint or with the ‘instanceof operator.

<?php
interface i {};

function foo(i $arg) { // Now,$arg is always an 'i'
}

function bar($arg) { if (!($arg 'instanceof i)) {
// Now, $arg is always an 'i' } } ?>   Command Line Interfaces/UselessInterfaces clearPHP no-useless-interfaces Analyzers Analyze ## Useless Parenthesis¶ Situations where parenthesis are not necessary, and may be removed. <?php if ( ($condition) ) {}
while( ($condition) ) {} do$a++; while ( ($condition) ); switch ( ($a) ) {}
$y = (1); ($y) == (1);

f(($x)); // = has precedence over == ($a = $b) ==$c;

($a++); // No need for parenthesis in default values function foo($c = ( 1 + 2) ) {}
?>

 Command Line Structures/UselessParenthesis Analyzers Analyze

## Useless Return¶

The spotted functions or methods have a return statement, but this statement is useless. This is the case for constructor and destructors, whose return value are ignored or inaccessible.

When return is void, and the last element in a function, it is also useless.

<?php

class foo {
function '__construct() {
// return is not used by PHP
return 2;
}
}

function bar(&$a) {$a++;
// The last return, when empty, is useless
return;
}

?>

 Command Line Functions/UselessReturn Analyzers Analyze

## Useless Switch¶

This switch has only one case. It may very well be replaced by a ifthen structure.

<?php
switch($a) { case 1: doSomething(); 'break; } // Same as if ($a == 1) {
doSomething();
}
?>

 Command Line Structures/UselessSwitch Analyzers Analyze

## Useless Unset¶

Unsetting variables may not be applicable with a certain type of variables. This is the list of such cases.

<?php

function foo($a) { // unsetting arguments is useless unset($a);

global $b; // unsetting global variable has no effect unset($b);

static $c; // unsetting static variable has no effect unset($c);

foreach($d as$e){
// unsetting a blind variable is useless
(unset) $e; } } ?>   Command Line Structures/UselessUnset clearPHP no-useless-unset Analyzers Analyze ## Uses Default Values¶ Default values are provided to methods so as to make it convenient to use. However, with new versions, those values may change. For example, in PHP 5.4, ‘htmlentities() switched from Latin1 to UTF-8 default encoding. <?php$string = Eu não sou o pão;

echo htmlentities($string); // PHP 5.3 : Eu n&Atilde;&pound;o sou o p&Atilde;&pound;o // PHP 5.4 : Eu n&atilde;o sou o p&atilde;o // Stable across versions echo htmlentities($string, 'UTF8');

?>


As much as possible, it is recommended to use explicit values in those methods, so as to prevent from being surprise at a future PHP evolution.

This analyzer tend to report a lot of false positives, including usage of ‘count(). Count() indeed has a second argument for recursive counts, and a default value. This may be ignored safely.

 Command Line Functions/UsesDefaultArguments Analyzers Analyze

## Using $this Outside A Class¶$this is a special variable, that should only be used in a class context.

Until PHP 7.1, $this may be used as an argument in a function (or a method), a global, a static : while this is legit, it sounds confusing enough to avoid it. <?php function foo($this) {
echo $this; } ?>  Starting with PHP 7.1, the PHP engine check thouroughly that$this is used in an appropriate manner, and raise fatal errors in case it isn’t.

 Command Line Classes/UsingThisOutsideAClass Analyzers Analyze, CompatibilityPHP71, CompatibilityPHP72

## Usort Sorting In PHP 7.0¶

Usort(), ‘uksort() and ‘uasort() behavior has changed in PHP 7. Values that are equals (based on the user-provided method) may be sorted differently than in PHP 5.

If this sorting is important, it is advised to add extra comparison in the user-function and avoid returning 0 (thus, depending on default implementation).

<?php

$a = [ 2, 4, 3, 6]; function noSort($a) { return $a > 5; } usort($a, 'noSort');
// Avoid var
//var $bar = 1; } ?>   Command Line Classes/OldStyleVar clearPHP no-php4-class-syntax Analyzers Analyze ## Variable Global¶ Variable global such are valid in PHP 5.6, but no in PHP 7.0. They should be replaced with${$foo->bar}. <?php // Forbidden in PHP 7 global$normalGlobal;

// Forbidden in PHP 7
global variable->global ;

// Tolerated in PHP 7
global ${$variable->global};

?>

 Command Line Structures/VariableGlobal Analyzers CompatibilityPHP53, CompatibilityPHP54, CompatibilityPHP55, CompatibilityPHP56

## While(List() = Each())¶

This code structure is quite old : it should be replace by the more modern and efficient foreach.

<?php
foreach($array as$key => $value) { doSomethingWith($key) and $value; } ?>   Command Line Structures/WhileListEach Analyzers Analyze, Performances ## Wpdb Best Usage¶ Use the adapted API with$wpdb.

Wordpress database API ($wpdb) offers several eponymous methods to safely handle insert, delete, replace and update. It is recommended to use them, instead of writing queries with concatenations. <?php // Example from Wordpress Manual$user_count = $wpdb->get_var( "SELECT COUNT(*) FROM$wpdb->users" );
echo <p>User count is {$user_count}</p>; ?>   Command Line Wordpress/WpdbBestUsage Analyzers Wordpress ## Wpdb Prepare Or Not¶ Always use$wpdb->prepare() when variables are used in the SQL query.

When using $wpdb, it is recommended to use directly the query() method when the SQL is not using variables. <?php // No need to prepare this query : it is all known at coding time.$wpdb->prepare('INSERT INTO table VALUES (1,2,3)');

// No need to prepare this query : $wpdb->prefix is safe$wpdb->prepare('INSERT INTO {$wpdb->prefix}table values (1,2,3)'); // Don't use query when variable are involved : always use prepare$wpdb->query('INSERT INTO TABLE values (1,2,'.$var.')'); ?>   Command Line Wordpress/WpdbPrepareOrNot Analyzers Wordpress ## Written Only Variables¶ Those variables are being written, but never read. This way, they are useless and should be removed, or read at some point.  Command Line Variables/WrittenOnlyVariable clearPHP no-unused-variable Analyzers Analyze ## Wrong Class Location¶ Classes may not be used or extended in any places inside the Zend Framework file hierarchy. For example, Zend_Controller_Action must be inside a /controllers/ folder for the routing system to find it. Here are the validation that are currently performed : * Zend_Auth shouldn’t be in templates files (.phtml) * Zend_Controller_Action must be in /controllers/ folder * Zend_View_Helper_Abstract must be in /helpers/ folder  Command Line ZendF/NotInThatPath Analyzers ZendFramework ## Wrong Number Of Arguments¶ Those functioncalls are made with too many or too few arguments. When the number arguments is wrong for native functions, PHP emits a warning. When the number arguments is too small for custom functions, PHP raises an exception. When the number arguments is too hight for custom functions, PHP ignores the arguments. Such arguments should be handled with the variadic operator, or with ‘func_get_args() family of functions. <?php echo strtoupper('This function is', 'ignoring arguments'); //Warning: 'strtoupper() expects exactly 1 parameter, 2 given in Command line code on line 1 echo 'strtoupper(); //Warning: 'strtoupper() expects exactly 1 parameter, 0 given in Command line code on line 1 function foo($argument) {}
echo foo();
//Fatal error: Uncaught ArgumentCountError: Too few arguments to function foo(), 0 passed in /Users/famille/Desktop/analyzeG3/test.php on line 10 and exactly 1 expected in /Users/famille/Desktop/analyzeG3/test.php:3

echo foo('This function is', 'ignoring arguments');

?>


It is recommended to check the signature of the methods, and fix the arguments.

 Command Line Functions/WrongNumberOfArguments clearPHP no-missing-argument.md Analyzers Analyze

## Wrong Optional Parameter¶

Wrong placement of optional parameters.

PHP parameters are optional when they defined with a default value, like this :

<?php
function x($arg = 1) { // PHP code here } ?>  When a function have both compulsory and optional parameters, the compulsory ones should appear first, and the optional should appear last : <?php function x($arg, $arg2 = 2) { // PHP code here } ?>  PHP will solve this problem at runtime, assign values in the same other, but will miss some of the default values and emits warnings. It is better to put all the optional parameters at the end of the method’s signature.  Command Line Functions/WrongOptionalParameter Analyzers Analyze ## Wrong Parameter Type¶ The expected parameter is not of the correct type. Check PHP documentation to know which is the right format to be used. <?php // substr() shouldn't work on integers. // the first argument is first converted to string, and it is 123456. echo substr(123456, 0, 4); // display 1234 // substr() shouldn't work on boolean // the first argument is first converted to string, and it is 1, and not t echo substr(true, 0, 1); // displays 1 // substr() works correctly on strings. echo substr(123456, 0, 4); ?>   Command Line Php/InternalParameterType Analyzers Analyze ## Wrong fopen() Mode¶ Wrong file opening for ‘fopen(). ‘fopen() has a few modes, as described in the documentation : ‘r’, ‘r+’, for reading; ‘w’, ‘w+’ for writing; ‘a’, ‘a+’ for appending; ‘x’, ‘x+’ for modifying; ‘c’, ‘c+’ for writing and locking, ‘t’ for text files and windows only. An optional ‘b’ may be used to make the ‘fopen() call more portable and binary safe. <?php // open the file for reading, in binary mode$fp = fopen('/tmp/php.txt', 'rb');

// New option e in PHP 7.0.16 and 7.1.2 (beware of compatibility)
$fp = fopen('/tmp/php.txt', 'rbe'); // Unknown option x$fp = fopen('/tmp/php.txt', 'rbx');

?>


Any other values are not understood by PHP.

 Command Line Php/FopenMode Analyzers Analyze

## Yoda Comparison¶

Yoda comparison is a way to write conditions which places literal values on the left side.

<?php
if (1 == $a) { // Then condition } ?>  The objective is to avoid mistaking a comparison to an assignation. If the comparison operateur is mistaken, but the literal is on the left, then an error will be triggered, instead of a silent bug. <?php // error in comparison! if ($a = 1) {
// Then condition
}
?>
`