Analyzers Documentation

Adding Zero

[Since 0.8.4] - [ -P Structures/AddZero ] - [ Online docs ]

Adding 0 is useless, as 0 is the neutral element for addition. Besides, when one of the argument is an integer, PHP triggers a cast to integer.

It is recommended to make the cast explicit with (int) .

<?php 
// Explicit cast
$a = (int) foo();

// Useless addition
$a foo() + 0;
$a foo();

// Also works with minus
$b $c// drop the 0, but keep the minus
$b $c 0// drop the 0 and the minus

$a += 0;
$a -= 0;
?>


Adding zero is also reported when the zero is a defined constants.

If it is used to type cast a value to integer, then casting with (int) is clearer.

Ambiguous Array Index

[Since 0.8.4] - [ -P Arrays/AmbiguousKeys ] - [ Online docs ]

Indexes should not be defined with different types than int or string.

Array indices only accept integers and strings, so any other type of literal is reported. In fact, null is turned into an empty string, booleans are turned into an integer, and real numbers are truncated (not rounded).

<?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.

See also array.

Array Index

[Since 0.8.4] - [ -P Arrays/Arrayindex ] - [ Online docs ]

List of all indexes used in arrays.

<?php 
// Index
$x['index'] = 1;

// in array creation
$a = array('index2' => 1);
$a2 = ['index3' => 2];
?>

Multidimensional Arrays

[Since 0.8.4] - [ -P Arrays/Multidimensional ] - [ Online docs ]

Simply, arrays of arrays.

<?php 
$x[1][2] = $x[2][3][4];
?>


See also Type array and
Using Multidimensional Arrays in PHP.

Multiple Index Definition

[Since 0.8.4] - [ -P Arrays/MultipleIdenticalKeys ] - [ Online docs ]

Indexes that are defined multiple times in the same array.

<?php 
// Multiple identical keys
    
$x = array(=> 2
               
=> 3,  
               
=> 3);

    
// Multiple identical keys (sneaky version)
    
$x = array(=> 2
               
1.1 => 3,  
               
true => 4);

    
// Multiple identical keys (automated version)
    
$x = array(=> 2
               
3,        // This will be index 2
               
=> 4);  // this index is overwritten
?>


They are indeed overwriting each other. This is most probably a typo.

PHP Arrays Index

[Since 0.8.4] - [ -P Arrays/Phparrayindex ] - [ Online docs ]

List of indexes used when manipulating PHP arrays in the code.

<?php 
// HTTP_HOST is a PHP array index. 
$ip 'http'.$_SERVER['HTTP_HOST'].'/'.$row['path'];

//'path' is not a PHP index
?>


Classes Names

[Since 0.8.4] - [ -P Classes/Classnames ] - [ Online docs ]

List of all classes, as defined in the application.

<?php 
// foo is in the list
class foo {}

// Anonymous classes are not in the list
$o = class { function foo(){} }
?>

Constant Definition

[Since 0.8.4] - [ -P Classes/ConstantDefinition ] - [ Online docs ]

List of class constants being defined.

<?php 
// traditional way of making constants
define('aConstant'1);

// modern way of making constants
const anotherConstant 2;

class 
foo {
    
// Not a constant, a class constant.
    
const aClassConstant 3;
}
?>


See also PHP Constants.

Empty Classes

[Since 0.8.4] - [ -P Classes/EmptyClass ] - [ Online docs ]

Classes that do no define anything at all. This is probably dead code.

Classes that are directly derived from an exception are omitted.

<?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 {}
?>

Magic Methods

[Since 0.8.4] - [ -P Classes/MagicMethod ] - [ Online docs ]

List of PHP magic methods being used. The magic methods are

__call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() and __debugInfo().

__construct and __destruct are omitted here, as they are routinely used to create and destroy objects.

<?php 
class foo{
    
// PHP Magic method, called when cloning an object.
    
function __clone() {}
}
?>


See also Magic Method.

Forgotten Visibility

[Since 0.8.4] - [ -P Classes/NonPpp ] - [ Online docs ]

Some classes elements (property, method, constant) 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.

Class constants support also visibility since PHP 7.1.

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 {
    protected 
sconst NO_VISIBILITY_CONST 1// For PHP 7.2 and later

    
private $noVisibilityProperty 2
    
    public function 
Method() {}
}

// Missing visibility
class {
    const 
NO_VISIBILITY_CONST 1// For PHP 7.2 and later

    
var $noVisibilityProperty 2// Only with var
    
    
function NoVisibilityForMethod() {}
}
?>


See also Visibility and Understanding The Concept Of Visibility In Object Oriented PHP.

Non Static Methods Called In A Static

[Since 0.8.4] - [ -P Classes/NonStaticMethodsCalledStatic ] - [ Online docs ]

Static methods have to be declared as such (using the static keyword). Then, one may call them without instantiating the object.

PHP 7.0, and more recent versions, yield a deprecated error : Non-static method A::B() should not be called statically .

PHP 5 and older doesn't check that a method is static or not : at any point, the code may call one method statically.

<?php 
class {
        static public function 
sm( ) { echo __METHOD__.\n; }
        public public 
sm( ) { echo __METHOD__.\n; }
    } 
    
    
x::sm( ); // echo x::sm 
    
    // Dynamic call
    
['x''sm']();
    [\
x::class, 'sm']();

    
$s 'x::sm';
    
$s();
?>


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 {
        public function 
foo( ) { self::bar() }
        public function 
bar( ) { echo __METHOD__.\n; }
    }
?>


See also Static Keyword.

Old Style Constructor

[Since 0.8.4] - [ -P Classes/OldStyleConstructor ] - [ Online docs ]

PHP classes used to have the method bearing the same name as the class acts as the constructor. That was PHP 4, and early PHP 5.

The manual issues a warning about this syntax : Old style constructors are DEPRECATED in PHP 7.0, and will be removed in a future version. You should always use __construct() in new code.

<?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.

See also Constructors and Destructors.

Static Methods

[Since 0.8.4] - [ -P Classes/StaticMethods ] - [ Online docs ]

List of all static methods.

<?php 
class foo {
    static public function 
staticMethod() {
        
    }
    
    public function 
notStaticMethod() {
    
    }
           
    private function 
method() {
        
// This is not a property
        
new static();
    }
}
?>


Static Methods Called From Object

[Since 0.8.4] - [ -P Classes/StaticMethodsCalledFromObject ] - [ Online docs ]

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 {
        static function 
y( ) {}
    }
    
    
$z = new x( );
    
    
$z->y( ); // Readability : no one knows it is a static call
    
x::y( );  // Readability : here we know
?>


Static Properties

[Since 0.8.4] - [ -P Classes/StaticProperties ] - [ Online docs ]

List of all static properties.

<?php 
class foo {
    static public 
$staticProperty 1;
           public 
$notStaticProperty 2;
           
    private function 
method() {
        
// This is not a property
        
new static();
    }
}

function 
bar() {
    
// This is not a static property
    
static $staticVariable;
    
    
//....
}
?>


Constants With Strange Names

[Since 0.8.4] - [ -P Constants/ConstantStrangeNames ] - [ Online docs ]

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
?>


See also PHP Constants.

Constants Usage

[Since 0.8.4] - [ -P Constants/ConstantUsage ] - [ Online docs ]

List of constants being used.

<?php 
const MY_CONST 'Hello';

// PHP_EOL (native PHP Constant)
// MY_CONST (custom constant)
echo PHP_EOL MY_CONST;
?>

Constants

[Since 0.8.4] - [ -P Constants/Constantnames ] - [ Online docs ]

List of PHP constants being defined.

<?php 
// with const
const 1;

// with `define() <https://www.php.net/define>`_
define ('Y'2);
?>


True False Inconsistant Case

[Since 0.8.4] - [ -P Constants/InconsistantCase ] - [ Online docs ]

TRUE or true or True is the favorite.

Usually, PHP projects choose between ALL CAPS True/False, or all lowercase True/False. Sometimes, the project will have no recommendations.

When your project use a vast majority of one of the convention, then the analyzer will report all remaining inconsistently cased constant.

<?php 
$a1 true;
$a2 true;
$a3 true;
$a4 true;
$a5 true;
$a6 true;
$a7 true;
$a8 true;
$a9 true;
$a10 true;

// This convention is inconsistence with the rest
$b1 TRUE;
?>


Magic Constant Usage

[Since 0.8.4] - [ -P Constants/MagicConstantUsage ] - [ Online docs ]

There are eight magical constants that change depending on where they are used. For example, the value of __LINE__ depends on the line that it's used on in your script. These special constants are case-insensitive.

+ __LINE__
+ __FILE__
+ __DIR__
+ __FUNCTION__
+ __CLASS__
+ __TRAIT__
+ __METHOD__
+ __NAMESPACE__


<?php 
echo 'This code is in file '__FILE__.', line '.__LINE__;
?>


See also Magic Constants.

PHP Constant Usage

[Since 0.8.4] - [ -P Constants/PhpConstantUsage ] - [ Online docs ]

List of PHP constants being used.

<?php 
const MY_CONST 'Hello';

// PHP_EOL (native PHP Constant)
// MY_CONST (custom constant, not reported)
echo PHP_EOL MY_CONST;
?>


See also Predefined Constants.

Defined Exceptions

[Since 0.8.4] - [ -P Exceptions/DefinedExceptions ] - [ Online docs ]

This is the list of defined exceptions.

<?php 
class myException extends \Exception {}

// A defined exception
throw new myException();

// not a defined exception : it is already defined. 
throw new \RuntimeException();
?>


See also Exceptions.

Thrown Exceptions

[Since 0.8.4] - [ -P Exceptions/ThrownExceptions ] - [ Online docs ]

Usage of throw keyword.

<?php 
throw new MyException('Error happened');
?>


See also Exceptions.

ext/apc

[Since 0.8.4] - [ -P Extensions/Extapc ] - [ Online docs ] - [ PHP older than 7.0]

Extension Alternative PHP Cache.

The Alternative PHP Cache (APC) is a free and open opcode cache for PHP. Its goal is to provide a free, open, and robust framework for caching and optimizing PHP intermediate code.

This extension is considered unmaintained and dead.

<?php 
$bar 'BAR';
   
apc_add('foo'$bar);
   
var_dump(apc_fetch('foo'));
   echo 
PHP_EOL;

   
$bar 'NEVER GETS SET';
   
apc_add('foo'$bar);
   
var_dump(apc_fetch('foo'));
   echo 
PHP_EOL;
?>


See also Alternative PHP Cache.

ext/bcmath

[Since 0.8.4] - [ -P Extensions/Extbcmath ] - [ Online docs ]

Extension BC Math.

For arbitrary precision mathematics PHP offers the Binary Calculator which supports numbers of any size and precision up to 2147483647-1 (or 0x7FFFFFFF-1 ) decimals, represented as strings.

<?php 
echo bcpow('2''123'); 
//10633823966279326983230456482242756608

echo 2**123;
//1.0633823966279E+37
?>


See also BC Math Functions.

ext/bzip2

[Since 0.8.4] - [ -P Extensions/Extbzip2 ] - [ Online docs ]

Extension ext/bzip2.

Bzip2 Functions for PHP.

<?php 
$file '/tmp/foo.bz2';
$bz bzopen($file'r') or die('Couldn\'t open $file for reading');

bzclose($bz);
?>


See also Bzip2 Functions.

ext/calendar

[Since 0.8.4] - [ -P Extensions/Extcalendar ] - [ Online docs ]

Extension ext/calendar.

The calendar extension presents a series of functions to simplify converting between different calendar formats.

<?php 
$number cal_days_in_month(CAL_GREGORIAN82003); // 31
echo "There were {$number} days in August 2003";
?>


See also Calendar Functions.

ext/crypto

[Since 0.8.4] - [ -P Extensions/Extcrypto ] - [ Online docs ]

Extension ext/crypto (PECL).

Objective PHP binding of OpenSSL Crypto library.

<?php 
use Crypto\Cipher;
use 
Crypto\AlgorihtmException;
$algorithm 'aes-256-cbc';
if (!
Cipher::hasAlgorithm($algorithm)) {
    die(
'Algorithm $algorithm not found' PHP_EOL);
}
try {
    
$cipher = new Cipher($algorithm);
    
// Algorithm method for retrieving algorithm
    
echo 'Algorithm: ' $cipher->getAlgorithmName() . PHP_EOL;
    
// Params
    
$key_len $cipher->getKeyLength();
    
$iv_len $cipher->getIVLength();
    
    echo 
'Key length: ' $key_len PHP_EOL;
    echo 
'IV length: '  $iv_len PHP_EOL;
    echo 
'Block size: ' $cipher->getBlockSize() . PHP_EOL;
    
// This is just for this example. You should never use such key and IV!
    
$key str_repeat('x'$key_len);
    
$iv str_repeat('i'$iv_len);
    
// Test data
    
$data1 'Test';
    
$data2 'Data';
    
$data $data1 $data2;
    
// Simple encryption
    
$sim_ct $cipher->encrypt($data$key$iv);
    
    
// init/update/finish encryption
    
$cipher->encryptInit($key$iv);
    
$iuf_ct  $cipher->encryptUpdate($data1);
    
$iuf_ct .= $cipher->encryptUpdate($data2);
    
$iuf_ct .= $cipher->encryptFinish();
    
// Raw data output (used base64 format for printing)
    
echo 'Ciphertext (sim): ' base64_encode($sim_ct) . PHP_EOL;
    echo 
'Ciphertext (iuf): ' base64_encode($iuf_ct) . PHP_EOL;
    
// $iuf_out == $sim_out
    
$ct $sim_ct;
    
// Another way how to create a new cipher object (using the same algorithm and mode)
    
$cipher Cipher::aes(Cipher::MODE_CBC256);
    
// Simple decryption
    
$sim_text $cipher-><?>


See also pecl crypto and php-crypto.

ext/ctype

[Since 0.8.4] - [ -P Extensions/Extctype ] - [ Online docs ]

Extension ext/ctype.

Ext/ctype checks whether a character or string falls into a certain character class according to the current locale.

<?php 
$strings = array('AbCd1zyZ9''foo!#$bar');
foreach (
$strings as $testcase) {
    if (
ctype_alnum($testcase)) {
        echo 
"The string $testcase consists of all letters or digits.\n";
    } else {
        echo 
"The string $testcase does not consist of all letters or digits.\n";
    }
}
?>


See also Ctype funtions.

ext/curl

[Since 0.8.4] - [ -P Extensions/Extcurl ] - [ Online docs ]

Extension curl.

PHP supports libcurl, a library created by Daniel Stenberg. It allows the connection and communication to many different types of servers with many different types of protocols.

<?php 
$ch curl_init("http://www.example.com/");
$fp fopen("example_homepage.txt""w");

curl_setopt($chCURLOPT_FILE$fp);
curl_setopt($chCURLOPT_HEADER0);

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


See also Curl for PHP and
curl.

ext/date

[Since 0.8.4] - [ -P Extensions/Extdate ] - [ Online docs ]

Extension ext/date.

These functions allows the manipulation of date and time from the server where the PHP scripts are running.

<?php 
$dt = new DateTime('2015-11-01 00:00:00', new DateTimeZone('America/New_York'));
echo 
'Start: '$dt->format('Y-m-d H:i:s P'), PHP_EOL;
$dt->add(new DateInterval('PT3H'));
echo 
'End:   '$dt->format('Y-m-d H:i:s P'), PHP_EOL;
?>


See also Date and Time.

ext/dba

[Since 0.8.4] - [ -P Extensions/Extdba ] - [ Online docs ]

Extension ext/dba.

These functions build the foundation for accessing Berkeley DB style databases.

<?php 
$id dba_open('/tmp/test.db''n''db2');

if (!
$id) {
    echo 
'dba_open failed'.PHP_EOL;
    exit;
}

dba_replace('key''This is an example!'$id);

if (
dba_exists('key'$id)) {
    echo 
dba_fetch('key'$id);
    
dba_delete('key'$id);
}

dba_close($id);
?>


See also Database (dbm-style) Abstraction Layer.

ext/dom

[Since 0.8.4] - [ -P Extensions/Extdom ] - [ Online docs ]

Extension Document Object Model.

The DOM extension allows the manipulation of XML documents through the DOM API with PHP.

<?php 
$dom = new DOMDocument('1.0''utf-8');

$element $dom->createElement('test''This is the root element!');

// We insert the new element as root (child of the document)
$dom->appendChild($element);

echo 
$dom->saveXML();
?>


See also Document Object Model.

ext/enchant

[Since 0.8.4] - [ -P Extensions/Extenchant ] - [ Online docs ]

Extension Enchant.

Enchant is the PHP binding for the Enchant spelling library. Enchant steps in to provide uniformity and conformity on top of all spelling libraries, and implement certain features that may be lacking in any individual provider library.

<?php 
$tag 'en_US';
$r enchant_broker_init();
$bprovides enchant_broker_describe($r);
echo 
'Current broker provides the following backend(s):'.PHP_EOL;
print_r($bprovides);

$dicts enchant_broker_list_dicts($r);
print_r($dicts);
if (
enchant_broker_dict_exists($r,$tag)) {
    
$d enchant_broker_request_dict($r$tag);
    
$dprovides enchant_dict_describe($d);
    echo 
'dictionary $tag provides:'.PHP_EOL;
    
$wordcorrect enchant_dict_check($d'soong');
    
print_r($dprovides);
    if (!
$wordcorrect) {
        
$suggs enchant_dict_suggest($d'soong');
        echo 
'Suggestions for "soong":';
        
print_r($suggs);
    }
    
enchant_broker_free_dict($d);
} else {
}
enchant_broker_free($r);
?>


See also Enchant spelling library and
Enchant.

ext/ereg

[Since 0.8.4] - [ -P Extensions/Extereg ] - [ Online docs ] - [ PHP older than 7.0]

Extension ext/ereg.

<?php 
if (ereg ('([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})'$date$regs)) {
    echo 
$regs[3].'.'.$regs[2].'.'.$regs[1];
} else {
    echo 
'Invalid date format: '.$date;
}
?>


See also Ereg.

ext/exif

[Since 0.8.4] - [ -P Extensions/Extexif ] - [ Online docs ]

Extension EXIF : Exchangeable image file format.

The EXIF extension manipulates image meta data.

<?php 
echo 'test1.jpg:<br />';
$exif exif_read_data('tests/test1.jpg''IFD0');
echo 
$exif===false 'No header data found.<br />' 'Image contains headers<br />';

$exif exif_read_data('tests/test2.jpg'0true);
echo 
'test2.jpg:<br />';
foreach (
$exif as $key => $section) {
    foreach (
$section as $name => $val) {
        echo 
$key.$name.': '.$val.'<br />';
    }
}
?>


See also Exchangeable image information.

ext/fdf

[Since 0.8.4] - [ -P Extensions/Extfdf ] - [ Online docs ]

Extension ext/fdf.

Forms Data Format (FDF) is a format for handling forms within PDF documents.

<?php 
$outfdf fdf_create();
fdf_set_value($outfdf'volume'$volume0);

fdf_set_file($outfdf'http:/testfdf/resultlabel.pdf');
fdf_save($outfdf'outtest.fdf');
fdf_close($outfdf);
Header('Content-type: application/vnd.fdf');
$fp fopen('outtest.fdf''r');
fpassthru($fp);
unlink('outtest.fdf');
?>


See also Form Data Format.

ext/fileinfo

[Since 0.8.4] - [ -P Extensions/Extfileinfo ] - [ Online docs ]

Extension ext/fileinfo.

This module guesses the content type and encoding of a file by looking for certain magic byte sequences at specific positions within the file.

<?php 
$finfo finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
foreach (glob('*') as $filename) {
    echo 
finfo_file($finfo$filename) . PHP_EOL;
}
finfo_close($finfo);
?>



See also Filinfo.

ext/filter

[Since 0.8.4] - [ -P Extensions/Extfilter ] - [ Online docs ]

Extension filter.

This extension filters data by either validating or sanitizing it.

<?php 
$email_a 'joe@example.com';
$email_b 'bogus';

if (
filter_var($email_aFILTER_VALIDATE_EMAIL)) {
    echo 
'This ($email_a) email address is considered valid.'.PHP_EOL;
}
if (
filter_var($email_bFILTER_VALIDATE_EMAIL)) {
    echo 
'This ($email_b) email address is considered valid.'.PHP_EOL;
} else {
    echo 
'This ($email_b) email address is considered invalid.'.PHP_EOL;
}
?>


See also Data filtering.

ext/ftp

[Since 0.8.4] - [ -P Extensions/Extftp ] - [ Online docs ]

Extension FTP.

The functions in this extension implement client access to files servers speaking the File Transfer Protocol (FTP) as defined in RFC 959.

<?php 
// set up basic connection
$conn_id ftp_connect($ftp_server); 

// login with username and password
$login_result ftp_login($conn_id$ftp_user_name$ftp_user_pass); 

// check connection
if ((!$conn_id) || (!$login_result)) { 
    echo 
'FTP connection has failed!';
    echo 
'Attempted to connect to $ftp_server for user $ftp_user_name'
    exit; 
} else {
    echo 
'Connected to $ftp_server, for user $ftp_user_name';
}

// upload the file
$upload ftp_put($conn_id$destination_file$source_fileFTP_BINARY); 

// check upload status
if (!$upload) { 
    echo 
'FTP upload has failed!';
} else {
    echo 
'Uploaded $source_file to $ftp_server as $destination_file';
}

// close the FTP stream 
ftp_close($conn_id);
?>


See also FTP.

ext/gd

[Since 0.8.4] - [ -P Extensions/Extgd ] - [ Online docs ]

Extension GD for PHP.

This extension allows PHP to create and manipulate image files in a variety of different image formats, including GIF, PNG, JPEG, WBMP, and XPM.

<?php 
header("Content-type: image/png");
$string $_GET['text'];
$im     imagecreatefrompng("images/button1.png");
$orange imagecolorallocate($im22021060);
$px     = (imagesx($im) - 7.5 strlen($string)) / 2;
imagestring($im3$px9$string$orange);
imagepng($im);
imagedestroy($im);
?>


See also Image Processing and GD.

ext/gmp

[Since 0.8.4] - [ -P Extensions/Extgmp ] - [ Online docs ]

Extension ext/gmp.

These functions allow for arbitrary-length integers to be worked with using the GNU MP library.

<?php 
$pow1 gmp_pow('2'131);
echo 
gmp_strval($pow1) . PHP_EOL;
$pow2 gmp_pow('0'0);
echo 
gmp_strval($pow2) . PHP_EOL;
$pow3 gmp_pow('2', -1); // Negative exp, generates warning
echo gmp_strval($pow3) . PHP_EOL;
?>


See also GMP and GNU MP library.

ext/gnupgp

[Since 0.8.4] - [ -P Extensions/Extgnupg ] - [ Online docs ]

Extension GnuPG.

This module allows you to interact with gnupg.

<?php 
// init gnupg
$res gnupg_init();
// not really needed. Clearsign is default
gnupg_setsignmode($res,GNUPG_SIG_MODE_CLEAR);
// add key with passphrase 'test' for signing
gnupg_addsignkey($res,"8660281B6051D071D94B5B230549F9DC851566DC","test");
// sign
$signed gnupg_sign($res,"just a test");
echo 
$signed;
?>


See also Gnupg Function for PHP and
GnuPG.

ext/hash

[Since 0.8.4] - [ -P Extensions/Exthash ] - [ Online docs ]

Extension for HASH Message Digest Framework.

Message Digest (hash) engine. Allows direct or incremental processing of arbitrary length messages using a variety of hashing algorithms.

<?php 
/* Create a file to calculate hash of */
file_put_contents('example.txt''The quick brown fox jumped over the lazy dog.');

echo 
hash_file('md5''example.txt');
?>


See also HASH Message Digest Framework.

ext/iconv

[Since 0.8.4] - [ -P Extensions/Exticonv ] - [ Online docs ]

Extension ext/iconv.

With this module, you can turn a string represented by a local character set into the one represented by another character set, which may be the Unicode character set.

<?php 
$text "This is the Euro symbol '€'.";

echo 
'Original : '$textPHP_EOL;
echo 
'TRANSLIT : 'iconv("UTF-8""ISO-8859-1//TRANSLIT"$text), PHP_EOL;
echo 
'IGNORE   : 'iconv("UTF-8""ISO-8859-1//IGNORE"$text), PHP_EOL;
echo 
'Plain    : 'iconv("UTF-8""ISO-8859-1"$text), PHP_EOL;
?>


See also Iconv, and
libiconv.

ext/json

[Since 0.8.4] - [ -P Extensions/Extjson ] - [ Online docs ]

Extension JSON.

This extension implements the JavaScript Object Notation (JSON) data-interchange format. PHP implements a superset of JSON as specified in the original RFC 7159.

<?php 
$arr = array('a' => 1'b' => 2'c' => 3'd' => 4'e' => 5);

echo 
json_encode($arr);
?>


See also JavaScript Object Notation and JSON.

ext/kdm5

[Since 0.8.4] - [ -P Extensions/Extkdm5 ] - [ Online docs ]

Extension kdm5 : Kerberos V .

These package allows you to access Kerberos V administration servers. You can create, modify, and delete Kerberos V principals and policies.

<?php 
// Extracted from the PHP Manual
  
$handle kadm5_init_with_password(afs-1GONICUS.LOCALadmin/adminpassword);

  print <
h1>get_principals</h1>\n;
  
$principals kadm5_get_principals($handle);
  for( 
$i=0$i<count($principals); $i++)
      print 
$principals[$i]<br>\n;

  print <
h1>get_policies</h1>\n;
  
$policies kadm5_get_policies($handle);
  for( 
$i=0$i<count($policies); $i++)
      print 
$policies[$i]<br>\n;

  print <
h1>get_principal burbach@GONICUS.LOCAL</h1>\n;

  
$options kadm5_get_principal($handleburbach@GONICUS.LOCAL );
  
$keys array_keys($options);
  for( 
$i=0$i<count($keys); $i++) {
    
$value $options[$keys[$i]];
    print 
$keys[$i]: $value<br>\n;
  }

  
$options = array(KADM5_PRINC_EXPIRE_TIME => 0);
  
kadm5_modify_principal($handleburbach@GONICUS.LOCAL$options);

  
kadm5_destroy($handle);
?>


See also Kerberos V and Kerberos: The Network Authentication Protocol.

ext/ldap

[Since 0.8.4] - [ -P Extensions/Extldap ] - [ Online docs ]

Extension ext/ldap.

LDAP is the Lightweight Directory Access Protocol, and is a protocol used to access 'Directory Servers'. The Directory is a special kind of database that holds information in a tree structure.

<?php 
// basic sequence with LDAP is connect, bind, search, interpret search
// result, close connection

echo '<h3>LDAP query test</h3>';
echo 
'Connecting ...';
$ds=ldap_connect('localhost');  // must be a valid LDAP server!
echo 'connect result is ' $ds '<br />';

if (
$ds) { 
    echo 
'Binding ...'
    
$r=ldap_bind($ds);     // this is an 'anonymous' bind, typically
                           // read-only access
    
echo 'Bind result is ' $r '<br />';

    echo 
'Searching for (sn=S*) ...';
    
// Search surname entry
    
$sr=ldap_search($ds'o=My Company, c=US''sn=S*');  
    echo 
'Search result is ' $sr '<br />';

    echo 
'Number of entries returned is ' ldap_count_entries($ds$sr) . '<br />';

    echo 
'Getting entries ...<p>';
    
$info ldap_get_entries($ds$sr);
    echo 
'Data for ' $info['count'] . ' items returned:<p>';

    for (
$i=0$i<$info['count']; $i++) {
        echo 
'dn is: ' $info[$i]['dn'] . '<br />';
        echo 
'first cn entry is: ' $info[$i]['cn'][0] . '<br />';
        echo 
'first email entry is: ' $info[$i]['mail'][0] . '<br /><hr />';
    }

    echo 
'Closing connection';
    
ldap_close($ds);

} else {
    echo 
'<h4>Unable to connect to LDAP server</h4>';
}
?>


See also Lightweight Directory Access Protocol.

ext/libxml

[Since 0.8.4] - [ -P Extensions/Extlibxml ] - [ Online docs ]

Extension libxml.

These functions/constants are available as of PHP 5.1.0, and the following core extensions rely on this libxml extension: DOM, libxml, SimpleXML, SOAP, WDDX, XSL, XML, XMLReader, XMLRPC and XMLWriter.

<?php 
// $xmlstr is a string, containing a XML document. 

$doc simplexml_load_string($xmlstr);
$xml explode(PHP_EOL$xmlstr);

if (
$doc === false) {
    
$errors libxml_get_errors();

    foreach (
$errors as $error) {
        echo 
display_xml_error($error$xml);
    }

    
libxml_clear_errors();
}


function 
display_xml_error($error$xml)
{
    
$return  $xml[$error->line 1] . PHP_EOL;
    
$return .= str_repeat('-'$error->column) . '^'.PHP_EOL;

    switch (
$error->level) {
        case 
LIBXML_ERR_WARNING:
            
$return .= 'Warning ',$error->code.': ';
            break;
         case 
LIBXML_ERR_ERROR:
            
$return .= 'Error '.$error->code.': ';
            break;
        case 
LIBXML_ERR_FATAL:
            
$return .= 'Fatal Error '.$error->code.': ';
            break;
    }

    
$return .= trim($error->message) .
               
PHP_EOL.'  Line: '.$error->line .
               
PHP_EOL.'  Column: '.$error->column;

    if (
$error->file) {
        
$return .= "\n  File: $error->file";
    }

    return 
$return.PHP_EOL.PHP_EOL.'--------------------------------------------'.PHP_EOL.PHP_EOL;
}
?>


See also libxml.

ext/mbstring

[Since 0.8.4] - [ -P Extensions/Extmbstring ] - [ Online docs ]

Extension ext/mbstring .

mbstring provides multibyte specific string functions that help you deal with multibyte encodings in PHP.

<?php 
/* Convert internal character encoding to SJIS */
$str mb_convert_encoding($str"SJIS");

/* Convert EUC-JP to UTF-7 */
$str mb_convert_encoding($str"UTF-7""EUC-JP");

/* Auto detect encoding from JIS, eucjp-win, sjis-win, then convert str to UCS-2LE */
$str mb_convert_encoding($str"UCS-2LE""JIS, eucjp-win, sjis-win");

/* "auto" is expanded to "ASCII,JIS,UTF-8,EUC-JP,SJIS" */
$str mb_convert_encoding($str"EUC-JP""auto");
?>


See also Mbstring.

ext/mcrypt

[Since 0.8.4] - [ -P Extensions/Extmcrypt ] - [ Online docs ]

Extension for mcrypt.

This extension has been deprecated as of PHP 7.1.0 and moved to PECL as of PHP 7.2.0.

This is an interface to the mcrypt library, which supports a wide variety of block algorithms such as DES, TripleDES, Blowfish (default), 3-WAY, SAFER-SK64, SAFER-SK128, TWOFISH, TEA, RC2 and GOST in CBC, OFB, CFB and ECB cipher modes. Additionally, it supports RC6 and IDEA which are considered 'non-free'. CFB/OFB are 8bit by default.

<?php 
# --- ENCRYPTION ---

    # the key should be random binary, use scrypt, bcrypt or PBKDF2 to
    # convert a string into a key
    # key is specified using hexadecimal
    
$key pack('H*''bcb04b7e103a0cd8b54763051cef08bc55abe029fdebae5e1d417e2ffb2a00a3');
    
    
# show key size use either 16, 24 or 32 byte keys for AES-128, 192
    # and 256 respectively
    
$key_size =  strlen($key);
    echo 
'Key size: ' $key_size PHP_EOL;
    
    
$plaintext 'This string was AES-256 / CBC / ZeroBytePadding encrypted.';

    
# create a random IV to use with CBC encoding
    
$iv_size mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128MCRYPT_MODE_CBC);
    
$iv mcrypt_create_iv($iv_sizeMCRYPT_RAND);
    
    
# creates a cipher text compatible with AES (Rijndael block size = 128)
    # to keep the text confidential 
    # only suitable for encoded input that never ends with value 00h
    # (because of default zero padding)
    
$ciphertext mcrypt_encrypt(MCRYPT_RIJNDAEL_128$key,
                                 
$plaintextMCRYPT_MODE_CBC$iv);

    
# prepend the IV for it to be available for decryption
    
$ciphertext $iv $ciphertext;
    
    
# encode the resulting cipher text so it can be represented by a string
    
$ciphertext_base64 base64_encode($ciphertext);

    echo  
$ciphertext_base64 PHP_EOL;

    
# === WARNING ===

    # Resulting cipher text has no integrity or authenticity added
    # and is not protected against padding oracle attacks.
    
    # --- DECRYPTION ---
    
    
$ciphertext_dec base64_decode($ciphertext_base64);
    
    
# retrieves the IV, iv_size should be created using mcrypt_get_iv_size()
    
$iv_dec substr($ciphertext_dec0$iv_size);
    
    
# retrieves the cipher text (everything except the $iv_size in the front)
    
$ciphertext_dec substr($ciphertext_dec$iv_size);

    
# may remove 00h valued characters from end of plain text
    
$plaintext_dec mcrypt_decrypt(MCRYPT_RIJNDAEL_128$key,
                                    
$ciphertext_decMCRYPT_MODE_CBC$iv_dec);
    
    echo  
$plaintext_dec PHP_EOL;
?>


See also extension mcrypt and mcrypt.

ext/mongo

[Since 0.8.4] - [ -P Extensions/Extmongo ] - [ Online docs ]

Extension MongoDB driver (legacy).

<?php 
// connect
$m = new MongoClient();

// select a database
$db $m->comedy;

// select a collection (analogous to a relational database\'s table)
$collection $db->cartoons;

// add a record
$document = array( 'title' => 'Calvin and Hobbes''author' => 'Bill Watterson' );
$collection->insert($document);

// add another record, with a different 'shape'
$document = array( 'title' => 'XKCD''online' => true );
$collection->insert($document);

// find everything in the collection
$cursor $collection->find();

// iterate through the results
foreach ($cursor as $document) {
    echo 
$document['title'] . PHP_EOL;
}
?>


Note : this is not the MongoDB driver. This is the legacy extension.

See also ext/mongo manual and
MongdDb.

ext/mssql

[Since 0.8.4] - [ -P Extensions/Extmssql ] - [ Online docs ]

Extension MSSQL, Microsoft SQL Server.

These functions allow you to access MS SQL Server database.

<?php 
// Connect to MSSQL
$link mssql_connect('KALLESPC\SQLEXPRESS''sa''phpfi');

if (!
$link || !mssql_select_db('php'$link)) {
    die(
'Unable to connect or select database!');
}

// Do a simple query, select the version of 
// MSSQL and print it.
$version mssql_query('SELECT @@VERSION');
$row mssql_fetch_array($version);

echo 
$row[0];

// Clean up
mssql_free_result($version);
?>


See also Microsoft SQL Server and Microsoft PHP Driver for SQL Server.

ext/mysql

[Since 0.8.4] - [ -P Extensions/Extmysql ] - [ Online docs ] - [ PHP older than 7.0]

Extension for MySQL (Original MySQL API).

This extension is deprecated as of PHP 5.5.0, and has been removed as of PHP 7.0.0. Instead, either the mysqli or PDO_MySQL extension should be used. See also the MySQL API Overview for further help while choosing a MySQL API.

<?php 
$result mysql_query('SELECT * WHERE 1=1');
if (!
$result) {
    die(
'Invalid query: ' mysql_error());
}
?>


See also Original MySQL API and MySQL.

ext/mysqli

[Since 0.8.4] - [ -P Extensions/Extmysqli ] - [ Online docs ]

Extension mysqli for MySQL.

The mysqli extension allows you to access the functionality provided by MySQL 4.1 and above.

<?php 
$mysqli = new mysqli('localhost''my_user''my_password''world');

/* check connection */
if (mysqli_connect_errno()) {
    
printf('Connect failed: %s\n'mysqli_connect_error());
    exit();
}

$city 'Amersfoort';

/* create a prepared statement */
if ($stmt $mysqli->prepare('SELECT District FROM City WHERE Name=?')) {

    
/* bind parameters for markers */
    
$stmt->bind_param('s'$city);

    
/* execute query */
    
$stmt->execute();

    
/* bind result variables */
    
$stmt->bind_result($district);

    
/* fetch value */
    
$stmt->fetch();

    
printf('%s is in district %s\n'$city$district);

    
/* close statement */
    
$stmt->close();
}

/* close connection */
$mysqli->close();
?>


See also MySQL Improved Extension and MySQL.

ext/odbc

[Since 0.8.4] - [ -P Extensions/Extodbc ] - [ Online docs ]

Extension ODBC.

In addition to normal ODBC support, the Unified ODBC functions in PHP allow you to access several databases that have borrowed the semantics of the ODBC API to implement their own API. Instead of maintaining multiple database drivers that were all nearly identical, these drivers have been unified into a single set of ODBC functions.

<?php 
$a 1;
$b 2;
$c 3;
$stmt    odbc_prepare($conn'CALL myproc(?,?,?)');
$success odbc_execute($stmt, array($a$b$c));
?>


See also ODBC (Unified), Unixodbc and IODBC.

ext/openssl

[Since 0.8.4] - [ -P Extensions/Extopenssl ] - [ Online docs ]

Extension Openssl.

This extension binds functions of OpenSSL library for symmetric and asymmetric encryption and decryption, PBKDF2 , PKCS7 , PKCS12 , X509 and other cryptographic operations. In addition to that it provides implementation of TLS streams.

<?php 
// $data and $signature are assumed to contain the data and the signature

// fetch public key from certificate and ready it
$pubkeyid openssl_pkey_get_public("file://src/openssl-0.9.6/demos/sign/cert.pem");

// state whether signature is okay or not
$ok openssl_verify($data$signature$pubkeyid);
if (
$ok == 1) {
    echo 
"good";
} elseif (
$ok == 0) {
    echo 
"bad";
} else {
    echo 
"ugly, error checking signature";
}
// free the key from memory
openssl_free_key($pubkeyid);
?>


See also ext/OpenSSL and OpenSSL.

ext/pcre

[Since 0.8.4] - [ -P Extensions/Extpcre ] - [ Online docs ]

Extension ext/pcre. PCRE stands for Perl Compatible Regular Expression. It is a standard PHP extension.

<?php 
$zip_code $_GET['zip'];

// Canadian Zip code H2M 3J1
$zip_ca '/^([a-zA-Z]\d[a-zA-Z])\ {0,1}(\d[a-zA-Z]\d)$/';

// French Zip code  75017
$zip_fr '/^\d{5}$/';

// Chinese Zip code  590615
$zip_cn '/^\d{6}$/';

var_dump(preg_match($_GET['zip']));
?>


See also Regular Expressions (Perl-Compatible).

ext/pdo

[Since 0.8.4] - [ -P Extensions/Extpdo ] - [ Online docs ]

Generic extension PDO.

The PHP Data Objects (PDO) extension defines a lightweight, consistent interface for accessing databases in PHP.

<?php 
/* Execute a prepared statement by passing an array of values */
$sql 'SELECT name, colour, calories
    FROM fruit
    WHERE calories < :calories AND colour = :colour'
;
$sth $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute(array(':calories' => 150':colour' => 'red'));
$red $sth->fetchAll();
$sth->execute(array(':calories' => 175':colour' => 'yellow'));
$yellow $sth->fetchAll();
?>


See also PHP Data Object.

ext/pgsql

[Since 0.8.4] - [ -P Extensions/Extpgsql ] - [ Online docs ]

Extension PostGreSQL.

PostgreSQL is an open source descendant of this original Berkeley code. It provides SQL92/SQL99 language support, transactions, referential integrity, stored procedures and type extensibility.

<?php 
// Connect to a database named 'mary'
$dbconn pg_connect('dbname=mary');

// Prepare a query for execution
$result pg_prepare($dbconn'my_query''SELECT * FROM shops WHERE name = $1');

// Execute the prepared query.  Note that it is not necessary to escape
// the string 'Joe's Widgets' in any way
$result pg_execute($dbconn'my_query', array('Joe\'s Widgets'));

// Execute the same prepared query, this time with a different parameter
$result pg_execute($dbconn'my_query', array('Clothes Clothes Clothes'));
?>


See also PostgreSQL and PostgreSQL: The world's most advanced open source database.

ext/phar

[Since 0.8.4] - [ -P Extensions/Extphar ] - [ Online docs ]

Extension phar.

The phar extension provides a way to put entire PHP applications into a single file called a phar (PHP Archive) for easy distribution and installation.

<?php 
try {
    
$p = new Phar('/path/to/my.phar'0'my.phar');
    
$p['myfile.txt'] = 'hi';
    
$file $p['myfile.txt'];
    
var_dump($file->isCompressed(Phar::BZ2));
    
$p['myfile.txt']->compress(Phar::BZ2);
    
var_dump($file->isCompressed(Phar::BZ2));
} catch (
Exception $e) {
    echo 
'Create/modify operations on my.phar failed: '$e;
}
?>


See also phar.

ext/posix

[Since 0.8.4] - [ -P Extensions/Extposix ] - [ Online docs ]

Extension POSIX.

Ext/posix contains an interface to those functions defined in the IEEE 1003.1 (POSIX.1) standards document which are not accessible through other means.

<?php 
posix_kill(999459,SIGKILL);
echo 
'Your error returned was '.posix_get_last_error(); //Your error was ___
?>


See also 1003.1-2008 - IEEE Standard for Information Technology - Portable Operating System Interface (POSIX(R)).

ext/readline

[Since 0.8.4] - [ -P Extensions/Extreadline ] - [ Online docs ]

Extension readline.

The readline functions implement an interface to the GNU Readline library. These are functions that provide editable command lines.

<?php 
//get 3 commands from user
for ($i=0$i 3$i++) {
        
$line readline("Command: ");
        
readline_add_history($line);
}

//dump history
print_r(readline_list_history());

//dump variables
print_r(readline_info());
?>


See also ext/readline and
The GNU Readline Library.

ext/reflection

[Since 0.8.4] - [ -P Extensions/Extreflection ] - [ Online docs ]

Extension Reflection.

PHP comes with a complete reflection API that adds the ability to reverse-engineer classes, interfaces, functions, methods and extensions. Additionally, the reflection API offers ways to retrieve doc comments for functions, classes and methods.

<?php 
/**
 * A simple counter
 *
 * @return    int
 */
function counter1()
{
    static 
$c 0;
    return ++
$c;
}

/**
 * Another simple counter
 *
 * @return    int
 */
$counter2 = function()
{
    static 
$d 0;
    return ++
$d;

};

function 
dumpReflectionFunction($func)
{
    
// Print out basic information
    
printf(
        
PHP_EOL.'===> The %s function '%s''.PHP_EOL.
        
'     declared in %s'.PHP_EOL.
        
'     lines %d to %d'.PHP_EOL,
        
$func->isInternal() ? 'internal' 'user-defined',
        
$func->getName(),
        
$func->getFileName(),
        
$func->getStartLine(),
        
$func->getEndline()
    );

    
// Print documentation comment
    
printf('---> Documentation:'.PHP_EOL.' %s',PHP_EOLvar_export($func->getDocComment(), 1));

    
// Print static variables if existant
    
if ($statics $func->getStaticVariables())
    {
        
printf('---> Static variables: %s',PHP_EOLvar_export($statics1));
    }
}

// Create an instance of the ReflectionFunction class
dumpReflectionFunction(new ReflectionFunction('counter1'));
dumpReflectionFunction(new ReflectionFunction($counter2));
?>


See also Reflection.

ext/sem

[Since 0.8.4] - [ -P Extensions/Extsem ] - [ Online docs ]

Extension Semaphore, Shared Memory and IPC.

This module provides wrappers for the System V IPC family of functions. It includes semaphores, shared memory and inter-process messaging (IPC).

<?php 
$key         ftok(__FILE__,'a');
$semaphore   sem_get($key);
sem_acquire($semaphore);
sem_release($semaphore);
sem_remove($semaphore);
?>


See also Semaphore, Shared Memory and IPC.

ext/session

[Since 0.8.4] - [ -P Extensions/Extsession ] - [ Online docs ]

Extension ext/session.

Session support in PHP consists of a way to preserve certain data across subsequent accesses.

<?php 
session_start();
if (!isset(
$_SESSION['count'])) {
  
$_SESSION['count'] = 0;
} else {
  
$_SESSION['count']++;
}
?>


See also Session.

ext/shmop

[Since 0.8.4] - [ -P Extensions/Extshmop ] - [ Online docs ]

Extension ext/shmop.

Shmop is an easy to use set of functions that allows PHP to read, write, create and delete Unix shared memory segments.

<?php 
// Create a temporary file and return its path
$tmp tempnam('/tmp''PHP');

// Get the file token key
$key ftok($tmp'a');

// Attach the SHM resource, notice the cast afterwards
$id shm_attach($key);

if (
$id === false) {
    die(
'Unable to create the shared memory segment');
}

// Cast to integer, since prior to PHP 5.3.0 the resource id 
// is returned which can be exposed when casting a resource
// to an integer
$id = (integer) $id;
?>


See also Semaphore, Shared Memory and IPC.

ext/simplexml

[Since 0.8.4] - [ -P Extensions/Extsimplexml ] - [ Online docs ]

Extension SimpleXML .

The SimpleXML extension provides a very simple and easily usable toolset to convert XML to an object that can be processed with normal property selectors and array iterators.

<?php 
$xml = <<<'XML'
<?xml version='1.0' standalone='yes' ? >
<movies>
 <movie>
  <title>PHP: Behind the Parser</title>
  <characters>
   <character>
    <name>Ms. Coder</name>
    <actor>Onlivia Actora</actor>
   </character>
   <character>
    <name>Mr. Coder</name>
    <actor>El Act&#211;r</actor>
   </character>
  </characters>
  <plot>
   So, this language. It's like, a programming language. Or is it a
   scripting language? All is revealed in this thrilling horror spoof
   of a documentary.
  </plot>
  <great-lines>
   <line>PHP solves all my web problems</line>
  </great-lines>
  <rating type="thumbs">7</rating>
  <rating type="stars">5</rating>
 </movie>
</movies>
XML;

$movies = new SimpleXMLElement($xml);

echo 
$movies->movie[0]->plot;
?>


See also SimpleXML.

ext/snmp

[Since 0.8.4] - [ -P Extensions/Extsnmp ] - [ Online docs ]

Extension SNMP.

The SNMP extension provides a very simple and easily usable toolset for managing remote devices via the Simple Network Management Protocol.

<?php 
$nameOfSecondInterface snmp3_get('localhost''james''authPriv''SHA''secret007''AES''secret007''IF-MIB::ifName.2');
?>


See also Net SNMP and SNMP.

ext/soap

[Since 0.8.4] - [ -P Extensions/Extsoap ] - [ Online docs ]

Extension SOAP.

The SOAP extension can be used to write SOAP Servers and Clients. It supports subsets of » SOAP 1.1, » SOAP 1.2 and » WSDL 1.1 specifications.

<?php 
$client = new SoapClient("some.wsdl");

$client = new SoapClient("some.wsdl", array('soap_version'   => SOAP_1_2));

$client = new SoapClient("some.wsdl", array('login'          => "some_name",
                                            
'password'       => "some_password"));
?>


See also SOAP and
SOAP specifications.

ext/sockets

[Since 0.8.4] - [ -P Extensions/Extsockets ] - [ Online docs ]

Extension socket.

The socket extension implements a low-level interface to the socket communication functions based on the popular BSD sockets, providing the possibility to act as a socket server as well as a client.

<?php 
//Example #2 Socket example: Simple TCP/IP client
//From the PHP manual

error_reporting(E_ALL);

echo 
"<h2>TCP/IP Connection</h2>\n";

/* Get the port for the WWW service. */
$service_port getservbyname('www''tcp');

/* Get the IP address for the target host. */
$address gethostbyname('www.example.com');

/* Create a TCP/IP socket. */
$socket socket_create(AF_INETSOCK_STREAMSOL_TCP);
if (
$socket === false) {
    echo 
'socket_create() failed: reason: ' socket_strerror(socket_last_error()) . PHP_EOL;
} else {
    echo 
'OK.'.PHP_EOL;
}

echo 
'Attempting to connect to '$address' on port '$service_port'...';
$result socket_connect($socket$address$service_port);
if (
$result === false) {
    echo 
'socket_connect() failed.\nReason: ($result) ' socket_strerror(socket_last_error($socket)) . '\n';
} else {
    echo 
'OK.'.PHP_EOL;
}

$in ""HEAD HTTP/1.1\r\n"";
$in .= ""Hostwww.example.com\r\n"";
$in .= ""ConnectionClose\r\n\r\n"";
$out '';

echo 
'Sending HTTP HEAD request...';
socket_write($socket$instrlen($in));
echo 
"OK.\n";

echo 
'Reading response:\n\n';
while (
$out socket_read($socket2048)) {
    echo 
$out;
}

echo 
'Closing socket...';
socket_close($socket);
echo 
'OK.\n\n';
?>


See also Sockets.

ext/spl

[Since 0.8.4] - [ -P Extensions/Extspl ] - [ Online docs ]

SPL extension.

The Standard PHP Library (SPL) is a collection of interfaces and classes that are meant to solve common problems.

<?php 
// Example with FilesystemIterator
$files = new FilesystemIterator('/path/to/dir');
foreach(
$files as $file) {
    echo 
$file->getFilename() . PHP_EOL;
}
?>


See also Standard PHP Library (SPL).

ext/sqlite

[Since 0.8.4] - [ -P Extensions/Extsqlite ] - [ Online docs ]

Extension Sqlite 2.

Support for SQLite version 2 databases. The support for this version of Sqlite is not maintained anymore. It is recommended to use SQLite3 .

<?php 
if ($db sqlite_open('mysqlitedb'0666$sqliteerror)) { 
    
sqlite_query($db'CREATE TABLE foo (bar varchar(10))');
    
sqlite_query($db'INSERT INTO foo VALUES ("fnord")');
    
$result sqlite_query($db'select bar from foo');
    
var_dump(sqlite_fetch_array($result)); 
} else {
    die(
$sqliteerror);
}
?>


See also ext/sqlite and
SQLite.

ext/sqlite3

[Since 0.8.4] - [ -P Extensions/Extsqlite3 ] - [ Online docs ]

Extension Sqlite3.

Support for SQLite version 3 databases.

<?php 
$db = new SQLite3('mysqlitedb.db');

$results $db->query('SELECT bar FROM foo');
while (
$row $results->fetchArray()) {
    
var_dump($row);
}
?>


See also ext/sqlite3 and
Sqlite.

ext/ssh2

[Since 0.8.4] - [ -P Extensions/Extssh2 ] - [ Online docs ]

Extension ext/ssh2.

<?php 
/* Notify the user if the server terminates the connection */
function my_ssh_disconnect($reason$message$language) {
  
printf("Server disconnected with reason code [%d] and message: %s\n",
         
$reason$message);
}

$methods = array(
  
'kex' => 'diffie-hellman-group1-sha1',
  
'client_to_server' => array(
    
'crypt' => '3des-cbc',
    
'comp' => 'none'),
  
'server_to_client' => array(
    
'crypt' => 'aes256-cbc,aes192-cbc,aes128-cbc',
    
'comp' => 'none'));

$callbacks = array('disconnect' => 'my_ssh_disconnect');

$connection ssh2_connect('shell.example.com'22$methods$callbacks);
if (!
$connection) die('Connection failed');
?>


See also SSH2 functions and
ext/ssh2 on PECL.

ext/standard

[Since 0.8.4] - [ -P Extensions/Extstandard ] - [ Online docs ]

Standards PHP functions.

This is not a real PHP extension : it covers the core functions.

<?php 
/*
Our php.ini contains the following settings:

display_errors = On
register_globals = Off
post_max_size = 8M
*/

echo 'display_errors = ' ini_get('display_errors') . PHP_EOL;
echo 
'register_globals = ' ini_get('register_globals') . PHP_EOL;
echo 
'post_max_size = ' ini_get('post_max_size') . PHP_EOL;
echo 
'post_max_size+1 = ' . (ini_get('post_max_size')+1) . PHP_EOL;
echo 
'post_max_size in bytes = ' return_bytes(ini_get('post_max_size'));

function 
return_bytes($val) {
    
$val trim($val);
    
$last strtolower($val[strlen($val)-1]);
    switch(
$last) {
        
// The 'G' modifier is available since PHP 5.1.0
        
case 'g':
            
$val *= 1024;
        case 
'm':
            
$val *= 1024;
        case 
'k':
            
$val *= 1024;
    }

    return 
$val;
}
?>


See also PHP Options/Info Functions.

ext/tidy

[Since 0.8.4] - [ -P Extensions/Exttidy ] - [ Online docs ]

Extension Tidy.

Tidy is a binding for the Tidy HTML clean and repair utility which allows you to not only clean and otherwise manipulate HTML documents, but also traverse the document tree.

<?php 
`ob_start() <https://www.php.net/ob_start>`_;
?>

a html document
<?php 
$html = `ob_get_clean() <https://www.php.net/ob_get_clean>`_;

// Specify configuration
$config = array(
           
'indent'         => true,
           
'output-xhtml'   => true,
           
'wrap'           => 200);

// Tidy
$tidy = new tidy;
$tidy->parseString($html$config'utf8');
$tidy->cleanRepair();

// Output
echo $tidy;
?>


See also Tidy and
HTML-tidy.

ext/tokenizer

[Since 0.8.4] - [ -P Extensions/Exttokenizer ] - [ Online docs ]

Extension Tokenizer.

The Tokenizer functions provide an interface to the PHP tokenizer embedded in the Zend Engine.

<?php 
/*
* T_ML_COMMENT does not exist in PHP 5.
* The following three lines define it in order to
* preserve backwards compatibility.
*
* The next two lines define the PHP 5 only T_DOC_COMMENT,
* which we will mask as T_ML_COMMENT for PHP 4.
*/
if (!defined('T_ML_COMMENT')) {
   
define('T_ML_COMMENT'T_COMMENT);
} else {
   
define('T_DOC_COMMENT'T_ML_COMMENT);
}

$source file_get_contents('example.php');
$tokens token_get_all($source);

foreach (
$tokens as $token) {
   if (
is_string($token)) {
       
// simple 1-character token
       
echo $token;
   } else {
       
// token array
       
list($id$text) = $token;

       switch (
$id) { 
           case 
T_COMMENT
           case 
T_ML_COMMENT// we\'ve defined this
           
case T_DOC_COMMENT// and this
               // no action on comments
               
break;

           default:
               
// anything else -> output 'as is'
               
echo $text;
               break;
       }
   }
}
?>


See also tokenizer.

ext/wddx

[Since 0.8.4] - [ -P Extensions/Extwddx ] - [ Online docs ]

Extension WDDX.

The Web Distributed Data Exchange, or WDDX, is a free, open XML-based technology that allows Web applications created with any platform to easily exchange data with one another over the Web.

<?php 
echo wddx_serialize_value("PHP to WDDX packet example""PHP packet");
?>


See also Wddx on PHP and
WDDX.

ext/xdebug

[Since 0.8.4] - [ -P Extensions/Extxdebug ] - [ Online docs ]

Xdebug extension.

The Xdebug is a extension PHP which provides debugging and profiling capabilities.

<?php 
class Strings
{
    static function 
fix_string($a)
    {
        echo
            
xdebug_call_class().
            
"::".
            
xdebug_call_function().
            
" is called at ".
            
xdebug_call_`file() <https://www.php.net/file>`_.
            
":".
            
xdebug_call_line();
    }
}

$ret Strings::fix_string'Derick' );
?>


See also Xdebug.

ext/xmlreader

[Since 0.8.4] - [ -P Extensions/Extxmlreader ] - [ Online docs ]

Extension XMLReader.

The XMLReader extension is an XML Pull parser. The reader acts as a cursor going forward on the document stream and stopping at each node on the way.

<?php 
$xmlreader = new XMLReader();
    
$xmlreader->xml("<xml><div>Content</div></xml>");
    
$xmlreader->read();
    
$xmlreader->read();
    
$xmlreader->readString();
?>


See also xmlreader.

ext/xmlrpc

[Since 0.8.4] - [ -P Extensions/Extxmlrpc ] - [ Online docs ]

Extension ext/xmlrpc.

This extension can be used to write XML-RPC servers and clients.

<?php 
$request xmlrpc_encode_request('method', array(123));
$context stream_context_create(array('http' => array(
    
'method' => 'POST',
    
'header' => 'Content-Type: text/xml',
    
'content' => $request
)));
$file file_get_contents('http://www.example.com/xmlrpc'false$context);
$response xmlrpc_decode($file);
if (
$response && xmlrpc_is_fault($response)) {
    
trigger_error('xmlrpc: '.$response['faultString'].' ('.$response['faultCode']));
} else {
    
print_r($response);
}
?>


See also XML-RPC.

ext/xmlwriter

[Since 0.8.4] - [ -P Extensions/Extxmlwriter ] - [ Online docs ]

Extension ext/xmlwriter.

The XMLWriter extension wraps the libxml xmlWriter API inside PHP.

<?php 
$xw xmlwriter_open_memory();
xmlwriter_set_indent($xwTRUE);
xmlwriter_start_document($xwNULL'UTF-8');
xmlwriter_start_element($xw'root');
xmlwriter_write_attribute_ns($xw'prefix''''http://www.php.net/uri');
xmlwriter_start_element($xw'elem1');
xmlwriter_write_attribute($xw'attr1''first');
xmlwriter_end_element($xw);
xmlwriter_full_end_element($xw);
xmlwriter_end_document($xw);
$output xmlwriter_flush($xwtrue);
print 
$output;
// write attribute_ns without start_element first
$xw xmlwriter_open_memory();
var_dump(xmlwriter_write_attribute_ns($xw'prefix''id''http://www.php.net/uri''elem1'));
print 
xmlwriter_output_memory($xw);
?>


See also XMLWriter and Module xmlwriter from libxml2.

ext/xsl

[Since 0.8.4] - [ -P Extensions/Extxsl ] - [ Online docs ]

Extension XSL.

The XSL extension implements the XSL standard, performing XSLT transformations using the libxslt library.

<?php 
// Example from the PHP manual

$xmldoc = new DOMDocument();
$xsldoc = new DOMDocument();
$xsl = new XSLTProcessor();

$xmldoc->loadXML('fruits.xml');
$xsldoc->loadXML('fruits.xsl');

libxml_use_internal_errors(true);
$result $xsl->importStyleSheet($xsldoc);
if (!
$result) {
    foreach (
libxml_get_errors() as $error) {
        echo 
"Libxml error: {$error->message}\n";
    }
}
libxml_use_internal_errors(false);

if (
$result) {
    echo 
$xsl->transformToXML($xmldoc);
}
?>


See also XSL extension;

ext/yaml

[Since 0.8.4] - [ -P Extensions/Extyaml ] - [ Online docs ]

Extension YAML.

This extension implements the YAML Ain't Markup Language (YAML) data serialization standard. Parsing and emitting are handled by the LibYAML library.

<?php 
$addr = array(
    
'given' => 'Chris',
    
'family'=> 'Dumars',
    
'address'=> array(
        
'lines'=> '458 Walkman Dr.
        Suite #292'
,
        
'city'=> 'Royal Oak',
        
'state'=> 'MI',
        
'postal'=> 48046,
      ),
  );
$invoice = array (
    
'invoice'=> 34843,
    
'date'=> '2001-01-23',
    
'bill-to'=> $addr,
    
'ship-to'=> $addr,
    
'product'=> array(
        array(
            
'sku'=> 'BL394D',
            
'quantity'=> 4,
            
'description'=> 'Basketball',
            
'price'=> 450,
          ),
        array(
            
'sku'=> 'BL4438H',
            
'quantity'=> 1,
            
'description'=> 'Super Hoop',
            
'price'=> 2392,
          ),
      ),
    
'tax'=> 251.42,
    
'total'=> 4443.52,
    
'comments'=> 'Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.',
    );

// generate a YAML representation of the invoice
$yaml yaml_emit($invoice);
var_dump($yaml);

// convert the YAML back into a PHP variable
$parsed yaml_parse($yaml);

// check that roundtrip conversion produced an equivalent structure
var_dump($parsed == $invoice);
?>



See also YAML.

ext/zip

[Since 0.8.4] - [ -P Extensions/Extzip ] - [ Online docs ]

Extension ext/zip.

This extension enables you to transparently read or write ZIP compressed archives and the files inside them.

<?php 
$zip = new ZipArchive();
$filename './test112.zip';

if (
$zip->open($filenameZipArchive::CREATE)!==TRUE) {
    exit(
'cannot open <$filename>');
}

$zip->addFromString('testfilephp.txt' time(), '#1 This is a test string added as testfilephp.txt.'.PHP_EOL);
$zip->addFromString('testfilephp2.txt' time(), '#2 This is a test string added as testfilephp2.txt.'.PHP_EOL);
$zip->addFile($thisdir '/too.php','/testfromfile.php');
echo 
'numfiles: ' $zip->numFiles PHP_EOL;
echo 
'status:' $zip->status PHP_EOL;
$zip->close();
?>


See also Zip.

ext/zlib

[Since 0.8.4] - [ -P Extensions/Extzlib ] - [ Online docs ]

Extension ext/zlib.

<?php 
$filename tempnam('/tmp''zlibtest') . '.gz';
echo 
"<html>\n<head></head>\n<body>\n<pre>\n";
$s "Only a test, test, test, test, test, test, test, test!\n";

// open file for writing with maximum compression
$zp gzopen($filename'w9');

// write string to file
gzwrite($zp$s);

// close file
gzclose($zp);
?>


See also Zlib.

Closures Glossary

[Since 0.8.4] - [ -P Functions/Closures ] - [ Online docs ]

List of all the closures in the code.

<?php 
// A closure is also a unnamed function
$closure = function ($arg) { return 'A'.strtolower($arg); }
?>


See also The Closure Class.

Empty Function

[Since 0.8.4] - [ -P Functions/EmptyFunction ] - [ Online docs ]

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.

A method is considered empty when it contains nothing, or contains expressions without impact.

<?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() {}
}
?>


Methods which overwrite another methods are omitted. Methods which are the concrete version of an abstract method are considered.

Functions Glossary

[Since 0.8.4] - [ -P Functions/Functionnames ] - [ Online docs ]

List of all the defined functions in the code.

<?php 
// A function
function aFunction() {}

// Closures (not reported)
$closure = function ($arg) {  }

// Methods
class foo {
    function 
aMethod() {}
}
?>


Recursive Functions

[Since 0.8.4] - [ -P Functions/Recursive ] - [ Online docs ]

Recursive functions are functions that calls itself.

<?php 
// a recursive function ; it calls itself
function factorial($n) {
    if (
$n == 1) { return 1; }
    
    return 
factorial($n 1) * $n;
}
?>


Methods are not handled here.

Redeclared PHP Functions

[Since 0.8.4] - [ -P Functions/RedeclaredPhpFunction ] - [ Online docs ]

Function that bear the same name as a PHP function, and that are declared.

This is useful when managing backward compatibility, like emulating an old function, or preparing for newer PHP versions, like emulating new upcoming function.

<?php 
if (version_compare(PHP_VERSION7.0) > 0) {
    function 
split($separator$string) {
        return 
explode($separator$string);
    }
}

print_rsplit(' ''2 3'));
?>

Typehints

[Since 0.8.4] - [ -P Functions/Typehints ] - [ Online docs ]

List of all the types (classes or scalar) used in Typehinting.

<?php 
// here, array, myObject and string are all typehints.
function foo(array $arraymyObject $xstring $string) {

}
?>


See also Type declarations.

Methods Without Return

[Since 0.8.4] - [ -P Functions/WithoutReturn ] - [ Online docs ]

List of all the function, closures, methods that have no explicit return.

Functions that hold the void return type are omitted.

<?php 
// With return null : Explicitly not returning
function withExplicitReturn($a 1) {
    
$a++;
    return 
null;
}

// Without indication
function withoutExplicitReturn($a 1) {
    
$a++;
}

// With return type void : Explicitly not returning
function withExplicitReturnType($a 1) : void {
    
$a++;
}
?>


See also return.

Empty Interfaces

[Since 0.8.4] - [ -P Interfaces/EmptyInterface ] - [ Online docs ]

Empty interfaces are a code smell. Interfaces should contains at least a method or a constant, and not be totally empty.

<?php 
// an empty interface
interface empty {}

// an normal interface
interface normal {
    public function 
i() ;
}

// a constants interface
interface constantsOnly {
    const 
FOO 1;
}
?>


See also Empty interfaces are bad practice and Blog : Are empty interfaces code smell?.

Interfaces Glossary

[Since 0.8.4] - [ -P Interfaces/Interfacenames ] - [ Online docs ]

List of all the defined interfaces in the code.

<?php 
// interfaceName is reported
interface interfaceName {
    function 
interfaceMethod() ; 
}
?>

Aliases

[Since 0.8.4] - [ -P Namespaces/Alias ] - [ Online docs ]

List of all aliases used, to alias namespaces.

<?php 
// This is an alias
use stdClass as aClass;

// This is not an alias : it is not explicit
use stdClass;

trait 
{
    
// This is not an alias, it's a trait usage
    
use otherTrait;
}
?>


See also Using namespaces: Aliasing/Importing.

Namespaces Glossary

[Since 0.8.4] - [ -P Namespaces/Namespacesnames ] - [ Online docs ]

List of all the defined namespaces in the code, using the namespace keyword.

<?php 
// One reported namespace
namespace one\name\space {}

// This global namespace is reported, as it is explicit
namespace { }
?>


Global namespaces are mentioned when they are explicitly used.

Autoloading

[Since 0.8.4] - [ -P Php/AutoloadUsage ] - [ Online docs ]

Usage of the autoloading feature of PHP.

<?php 
spl_autoload_register('my_autoloader');

// Old way to autoload. Deprecated in PHP 7.2
function __autoload($class ) {}
?>


Defining the __autoload() function is obsolete since PHP 7.2.

See also __autoload.

Use Lower Case For Parent, Static And Self

[Since 0.8.4] - [ -P Php/CaseForPSS ] - [ Online docs ] - [ PHP older than 5.5]

The special parent, static and self keywords needed to be lowercase to be usable. This was fixed in PHP 5.5; 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.

Goto Names

[Since 0.8.4] - [ -P Php/Gotonames ] - [ Online docs ]

List of all goto labels used in the code.

<?php 
GOTO_NAME_1

// reports the usage of GOTO_NAME_1
goto GOTO_NAME_1;

UNUSED_GOTO_NAME_1:
?>


__halt_compiler

[Since 0.8.4] - [ -P Php/Haltcompiler ] - [ Online docs ]

__halt_compiler() usage.

<?php 
// open this file
$fp fopen(__FILE__'r');

// seek file pointer to data
fseek($fp__COMPILER_HALT_OFFSET__);

// and output it
var_dump(stream_get_contents($fp));

// the end of the script execution
__halt_compiler(); the installation data (egtargzPHPetc.)
?>

Incompilable Files

[Since 0.8.4] - [ -P Php/Incompilable ] - [ Online docs ]

Files that cannot be compiled, and, as such, be run by PHP. Scripts are linted against various versions of PHP.

This is usually undesirable, as all code must compile before being executed. It may 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 not compilable with older PHP versions means that the code is breaking backward compatibility : good or bad is project decision.

When the code is used as a template for PHP code generation, for example at installation time, it is recommended to use a distinct file extension, so as to distinguish them from actual PHP code.

Labels

[Since 0.8.4] - [ -P Php/Labelnames ] - [ Online docs ]

List of all labels used in the code.

<?php 
// A is label. 
goto A:

A:

// A label may be used by several gotos.
goto A:
?>


Functions Removed In PHP 5.4

[Since 0.8.4] - [ -P Php/Php54RemovedFunctions ] - [ Online docs ] - [ PHP older than 5.4]

Those functions were removed in PHP 5.4.

<?php 
// Deprecated as of PHP 5.4.0
$link mysql_connect('localhost''mysql_user''mysql_password');
$db_list mysql_list_dbs($link);

while (
$row mysql_fetch_object($db_list)) {
     echo 
$row->Database "\n";
}
?>


See also Deprecated features in PHP 5.4.x.

Functions Removed In PHP 5.5

[Since 0.8.4] - [ -P Php/Php55RemovedFunctions ] - [ Online docs ] - [ PHP older than 5.5]

Those functions were removed in PHP 5.5.

+ php_logo_guid()
+ php_egg_logo_guid()
+ php_real_logo_guid()
+ zend_logo_guid()
+ mcrypt_cbc()
+ mcrypt_cfb()
+ mcrypt_ecb()
+ mcrypt_ofb()

<?php 
echo '<img src="' $_SERVER['PHP_SELF'] .
     
'?=' . `php_logo_guid() <https://www.php.net/php_logo_guid>`'" alt="PHP Logo !" />';
?>


See also Deprecated features in PHP 5.5.x.

Throw

[Since 0.8.4] - [ -P Php/ThrowUsage ] - [ Online docs ]

List of thrown exceptions.

<?php 
if ($divisor === 0) {
    
// Throw native exception
    
throw new DivisionByZeroError("Shouldn't divide by one");
}

if (
$divisor === 1) {
    
// Throw custom exception
    
throw new DontDivideByOneException("Shouldn't divide by one");
}
?>


See also Exceptions.

Trigger Errors

[Since 0.8.4] - [ -P Php/TriggerErrorUsage ] - [ Online docs ]

List of situations where user errors are triggered.

PHP errors are triggered with trigger_error().

<?php 
if ($divisor == 0) {
    
trigger_error('Cannot divide by zero'E_USER_ERROR);
}
?>


See also trigger_error.

Caught Expressions

[Since 0.8.4] - [ -P Php/TryCatchUsage ] - [ Online docs ]

List of caught exceptions.

<?php 
// This analyzer reports MyException and Exception
try {
    
doSomething();
} catch (
MyException $e) {
    
fixIt();
} catch (\
Exception $e) {
    
fixIt();
}
?>


Break With 0

[Since 0.8.4] - [ -P Structures/Break0 ] - [ Online docs ] - [ PHP older than 5.4]

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;
        }
    }
?>


Break With Non Integer

[Since 0.8.4] - [ -P Structures/BreakNonInteger ] - [ Online docs ] - [ PHP older than 5.4]

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;
        }
    }
?>


Calltime Pass By Reference

[Since 0.8.4] - [ -P Structures/CalltimePassByReference ] - [ Online docs ] - [ PHP older than 5.4]

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.

<?php 
function foo($name) {
    
$arg ucfirst(strtolower($name));
    echo 
'Hello '.$arg;
}

$a 'name';
foo(&$a);
?>


error_reporting() With Integers

[Since 0.8.4] - [ -P Structures/ErrorReportingWithInteger ] - [ Online docs ]

Using named constants with error_reporting is strongly encouraged to ensure compatibility for future versions. As error levels are added, the range of integers increases, so older integer-based error levels will not always behave as expected. (Adapted from the documentation).

<?php 
// This is ready for PHP next version
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE & ~E_WARNING);

// This is not ready for PHP next version
error_reporting(2047);

// -1 and 0 are omitted, as they will be valid even is constants changes.
error_reporting(-1);
error_reporting(0);
?>


See also directive error_reporting and
error_reporting.

Eval() Usage

[Since 0.8.4] - [ -P Structures/EvalUsage ] - [ Online docs ]

Using eval() is evil.

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() <https://www.php.net/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 the code code given to `eval() <https://www.php.net/eval>`_ is known at compile time, it is best to put it inline
    
$literalCode '`phpinfo() <https://www.php.net/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 pregenerated file is faster and cacheable.

There are several situations where eval() is actually the only solution :

For PHP 7.0 and later, it is important to put eval() in a try..catch expression.

See also eval and
The Land Where PHP Uses `eval() `_.

Exit() Usage

[Since 0.8.4] - [ -P Structures/ExitUsage ] - [ Online docs ]

Using exit or die() in the code makes the code untestable (it will break unit tests). Moreover, 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.

For Using Functioncall

[Since 0.8.4] - [ -P Structures/ForWithFunctioncall ] - [ Online docs ]

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() <https://www.php.net/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.

Forgotten Whitespace

[Since 0.8.4] - [ -P Structures/ForgottenWhiteSpace ] - [ Online docs ]

Forgotten whitespaces only bring misery to the code.

White spaces have been left at either end of a file : before the PHP opening tag, or after the closing tag.

Usually, such whitespaces are forgotten, and may end up summoning the infamous 'headers already sent' error. It is better to remove them.

<?php 
// This script has no forgotten whitespace, not at the beginning
    
function foo() {}

    
// This script has no forgotten whitespace, not at the end
?>


See also How to fix Headers already sent error in PHP.

Iffectations

[Since 0.8.4] - [ -P Structures/Iffectation ] - [ Online docs ]

Affectations that appears in a condition.

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;
}
?>


Multiply By One

[Since 0.8.4] - [ -P Structures/MultiplyByOne ] - [ Online docs ]

Multiplying by 1 is a fancy type cast.

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;
?>


See also Type Juggling

@ Operator

[Since 0.8.4] - [ -P Structures/Noscream ] - [ Online docs ]

@ is the 'no scream' operator : it suppresses error output.

<?php 
// Set x with incoming value, or else null. 
$x = @$_GET['x'];
?>


This operator is actually very slow : it will process the error all the way up, and finally decide not to display it. It is often faster to check the conditions first, then run the method without @ .

You may also set display_error to 0 in the php.ini : this will avoid user's error display, but will keep the error in the PHP logs, for later processing.

The only situation where @ is useful is when a native PHP function displays errors messages when error happens and there is no way to check it from the code.

This is the case with fopen(), stream_socket_server(), token_get_all().

See also Error Control Operators and
Five reasons why the shut-op operator should be avoided.

Not Not

[Since 0.8.4] - [ -P Structures/NotNot ] - [ Online docs ]

Double not makes a boolean, not a true .

This is a wrong casting to boolean. PHP supports (boolean) to do the same, faster and cleaner.

<?php 
// Explicit code
    
$b = (boolean) $x
    
$b = (bool) $x

    
// Wrong type casting
    
$b = !!$x;
?>


See also Logical Operators and
Type Juggling.

include_once() Usage

[Since 0.8.4] - [ -P Structures/OnceUsage ] - [ Online docs ]

include_once() and require_once() functions should be avoided for performances reasons.

<?php 
// Including a library. 
include 'lib/helpers.inc';

// Including a library, and avoiding double inclusion
include_once 'lib/helpers.inc';
?>


Try using autoload for loading classes, or use include() or require() and make it possible to include several times the same file without errors.

Phpinfo

[Since 0.8.4] - [ -P Structures/PhpinfoUsage ] - [ Online docs ]

phpinfo() is a great function to learn about the current configuration of the server.

<?php 
if (DEBUG) {
    `
phpinfo() <https://www.php.net/phpinfo>`_;
}
?>


If left in the production code, it may lead to a critical leak, as any attacker gaining access to this data will know a lot about the server configuration.

It is advised to never leave that kind of instruction in a production code.

phpinfo() may be necessary to access some specific configuration of the server : for example, Apache module list are only available via phpinfo(), and apache_get(), when they are loaded.

Using Short Tags

[Since 0.8.4] - [ -P Structures/ShortTags ] - [ Online docs ]

The code makes use of short tags. Short tags are the following : . A full scripts looks like that : .

It is recommended to not use short tags, and use standard PHP tags. This makes PHP code compatible with XML standards. Short tags used to be popular, but have lost it.

See also PHP Tags.

Strpos()-like Comparison

[Since 0.8.4] - [ -P Structures/StrposCompare ] - [ Online docs ]

The result of that function may be mistaken with an error.

strpos(), along with several PHP native functions, 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 result of strpos() with === or !==, so as to avoid confusing 0 and false.

This analyzer list all the strpos()-like functions that are directly compared with == or !=. preg_match(), when its first argument is a literal, is omitted : this function only returns NULL in case of regex error.

The full list is the following :



In PHP 8.0, str_contains() will do the expected job of strpos(), with less confusion.

See also strpos not working correctly.

Throws An Assignement

[Since 0.8.4] - [ -P Structures/ThrowsAndAssign ] - [ Online docs ]

It is possible to throw an exception, and, in the same time, assign this exception to a variable.

However, the variable will never be used, as the exception is thrown, and any following code is not executed.

<?php 
// $e is useful, though not by much
    
$e = new() Exception();
    throw 
$e;

    
// $e is useless
    
throw $e = new Exception();
?>


The assignment should be removed.

var_dump()... Usage

[Since 0.8.4] - [ -P Structures/VardumpUsage ] - [ Online docs ]

var_dump(), print_r() or var_export() should not be left in any production code. They are debugging functions.

<?php 
if ($error) {
    
// Debugging usage of var_dump
    // And major security problem 
    
var_dump($query);
    
    
// This is OK : the $query is logged, and not displayed
    
$this->log(print_r($querytrue));
}
?>


They may be tolerated during development time, but must be removed so as not to have any chance to be run in production.

__toString() Throws Exception

[Since 0.8.4] - [ -P Structures/toStringThrowsException ] - [ Online docs ]

Magical method __toString() can't throw exceptions.

In fact, __toString() may not let an exception pass. If it throw an exception, but must catch it. If an underlying method throws an exception, it must be caught.

<?php 
class myString {
    private 
$string null;
    
    public function 
__construct($string) {
        
$this->string $string;
    }
    
    public function 
__toString() {
        
// Do not throw exceptions in __toString
        
if (!is_string($this->string)) {
            throw new 
Exception("$this->string is not a string!!");
        }
        
        return 
$this->string;
    }
}
?>


A fatal error is displayed, when an exception is not intercepted in the __toString() function.

::

PHP Fatal error: Method myString::__toString() must not throw an exception, caught Exception: 'Exception message' in file.php

See also __toString().

Binary Glossary

[Since 0.8.4] - [ -P Type/Binary ] - [ Online docs ] - [ PHP 5.4 and more recent ]

List of all the integer values using the binary format.

<?php 
$a 0b10;
$b 0B0101;
?>

Email Addresses

[Since 0.8.4] - [ -P Type/Email ] - [ Online docs ]

List of all the email addresses that were found in the code.

Emails are detected with regex : [_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})

<?php 
$email 'contact@exakat.io';
?>


Heredoc Delimiter Glossary

[Since 0.8.4] - [ -P Type/Heredoc ] - [ Online docs ]

List of all the delimiters used to build a Heredoc string.

In the example below, EOD is the delimiter.

<?php 
$a = <<<EOD
heredoc
EOD;
?>


See also Heredoc.

Hexadecimal Glossary

[Since 0.8.4] - [ -P Type/Hexadecimal ] - [ Online docs ]

List of all the integer values using the hexadecimal format.

<?php 
$hexadecimal 0x10;

$anotherHexadecimal =0XAF;
?>


See also Integer Syntax.

Http Headers

[Since 0.8.4] - [ -P Type/HttpHeader ] - [ Online docs ]

List of HTTP headers use in the code.

<?php 
header('Location: http://www.example.com/');

// Parseable headers are also reported
header('Location: http://www.example.com/');

// UnParseable headers are not reported
header('GarbagexxxxXXXXxxxGarbagexxxxXXXXxxx');
header($header);
?>


Those headers are mostly used with header() function to send to browser.

See also List of HTTP header fields.

HTTP Status Code

[Since 0.8.4] - [ -P Type/HttpStatus ] - [ Online docs ]

List of all the HTTP status codes mentioned in the code.

<?php 
http_response_code(418);

header('HTTP/1.1 418 I\'m a teapot');
?>


See also List of HTTP status codes.

Malformed Octal

[Since 0.8.4] - [ -P Type/MalformedOctal ] - [ Online docs ] - [ PHP older than 7.0]

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.

See also Integers.

Md5 Strings

[Since 0.8.4] - [ -P Type/Md5String ] - [ Online docs ]

List of all the MD5 values hard coded in the application.

MD5 values are detected as hexadecimal strings, of length 32. No attempt at recognizing the origin value is made, so any such strings, including dummy '11111111111111111111111111111111' are reported.

<?php 
// 32 
   
$a '0cc175b9c0f1b6a831c399e269771111';
?>


See also MD5.

Mime Types

[Since 0.8.4] - [ -P Type/MimeType ] - [ Online docs ]

List of Mime Types that are mentioned in the code.

<?php 
$mimeType 'multipart/form-data';
$mimeType 'image/jpeg';
$mimeType 'application/zip';

header('Content-Type: '.$mimeType);
?>


See also Media Type and
MIME.

Nowdoc Delimiter Glossary

[Since 0.8.4] - [ -P Type/Nowdoc ] - [ Online docs ]

List of all the delimiters used to build a Nowdoc string.

<?php 
$nowdoc = <<<'EOD'

EOD;
?>


See also Nowdoc and
Heredoc.

Octal Glossary

[Since 0.8.4] - [ -P Type/Octal ] - [ Online docs ]

List of all the integer values using the octal format : an integer starting with an initial 0.

<?php 
$a 1234// decimal number
  
$a 0123// octal number (equivalent to 83 decimal)

  // silently valid for PHP 5.x
  
$a 01283// octal number (equivalent to 10 decimal)
?>


Putting an initial 0 is often innocuous, but in PHP, 0755 and 755 are not the same. The second is actually 1363 in octal, and will not provide the expected privileges.

See also Integers.

Perl Regex

[Since 0.8.4] - [ -P Type/Pcre ] - [ Online docs ]

List of all the Perl Regex (Pcre-style).

<?php 
preg_match('/[abc]/'$haystack);

preg_replace('#[0-9A-Z]+#is'$y$z);
?>


Regex are spotted when they are literals : dynamically built regex, (including /$x/) are not reported.

Internet Ports

[Since 0.8.4] - [ -P Type/Ports ] - [ Online docs ]

List of all the Internet ports mentioned in the code.

Ports are recognized based on a internal database of port. They are found in Integers.

<?php 
// 21 is the default port for FTP
$ftp ftp_connect($host21$timeout 90);
?>


See also List of TCP and UDP port numbers.

Special Integers

[Since 0.8.4] - [ -P Type/SpecialIntegers ] - [ Online docs ]

Short and incomplete list of integers that may hold special values.

<?php 
// 86400 is the number of seconds in a day
$day 86400;

// 1400 is the number of minutes in a day
$day 1440;
?>


The list includes powers of 2, duration in various units, factorial, ASCII codes and years.

All strings

[Since 0.10.1] - [ -P Type/CharString ] - [ Online docs ]

Strings and heredocs in one place.

<?php 
$string 'string';

$query = <<<SQL
Heredoc
SQL;
?>


Unicode Blocks

[Since 0.8.4] - [ -P Type/UnicodeBlock ] - [ Online docs ]

List of the Unicode blocks used in string literals.

This is the kind of characters that can be found in the applications strings.

<?php 
$a zoo

$b // Telugu character
$b = \u{0C12}; Same as above

$b 
// Chinese Mandarin character
$b = \u{4EBA}; Same as above?>


Note that Exakat only analyze PHP scripts : any translation available in a .po or external resource is not parsed and will not show.

See also Unicode block.

URL List

[Since 0.8.4] - [ -P Type/Url ] - [ Online docs ]

List of all the URL addresses that were found in the code.

<?php 
// the first argument is recognized as an URL
ftp_connect('http://www.example.com/'$port$timeout);

// the string argument  is recognized as an URL
$source 'https://www.other-example.com/';
?>


References

[Since 0.8.4] - [ -P Variables/References ] - [ Online docs ]

Variables that are references.

<?php 
$a '1'// not a reference
$b = &$a// a reference
?>


See also References.

Static Variables

[Since 0.8.4] - [ -P Variables/StaticVariables ] - [ Online docs ]

In PHP, variables may be static. They will survive after the function execution end, and will be available at the next function run. They are distinct from globals, which are available application wide, and from static properties, which are tied to a class of objects.

<?php 
function foo() {
    
// static variable
    
static $count 0;
    
    echo ++
$count;
}

class 
bar {
    
// This is not a static variable : 
    // it is a static property
    
static $property 1;
}
?>

Variables With Long Names

[Since 0.8.4] - [ -P Variables/VariableLong ] - [ Online docs ]

VariablesLong collect all variables with more than 20 characters longs.

<?php 
// Quite a long variable name
$There_is nothing_wrong_with_long_variable_names_They_tend_to_be_rare_and_that_make_them_noteworthy 1;
?>


There is nothing wrong with long variable names. They tend to be rare, and that make them noteworthy.

See also Basics.

Non Ascii Variables

[Since 0.8.4] - [ -P Variables/VariableNonascii ] - [ Online docs ]

PHP allows certain characters in variable names. 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__;
    }
}

$人民 = new ();
?>


See also Variables.

Used Once Variables

[Since 0.8.4] - [ -P Variables/VariableUsedOnce ] - [ Online docs ]

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.

Variables Variables

[Since 0.8.4] - [ -P Variables/VariableVariables ] - [ Online docs ]

A variable variable takes the value of a variable and treats that as the name of a variable.

PHP has the ability to dynamically use a variable.

<?php 
// Normal variable
$a 'b';
$b 'c';

// Variable variable
$d = $$b;

// Variable variable in string
$d "$\{$b\}";
?>


See also Variable variables.

Abstract Class Usage

[Since 0.8.4] - [ -P Classes/Abstractclass ] - [ Online docs ]

List of all abstract classes being used.

<?php 
abstract class foo {
    function 
foobar(); 
}

class 
bar extends foo {
    
// extended method
    
function foobar() {
        
// doSomething()
    
}

    
// extra method
    
function barbar() {
        
// doSomething()
    
}
}
?>


See also Classes abstraction.

Abstract Methods Usage

[Since 0.8.4] - [ -P Classes/Abstractmethods ] - [ Online docs ]

List of all abstract methods being used.

<?php 
// abstract class
abstract class foo {
    
// abstract method
    
function foobar(); 
}

class 
bar extends foo {
    
// extended abstract method
    
function foobar() {
        
// doSomething()
    
}

    
// extra method
    
function barbar() {
        
// doSomething()
    
}
}
?>


See also Classes abstraction.

Clone Usage

[Since 0.8.4] - [ -P Classes/CloningUsage ] - [ Online docs ]

List of all clone situations.

<?php 
$dateTime = new DateTime();
    echo (clone 
$dateTime)->format('Y');
?>


See also Object cloning.

Final Class Usage

[Since 0.8.4] - [ -P Classes/Finalclass ] - [ Online docs ]

List of all final classes being used.

final may be applied to classes and methods.

<?php 
class BaseClass {
   public function 
test() {
       echo 
'BaseClass::test() called'.PHP_EOL;
   }
   
   final public function 
moreTesting() {
       echo 
'BaseClass::moreTesting() called'.PHP_EOL;
   }
}

class 
ChildClass extends BaseClass {
   public function 
moreTesting() {
       echo 
'ChildClass::moreTesting() called'.PHP_EOL;
   }
}
// Results in Fatal error: Cannot override final method BaseClass::moreTesting()
?>


See also Final Keyword.

Final Methods Usage

[Since 0.8.4] - [ -P Classes/Finalmethod ] - [ Online docs ]

List of all final methods being used.

final may be applied to classes and methods.

<?php 
class BaseClass {
   public function 
test() {
       echo 
'BaseClass::test() called'.PHP_EOL;
   }
   
   final public function 
moreTesting() {
       echo 
'BaseClass::moreTesting() called'.PHP_EOL;
   }
}

class 
ChildClass extends BaseClass {
   public function 
moreTesting() {
       echo 
'ChildClass::moreTesting() called'.PHP_EOL;
   }
}
// Results in Fatal error: Cannot override final method BaseClass::moreTesting()
?>


See also Final Keyword.

Bad Constants Names

[Since 0.8.4] - [ -P Constants/BadConstantnames ] - [ Online docs ]

PHP's manual recommends that developer do not use constants with the convention __NAME__ . Those are reserved for PHP future use.

For example, __TRAIT__ recently appeared in PHP, as a magic constant. In the future, other may appear.

<?php 
const __MY_APP_CONST__ 1;

const 
__MY_APP_CONST__ 1;

define('__MY_OTHER_APP_CONST__'2);
?>


The analyzer will report any constant which name is __.*.__ , or even _.*_ (only one underscore).

See also Constants.

Variable Constants

[Since 0.8.4] - [ -P Constants/VariableConstant ] - [ Online docs ]

Variable constants are actually constants whose value is accessed via the function constant(). Otherwise, there is no way to dynamically access a constant (aka, when the developer has the name of the constant as a incoming parameter, and it requires the value of it).

<?php 
const 'constant_value';

$constant_name 'A';

$variableConstant constant($constant_name);
?>


See also `constant() `_.

Empty Traits

[Since 0.8.4] - [ -P Traits/EmptyTrait ] - [ Online docs ]

List of all empty trait defined in the code.

<?php 
// empty trait
trait { }

// Another empty trait
trait t2 {
    use 
t
}
?>


Such traits may be reserved for future use. They may also be forgotten, and dead code.

Redefined PHP Traits

[Since 0.8.4] - [ -P Traits/Php ] - [ Online docs ]

List of all traits that bears name of a PHP trait. Although, at the moment, there are no PHP trait defined.

Traits Usage

[Since 0.8.4] - [ -P Traits/TraitUsage ] - [ Online docs ]

Usage of traits in the code.

<?php 
trait {
    function 
t() {
        echo 
'I\'m in t';
    }
}

class 
foo {
    use 
t;
}

$x = new foo();
$x->t();
?>


See also Traits.

Trait Names

[Since 0.8.4] - [ -P Traits/Traitnames ] - [ Online docs ]

List all the traits names in the code.

<?php 
// This trait is called 't'
trait {}
?>


See also Traits.

Alternative Syntax

[Since 0.8.4] - [ -P Php/AlternativeSyntax ] - [ Online docs ]

Identify the usage of alternative syntax in the code, for If then, Switch, While, For and Foreach.

<?php 
// Normal syntax
if ($a == 1) { 
    print 
$a;
}

// Alternative syntax : identical to the previous one.
if ($a == 1) : 
    print 
$a;
endif;
?>


See also Alternative syntax.

Short Syntax For Arrays

[Since 0.8.4] - [ -P Arrays/ArrayNSUsage ] - [ Online docs ]

Arrays written with the new 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(123);

// PHP 5.4+ arrays
$a = [123];
?>


See also Array.

Inclusions

[Since 0.8.4] - [ -P Structures/IncludeUsage ] - [ Online docs ]

List of all inclusions. Inclusions are made with include(), include_once(), require() and require_once().

<?php 
include 'library.php';

// display is a function defined in 'library.php';
display('Message');
?>


ext/file

[Since 0.8.4] - [ -P Extensions/Extfile ] - [ Online docs ]

Filesystem functions from standard.

Extension that handle access to file on the file system.

<?php 
$row 1;
if ((
$handle fopen('test.csv''r')) !== FALSE) {
    while ((
$data fgetcsv($handle1000',')) !== FALSE) {
        
$num count($data);
        echo 
'<p> $num fields in line $row: <br /></p>'.PHP_EOL;
        
$row++;
        for (
$c=0$c $num$c++) {
            echo 
$data[$c] . '<br />'.PHP_EOL;
        }
    }
    
fclose($handle);
}
?>


See also filesystem.

Unused Use

[Since 0.8.4] - [ -P Namespaces/UnusedUse ] - [ Online docs ]

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 as B// Used in a new call.
use Unused// Never used. May be removed

$a = new B();
?>


Use With Fully Qualified Name

[Since 0.8.4] - [ -P Namespaces/UseWithFullyQualifiedNS ] - [ Online docs ]

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\as E;

// No need to use the initial \
use \A\B\C\as F;
?>


ext/array

[Since 0.8.4] - [ -P Extensions/Extarray ] - [ Online docs ]

Core functions processing arrays.

These functions manipulate arrays in various ways. Arrays are essential for storing, managing, and operating on sets of variables.

This is not a real extension : it is a documentation section, that helps classifying the functions.

<?php 
function odd($var)
{
    
// returns whether the input integer is odd
    
return($var 1);
}

function 
even($var)
{
    
// returns whether the input integer is even
    
return(!($var 1));
}

$array1 = array('a'=>1'b'=>2'c'=>3'd'=>4'e'=>5);
$array2 = array(6789101112);

echo 
'Odd :'.PHP_EOL;
print_r(array_filter($array1'odd'));
echo 
'Even:'.PHP_EOL;
print_r(array_filter($array2'even'));
?>


See also Arrays.

ext/ffmpeg

[Since 0.8.4] - [ -P Extensions/Extffmpeg ] - [ Online docs ]

Extension ffmpeg for PHP.

ffmpeg-php is an extension for PHP that adds an easy to use, object-oriented API for accessing and retrieving information from video and audio files.

<?php 
$movie = new ffmpeg_movie($path_to_media$persistent);
echo 
'The movie lasts '.$movie->getDuration().' seconds';
?>


See also ffmpeg-php and
FFMPEG.

ext/info

[Since 0.8.4] - [ -P Extensions/Extinfo ] - [ Online docs ]

PHP Options and Information.

These functions enable you to get a lot of information about PHP itself, e.g. runtime configuration, loaded extensions, version and much more.

<?php 
/*
Our php.ini contains the following settings:

display_errors = On
register_globals = Off
post_max_size = 8M
*/

echo 'display_errors = ' ini_get('display_errors') . "\n";
echo 
'register_globals = ' ini_get('register_globals') . "\n";
echo 
'post_max_size = ' ini_get('post_max_size') . "\n";
echo 
'post_max_size+1 = ' . (ini_get('post_max_size')+1) . "\n";
echo 
'post_max_size in bytes = ' return_bytes(ini_get('post_max_size'));

function 
return_bytes($val) {
    
$val trim($val);
    
$last strtolower($val[strlen($val)-1]);
    switch(
$last) {
        
// The 'G' modifier is available since PHP 5.1.0
        
case 'g':
            
$val *= 1024;
        case 
'm':
            
$val *= 1024;
        case 
'k':
            
$val *= 1024;
    }

    return 
$val;
}
?>


See also PHP Options And Information.

ext/math

[Since 0.8.4] - [ -P Extensions/Extmath ] - [ Online docs ]

Core functions that provides math standard functions.

This is not a real extension : it is a documentation section, that helps sorting the functions.

<?php 
echo decbin(12) . PHP_EOL;
echo 
decbin(26);
?>


See also Mathematical Functions.

$HTTP_RAW_POST_DATA Usage

[Since 0.8.4] - [ -P Php/RawPostDataUsage ] - [ Online docs ]

$HTTP_RAW_POST_DATA is deprecated, and should be replaced by php://input .

$HTTP_RAW_POST_DATA is deprecated since PHP 5.6.

It is possible to prepare code to this lack of feature 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);
?>


See also $HTTP_RAW_POST_DATA variable.

ext/yis

[Since 0.8.4] - [ -P Extensions/Extyis ] - [ Online docs ]

Yellow Pages extensions (NIS).

NIS (formerly called Yellow Pages) allows network management of important administrative files (e.g. the password file).

<?php 
$entry yp_first($domain'passwd.byname');

$key key($entry);
$value $entry[$key];

echo 
'First entry in this map has key ' $key ' and value ' $value;
?>


See also The Linux NIS(YP)/NYS/NIS+ HOWTO and YP/NIS.

New Functions In PHP 5.4

[Since 0.8.4] - [ -P Php/Php54NewFunctions ] - [ Online docs ] - [ PHP older than 5.3]

PHP introduced new functions in PHP 5.4. If there are defined functions with such names, there will be a conflict when upgrading. It is advised to change those functions' name.

New Functions In PHP 5.5

[Since 0.8.4] - [ -P Php/Php55NewFunctions ] - [ Online docs ] - [ PHP older than 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.

Useless Instructions

[ -P Structures/UselessInstruction ] - [ Online docs ]

Those instructions are useless, or contains useless parts.

For example, an addition whose result is not stored in a variable, or immediately used, does nothing : it is actually performed, and the result is lost. Just plain lost. In fact, PHP might detect it, and optimize it away.

Here the useless instructions that are spotted :


// Concatenating with an empty string is useless.
$string = 'This part '.$is.' useful but '.$not.'';

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

// 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;
}

// Counting the keys and counting the array is the same.
$c = count(array_keys($array))

//array_keys already provides an array with only unique values, as they were keys in a previous array
$d = array_unique(array_keys($file['messages']))

// No need for assignation inside the ternary operator
$closeQuote = $openQuote[3] ===

Abstract Static Methods

[Since 0.8.4] - [ -P Classes/AbstractStatic ] - [ Online docs ] - [ PHP older than 7.0]

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, it is necessary 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 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 independent.

This is not the case anymore in PHP 7.0+.

<?php 
abstract class foo {
    
// This is not possible
    
static abstract function bar() ;
}
?>


See also Why does PHP 5.2+ disallow abstract static class methods?.

New Functions In PHP 5.6

[Since 0.8.4] - [ -P Php/Php56NewFunctions ] - [ Online docs ] - [ PHP older than 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.

Invalid Constant Name

[Since 0.8.4] - [ -P Constants/InvalidName ] - [ Online docs ]

There is a naming convention for PHP constants names.

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, must follow this regex : /[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/ .

In particular when defined using define() function, no error is produced. When using const , on the other hand, the

<?php 
define('+3'1); // wrong constant! 

echo constant('+3'); // invalid constant access
?>


See also Constants.

Multiple Constant Definition

[Since 0.8.4] - [ -P Constants/MultipleConstantDefinition ] - [ Online docs ]

Some constants are defined several times in your code. This will lead to a fatal error, if they are defined during the same execution.

Multiple definitions may happens at bootstrap, when the application code is collecting information about the current environment. It may also happen at inclusion time, which one set of constant being loaded, while other definition are not, avoiding conflict. Both are false positive.

<?php 
// OS is defined twice. 
if (PHP_OS == 'Windows') {
    
define('OS''Win');
} else {
    
define('OS''Other');
}
?>


Wrong Optional Parameter

[Since 0.8.4] - [ -P Functions/WrongOptionalParameter ] - [ Online docs ]

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 solves 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.

Optional parameter wrongly placed are now a Notice in PHP 8.0. The only previous case that is allowed in PHP 8.0 and also in this analysis, is when the null value is used as default for typed arguments.

See also Function arguments.

Multiple Definition Of The Same Argument

[Since 0.8.4] - [ -P Functions/MultipleSameArguments ] - [ Online docs ] - [ PHP older than 7.0]

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 ($a$a) { print $a; };
  
x(1,2); => display 2

    
// special case with a closure : 
  
function ($a) use ($a) { print $a; };
  
x(1,2); => display 2?>


However, this is not common programming practise : all arguments should be named differently.

See also Prepare for PHP 7 error messages (part 3).

Echo Or Print

[Since 0.8.4] - [ -P Structures/EchoPrintConsistance ] - [ Online docs ]

Echo and print have the same functional use. printf() are also considered in this analysis.

There seems to be a choice that is not enforced : one form is dominant, (> 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

<?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';
?>

Use === null

[Since 0.8.4] - [ -P Php/IsnullVsEqualNull ] - [ Online docs ]

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)) {

}
?>


Constant Comparison

[Since 0.8.4] - [ -P Structures/ConstantComparisonConsistance ] - [ Online docs ]

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 (=== $a) {}

// Compari
if (<= $a) {}
?>

Assertions

[Since 0.8.4] - [ -P Php/AssertionUsage ] - [ Online docs ]

Usage of assertions, to add checks within PHP code.

Assertions should be used as a debugging feature only. You may use them for sanity-checks that test for conditions that should always be TRUE and that indicate some programming errors if not or to check for the presence of certain features like extension functions or certain system limits and features.

<?php 
function foo($string) {
    
assert(!empty($string), 'An empty string was provided!');
    
    echo 
'['.$string.']';
}
?>


See also assert.

$this Is Not An Array

[Since 0.8.4] - [ -P Classes/ThisIsNotAnArray ] - [ Online docs ]

$this variable represents the current object and it is not an array.

This is unless the class (or its parents) has the ArrayAccess interface, or extends ArrayObject or SimpleXMLElement .

<?php 
// $this is an array
class Foo extends ArrayAccess {
    function 
bar() {
        ++
$this[3];
    }
}

// $this is not an array
class Foo2 {
    function 
bar() {
        ++
$this[3];
    }
}
?>


See also ArrayAccess,
ArrayObject and
The Basics.

One Variable String

[Since 0.8.4] - [ -P Type/OneVariableStrings ] - [ Online docs ]

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()}";
?>


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

See also Strings and
Type Juggling.

Cast Usage

[Since 0.8.4] - [ -P Php/CastingUsage ] - [ Online docs ]

List of all cast usage.

PHP does not require (or support) explicit type definition in variable declaration; a variable's type is determined by the context in which the variable is used.

<?php 
if (is_int($_GET['x'])) {
    
$number = (int) $_GET['x'];
} else {
    
error_display('a wrong value was provided for "x"');
}
?>


Until PHP 7.2, a (unset) operator was available. It had the same role as unset() `_ as a function.

See also Type Juggling and
unset.

Function Subscripting

[Since 0.8.4] - [ -P Structures/FunctionSubscripting ] - [ Online docs ] - [ PHP 5.4 and more recent ]

It is possible to use the result of a methodcall directly as an array, without storing the result in a temporary variable.

This works, given that the method actually returns an array.

This syntax was not possible until PHP 5.4. Until then, it was compulsory to store the result in a variable first. Although this is now superfluous, it has been a standard syntax in PHP, and is still being used.

<?php 
function foo() {
    return array(
=> 'a''b''c');
}

echo 
foo()[1]; // displays 'a';

// Function subscripting, the old way
function foo() {
    return array(
=> 'a''b''c');
}

$x foo();
echo 
$x[1]; // displays 'a';
?>


Storing the result in a variable is still useful if the result is actually used more than once.

Nested Loops

[Since 0.8.4] - [ -P Structures/NestedLoops ] - [ Online docs ]

Nested loops happens when a loop (while, do..while, for, foreach), is used inside another loop.

<?php 
// Nested loops
foreach($array as $a) {
    foreach (
$letters as $b) {
        
// This is performed count($array) * count($letters) times. 
        
doSomething();
    }
}
?>


Such structure tends to require a lot of processing, as the size of both loops have to be multiplied to estimate the actual payload. They should be avoided as much as possible. This may no be always possible, though.

Nested loops are worth a check for performances reasons, as they will process a lot of times the same instructions.

[Since 0.8.4] - [ -P Php/EchoTagUsage ] - [ Online docs ]

Usage of the
?>

Static Methods Can't Contain $this

[Since 0.8.4] - [ -P Classes/StaticContainsThis ] - [ Online docs ]

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, which is fixed by removing the static keyword, or replace all $this mention by static properties Class::$property .

See also Static Keyword

Closure May Use $this

[Since 0.8.4] - [ -P Php/ClosureThisSupport ] - [ Online docs ] - [ PHP older than 5.4]

$this is automatically accessible to closures.

When closures 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.

<?php 
// Invalid code in PHP 5.4 and less
class Test
{
    public function 
testing()
    {
        return function() {
            
var_dump($this);
        };
    }
}

$object = new Test;
$function $object->testing();
$function();
?>


This is not the case anymore since PHP 5.4.

See also Anonymous functions.

While(List() = Each())

[Since 0.8.4] - [ -P Structures/WhileListEach ] - [ Online docs ]

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

This structure is deprecated since PHP 7.2. It may disappear in the future.

<?php 
while(list($key$value) = each($array)) {
        
doSomethingWith($key) and $value();
    }

    foreach(
$array as $key => $value) {
        
doSomethingWith($key) and $value();
    }
?>


See also PHP RFC: Deprecations for PHP 7.2 : Each().

Several Instructions On The Same Line

[Since 0.8.4] - [ -P Structures/OneLineTwoInstructions ] - [ Online docs ]

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.

<?php 
switch ($x) {
    
// Is it a fallthrough or not ? 
    
case 1:
        
doSomething(); break;

    
// Easily spotted break.
    
case 1:
        
doSomethingElse(); 
        break;

    default : 
        
doDefault(); 
        break;
}
?>


See also Object Calisthenics, rule # 5.

Multiples Identical Case

[Since 0.8.4] - [ -P Structures/MultipleDefinedCase ] - [ Online docs ]

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 
const 1;

case (
$x) {
    case 

        break;
    case 
true:    // This is a duplicate of the previous
        
break; 
    case 
0:   // This is a duplicate of the previous
        
break; 
    case 
1.0 :    // This is a duplicate of the previous
        
break; 
    case 
:      // The A constant is actually 1
        
break; 
    case 
$y  :    // This is not reported.
        
break; 
    default:
        
}
?>

Switch Without Default

[Since 0.8.4] - [ -P Structures/SwitchWithoutDefault ] - [ Online docs ]

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.

Function Subscripting, Old Style

[Since 0.8.4] - [ -P Structures/FunctionPreSubscripting ] - [ Online docs ] - [ PHP 5.4 and more recent ]

Since PHP 5.4, it is now possible use function results as an array, and access directly its element :

<?php 
function foo() {
    return array(
=> 'a''b''c');
}

echo 
foo()[1]; // displays 'a';

// Function subscripting, the old way
function foo() {
    return array(
=> 'a''b''c');
}

$x foo();
echo 
$x[1]; // displays 'a';
?>


$this Belongs To Classes Or Traits

[Since 0.8.4] - [ -P Classes/ThisIsForClasses ] - [ Online docs ]

$this variable represents the current object, inside a class or trait scope.

It is a pseudo-variable, and should be used within class's or trait's methods and not outside. It should also not be used in static methods.

PHP 7.1 is stricter and check for $this at several situations. 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() <https://www.php.net/extract>`_, `parse_str() <https://www.php.net/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
    
}

}
?>


Nested Ternary

[Since 0.8.4] - [ -P Structures/NestedTernary ] - [ Online docs ]

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 == $b $c) ;

// Nested ternary expressions
echo ($a === $d === $b $d $d === $e $c) ;
echo (
$a === $d === $f ===$g $h $d $d === $e $i === $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;
        }
    }
}
?>


See also Nested Ternaries are Great.

Switch With Too Many Default

[Since 0.8.4] - [ -P Structures/SwitchWithMultipleDefault ] - [ Online docs ] - [ PHP older than 7.0]

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 

        break;
    default : 
        break;
    case 

        break;
    default :  
// This default is never reached
        
break;
}
?>


Non-constant Index In Array

[Since 0.8.4] - [ -P Arrays/NonConstantArray ] - [ Online docs ]

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.

See also PHP RFC: Deprecate and Remove Bareword (Unquoted) Strings and
Syntax.

Undefined Constants

[Since 0.8.4] - [ -P Constants/UndefinedConstants ] - [ Online docs ]

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 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.

See also Constants.

Instantiating Abstract Class

[Since 0.8.4] - [ -P Classes/InstantiatingAbstractClass ] - [ Online docs ]

PHP cannot instantiate an abstract class.

The classes are actually abstract classes, and should be derived into a concrete class to be instantiated.

<?php 
abstract class Foo {
    protected 
$a;
}

class 
Bar extends Foo {
    protected 
$b;
}

// instantiating a concrete class.
new Bar();

// instantiating an abstract class.
// In real life, this is not possible also because the definition and the instantiation are in the same file
new Foo();
?>


See also Class Abstraction.

Classes Mutually Extending Each Other

[Since 0.8.4] - [ -P Classes/MutualExtension ] - [ Online docs ]

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 { }
?>


Class, Interface Or Trait With Identical Names

[Since 0.8.4] - [ -P Classes/CitSameName ] - [ Online docs ]

The following names are used at the same time for classes, interfaces or traits. For example,

<?php 
class a     /* some definitions */ }
    interface 
/* some definitions */ }
    trait 
a     /* some definitions */ }
?>


Even if they are in different namespaces, identical names makes classes easy to confuse. This is often solved by using alias at import time : this leads to more confusion, as a class suddenly changes its name.

Internally, PHP use the same list for all classes, interfaces and traits. As such, it is not allowed to have both a trait and a class with the same name.

In PHP 4, and PHP 5 before namespaces, it was not possible to have classes with the same name. They were simply included after a check.

Empty Try Catch

[Since 0.8.4] - [ -P Structures/EmptyTryCatch ] - [ Online docs ]

The code does try, then catch errors but do no act upon the error.

<?php 
try { 
    
doSomething();
} catch (
Throwable $e) {
    
// 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. They ignore any error and proceed as if nothing happened. At worst, the event should be logged for future analysis.

See also Empty Catch Clause.

ext/pcntl

[Since 0.8.4] - [ -P Extensions/Extpcntl ] - [ Online docs ]

Extension for process control.

Process Control support in PHP implements the Unix style of process creation, program execution, signal handling and process termination. Process Control should not be enabled within a web server environment and unexpected results may happen if any Process Control functions are used within a web server environment.

<?php 
declare(ticks=1);

$pid pcntl_fork();
if (
$pid == -1) {
     die(
'could not fork'); 
} else if (
$pid) {
     exit(); 
// we are the parent 
} else {
     
// we are the child
}

// detatch from the controlling terminal
if (posix_setsid() == -1) {
    die(
'could not detach from terminal');
}

// setup signal handlers
pcntl_signal(SIGTERM'sig_handler');
pcntl_signal(SIGHUP'sig_handler');

// loop forever performing tasks
while (1) {

    
// do something interesting here

}

function 
sig_handler($signo
{

     switch (
$signo) {
         case 
SIGTERM:
             
// handle shutdown tasks
             
exit;
             break;
         case 
SIGHUP:
             
// handle restart tasks
             
break;
         default:
             
// handle all other signals
     
}

}
?>


See also Process Control.

Undefined Classes

[Since 0.8.4] - [ -P Classes/UndefinedClasses ] - [ Online docs ]

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();
}
?>


ext/ming

[Since 0.8.4] - [ -P Extensions/Extming ] - [ Online docs ]

Extension ext/ming, to create swf files with PHP.

Ming is an open-source (LGPL) library which allows you to create SWF ('Flash') format movies.

<?php 
$s = new SWFShape();
  
$f $s->addFill(0xff00);
  
$s->setRightFill($f);

  
$s->movePenTo(-500, -500);
  
$s->drawLineTo(500, -500);
  
$s->drawLineTo(500500);
  
$s->drawLineTo(-500500);
  
$s->drawLineTo(-500, -500);

  
$p = new SWFSprite();
  
$i $p->add($s);
  
$i->setDepth(1);
  
$p->nextFrame();

  for (
$n=0$n<5; ++$n) {
    
$i->rotate(-15);
    
$p->nextFrame();
  }

  
$m = new SWFMovie();
  
$m->setBackground(0xff0xff0xff);
  
$m->setDimension(60004000);

  
$i $m->add($p);
  
$i->setDepth(1);
  
$i->moveTo(-500,2000);
  
$i->setName('box');

  
$m->add(new SWFAction('/box.x += 3;'));
  
$m->nextFrame();
  
$m->add(new SWFAction('gotoFrame(0); play();'));
  
$m->nextFrame();

  
header('Content-type: application/x-shockwave-flash');
  
$m->output();
?>


See also Ming (flash) and Ming.

ext/redis

[Since 0.8.4] - [ -P Extensions/Extredis ] - [ Online docs ]

Extension ext/redis.

The phpredis extension provides an API for communicating with the Redis key-value store.

<?php 
$redis = new Redis();
$redis->connect('127.0.0.1'6379);

$redis->setOption(Redis::OPT_SERIALIZERRedis::SERIALIZER_NONE);    // don't serialize data
$redis->setOption(Redis::OPT_SERIALIZERRedis::SERIALIZER_PHP);    // use built-in serialize/unserialize
$redis->setOption(Redis::OPT_SERIALIZERRedis::SERIALIZER_IGBINARY);    // use igBinary serialize/unserialize

$redis->setOption(Redis::OPT_PREFIX'myAppName:');    // use custom prefix on all keys

/* Options for the SCAN family of commands, indicating whether to abstract
   empty results from the user.  If set to SCAN_NORETRY (the default), phpredis
   will just issue one SCAN command at a time, sometimes returning an empty
   array of results.  If set to SCAN_RETRY, phpredis will retry the scan command
   until keys come back OR Redis returns an iterator of zero
*/
$redis->setOption(Redis::OPT_SCANRedis::SCAN_NORETRY);
$redis->setOption(Redis::OPT_SCANRedis::SCAN_RETRY);
?>


See also A PHP extension for Redis and Redis.

Htmlentities Calls

[Since 0.8.4] - [ -P Structures/Htmlentitiescall ] - [ Online docs ]

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 HTML 4 or 5, etc. It is highly recommended to set it explicitly.

The third argument of the functions is the encoding of the string. In PHP 5.3, it is 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.

<?php 
$str 'A quote is <b>bold</b>';

// Outputs, without depending on the php.ini: A &#039;quote&#039; is &lt;b&gt;bold&lt;/b&gt; 
echo htmlentities($strENT_QUOTES'UTF-8');

// Outputs, while depending on the php.ini: A quote is &lt;b&gt;bold&lt;/b&gt;
echo htmlentities($str);
?>


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.

See also htmlentities and htmlspecialchars.

Undefined Class Constants

[Since 0.8.4] - [ -P Classes/UndefinedConstants ] - [ Online docs ]

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 
1;
    
define('B'2);
}

// here, C is not defined in the code and is reported
echo foo::A.foo::B.foo::C;
?>

Unused Private Properties

[Since 0.8.4] - [ -P Classes/UnusedPrivateProperty ] - [ Online docs ]

Unused static properties should be removed.

Unused private properties are dead code. They are usually leftovers of development or refactorisation : they used to have a mission, but are now left.

Being private, those properties are only accessible to the current class or trait. As such, validating the

<?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;
    }
}
?>


Unused Private Methods

[Since 0.8.4] - [ -P Classes/UnusedPrivateMethod ] - [ Online docs ]

Private methods that are not used are dead code.

Private methods are reserved for the defining class. Thus, they must be used with the current class, with $this or self:: .

Protected methods, in a standalone class, are also included.


<?php 
class Foo {
    
// Those methods are used
    
private function method() {}
    private static function 
staticMethod() {}

    
// Those methods are not used
    
private function unusedMethod() {}
    private static function 
staticUnusedMethod() {}
    
    public function 
bar() {
        
self::staticMethod();
        
$this->method();
    }
}
?>


This analysis skips classes that makes self dynamic calls, such as $this->$method() .

Unused Functions

[Since 0.8.4] - [ -P Functions/UnusedFunctions ] - [ Online docs ]

The functions below are unused. They look like dead code.

Recursive functions, level 1, are detected : they are only reported when a call from outside the function is made. Recursive functions calls of higher level (A calls B calls A) are not handled.

<?php 
function used() {}
// The 'unused' function is defined but never called
function unused() {}

// The 'used' function is called at least once
used();
?>


Used Once Variables (In Scope)

[Since 0.8.4] - [ -P Variables/VariableUsedOnceByContext ] - [ Online docs ]

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);
}
?>


Undefined Functions

[Since 0.8.4] - [ -P Functions/UndefinedFunctions ] - [ Online docs ]

Some functions are called, but 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();
?>


See also Functions.

Deprecated Functions

[Since 0.8.4] - [ -P Php/Deprecated ] - [ Online docs ]

The following functions are deprecated. It is recommended to stop using them now and replace them with a durable equivalent.

Note that these functions may be still usable : they generate warning that help tracking their usage in the log. To eradicate their usage, watch the logs, and update any deprecated warning. This way, the code won't be stuck when the function is actually removed from PHP.

<?php 
// This is the current function
list($day$month$year) = explode('/''08/06/1995');

// This is deprecated
list($day$month$year) = split('/''08/06/1995');
?>


crypt() Without Salt

[Since 0.8.4] - [ -P Structures/CryptWithoutSalt ] - [ Online docs ] - [ PHP older than 5.6]

PHP requires a salt when calling crypt(). 5.5 and previous versions didn't require it. Salt is a simple string, that is usually only known by the application.

According to the manual : The salt parameter is optional. However, crypt() creates a weak hash without the salt. PHP 5.6 or later raise an E_NOTICE error without it. Make sure to specify a strong enough salt for better security.

<?php 
// Set the password
$password 'mypassword';

// salted crypt usage (always valid)
$hash crypt($password'123salt');

// Get the hash, letting the salt be automatically generated
// This generates a notice after PHP 5.6
$hash crypt($password);
?>


See also crypt.

mcrypt_create_iv() With Default Values

[Since 0.8.4] - [ -P Structures/McryptcreateivWithoutOption ] - [ Online docs ] - [ PHP older than 5.6]

Avoid using mcrypt_create_iv() default values.

mcrypt_create_iv() used to have MCRYPT_DEV_RANDOM as default values, and in PHP 5.6, it now uses MCRYPT_DEV_URANDOM .

<?php 
$size mcrypt_get_iv_size(MCRYPT_CAST_256MCRYPT_MODE_CFB);
    
// mcrypt_create_iv is missing the second argument
    
$iv mcrypt_create_iv($size);

// Identical to the line below
//    $iv = mcrypt_create_iv($size, MCRYPT_DEV_RANDOM);
?>


If the code doesn't have a second argument, it relies on the default value. It is recommended to set explicitly the value, so has to avoid problems while migrating.

See also mcrypt_create_iv().

Dangling Array References

[Since 0.8.4] - [ -P Structures/DanglingArrayReferences ] - [ Online docs ]

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)
// $a is already a reference, even if it doesn't show here.
foreach($array as $a) {}
//$array === array(3,4,5,5);
?>


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,
PHP foreach pass-by-reference: Do it right, or better not at all,
How does PHP 'foreach' actually work?,
References and foreach.

ext/cyrus

[Since 0.8.4] - [ -P Extensions/Extcyrus ] - [ Online docs ]

Extension ext/cyrus.

The Cyrus IMAP server is electronic mail server software developed by Carnegie Mellon University.

<?php 
$connexion cyrus_connect ('localhost');
?>


See also Cyrus and Cyrus IMAP server.

ext/sqlsrv

[Since 0.8.4] - [ -P Extensions/Extsqlsrv ] - [ Online docs ]

Extension for Microsoft SQL Server Driver.

The SQLSRV extension allows you to access Microsoft SQL Server and SQL Azure databases when running PHP on Windows.

<?php 
$serverName 'serverName\sqlexpress';
$connectionInfo = array( 'Database'=>'dbName''UID'=>'username''PWD'=>'password' );
$conn sqlsrv_connect$serverName$connectionInfo);
if( 
$conn === false ) {
     die( 
print_rsqlsrv_errors(), true));
}

$sql 'INSERT INTO Table_1 (id, data) VALUES (?, ?)';
$params = array(1'some data');

$stmt sqlsrv_query$conn$sql$params);
if( 
$stmt === false ) {
     die( 
print_rsqlsrv_errors(), true));
}
?>


See also Microsoft SQL Server Driver and PHP Driver for SQL Server Support for LocalDB.

Queries In Loops

[Since 0.8.4] - [ -P Structures/QueriesInLoop ] - [ Online docs ]

Avoid querying databases in a loop.

Querying an external database in a loop usually leads to performances problems. This is also called the 'n + 1 problem'.

This problem applies also to prepared statement : when such statement are called in a loop, they are slower than one-time large queries.

It is recommended to reduce the number of queries by making one query, and dispatching the results afterwards. This is true with SQL databases, graph queries, LDAP queries, etc.

<?php 
// Typical N = 1 problem : there will be as many queries as there are elements in $array
$ids = array(1,2,3,5,6,10);

$db = new SQLite3('mysqlitedb.db');

// all the IDS are merged into the query at once
$results $db->query('SELECT bar FROM foo WHERE id  in ('.implode(','$id).')');
while (
$row $results->fetchArray()) {
    
var_dump($row);
}


// Typical N = 1 problem : there will be as many queries as there are elements in $array
$ids = array(1,2,3,5,6,10);

$db = new SQLite3('mysqlitedb.db');

foreach(
$ids as $id) {
    
$results $db->query('SELECT bar FROM foo WHERE id = '.$id);
    while (
$row $results->fetchArray()) {
        
var_dump($row);
    }
}
?>


This optimisation is not always possible : for example, some SQL queries may not be prepared, like DROP TABLE or DESC . UPDATE commands often update one row at a time, and grouping such queries may be counter-productive or unsafe.

Var Keyword

[Since 0.8.4] - [ -P Classes/OldStyleVar ] - [ Online docs ]

Var was used in PHP 4 to mark properties as public. Nowadays, new keywords are available : public, protected, private. Var is equivalent to public.

It is recommended to avoid using var, and explicitly use the new keywords.

<?php 
class foo {
    public 
$bar 1;
    
// Avoid var
    //var $bar = 1; 
}
?>


See also Visibility.

Aliases Usage

[Since 0.8.4] - [ -P Functions/AliasesUsage ] - [ Online docs ]

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.

Uses Default Values

[Since 0.8.4] - [ -P Functions/UsesDefaultArguments ] - [ Online docs ]

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.

Wrong Number Of Arguments

[Since 0.8.4] - [ -P Functions/WrongNumberOfArguments ] - [ Online docs ]

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 high 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() <https://www.php.net/strtoupper>`_ expects exactly 1 parameter, 2 given in Command line code on line 1

echo `strtoupper() <https://www.php.net/strtoupper>`_;
//Warning: `strtoupper() <https://www.php.net/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.

Hardcoded Passwords

[Since 0.8.4] - [ -P Functions/HardcodedPasswords ] - [ Online docs ]

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';   // yes, this doesn't exists, it's an example
$conn_id ftp_connect($ftp_server); 

// login with username and password
$login_result ftp_login($conn_id'login''password');
?>


See also 10 GitHub Security Best Practices and
Git How-To: Remove Your Password from a Repository.

Unresolved Classes

[Since 0.8.4] - [ -P Classes/UnresolvedClasses ] - [ Online docs ]

The following classes are instantiated in the code, but their definition couldn't be found.

<?php 
class Foo extends Bar {
    private function 
foobar() {
        
// here, parent is not resolved, as Bar is not defined in the code.
        
return parent::$prop;
    }
}
?>


Ellipsis Usage

[Since 0.8.4] - [ -P Php/EllipsisUsage ] - [ Online docs ] - [ PHP 5.6 and more recent ]

Usage of the ellipsis keyword. The keyword is three dots : ... . It is also named variadic or splat operator.

It may be in function definitions, either in functioncalls.

... allows for packing or unpacking arguments into an array.

<?php 
$args = [123];
foo(...$args); 
// Identical to foo(1,2,3);

function bar(...$a) {
    
// Identical to : $a = `func_get_args() <https://www.php.net/func_get_args>`_;
}
?>


See also PHP RFC: Syntax for variadic functions,
PHP 5.6 and the Splat Operator, and
Variable-length argument lists.

Exponent Usage

[Since 0.8.4] - [ -P Php/ExponentUsage ] - [ Online docs ] - [ PHP 5.6 and more recent ]

Usage of the ** operator or **=, to make exponents.

<?php 
$eight ** 3;

$sixteen 4;
$sixteen **= 2;
?>


See also Arithmetic Operators.

** For Exponent

[Since 0.8.4] - [ -P Php/NewExponent ] - [ Online docs ] - [ PHP 5.6 and more recent ]

The operator ** calculates exponents, also known as power.

Use it instead of the slower function pow(). This operator was introduced in PHP 5.6.

<?php 
$cube pow(23); // 8

    
$cubeInPHP56 ** 3// 8
?>


If the code needs to be backward compatible to 5.5 or less, don't use the new operator.

Be aware the the '-' operator has lower priority than the ** operator : this leads to the following confusing result.

<?php 
echo -** 2;
    
// displays -9, instead of 9
?>


This is due to the parser that processes separately - and the following number. Since ** has priority, the power operation happens first.

Being an operator, ** is faster than pow(). This is a microoptimisation.

See also Arithmetic Operators.

Useless Constructor

[Since 0.8.4] - [ -P Classes/UselessConstructor ] - [ Online docs ]

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

<?php 
class {
    function 
__construct() {
        
// Do nothing
    
}
}

class 
extends {
    
// Useful constructor, as it prevents usage of the parent
    
function __construct() {
        
// Do nothing
    
}
}
?>

Too Many Children

[Since 0.8.4] - [ -P Classes/TooManyChildren ] - [ Online docs ]

Classes that have more than 15 children. It is worth checking if they cannot be refactored in anyway.

The threshold of 15 children can be configured. There is no technical limitation of the number of children and grand-children for a class.

The analysis doesn't work recursively : only direct generations are counted. Only children that can be found in the code are counted.

<?php 
// parent class
// calling it grandparent to avoid confusion with 'parent'
class grandparent {}


class 
children1 extends grandparent {}
class 
children2 extends grandparent {}
class 
children3 extends grandparent {}
class 
children4 extends grandparent {}
class 
children5 extends grandparent {}
class 
children6 extends grandparent {}
class 
children7 extends grandparent {}
class 
children8 extends grandparent {}
class 
children9 extends grandparent {}
class 
children11 extends grandparent {}
class 
children12 extends grandparent {}
class 
children13 extends grandparent {}
class 
children14 extends grandparent {}
class 
children15 extends grandparent {}
class 
children16 extends grandparent {}
class 
children17 extends grandparent {}
class 
children18 extends grandparent {}
class 
children19 extends grandparent {}
?>


See also Why is subclassing too much bad (and hence why should we use prototypes to do away with it)?.

Implement Is For Interface

[Since 0.8.4] - [ -P Classes/ImplementIsForInterface ] - [ Online docs ]

With class heritage, implements should be used for interfaces, and extends with classes.

PHP defers the implements check until execution : the code in example does lint, but won,t run.

<?php 
class {
    function 
foo() {}
}

interface 
{
    function 
foo();
}

// Use implements with an interface
class implements {}

// Implements is for an interface, not a class
class implements {}
?>

Use const

[Since 0.8.4] - [ -P Constants/ConstRecommended ] - [ Online docs ]

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 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'1true);
  echo 
b;
?>


See also Syntax.

Unresolved Use

[Since 0.8.4] - [ -P Namespaces/UnresolvedUse ] - [ Online docs ]

The following use instructions cannot be resolved to a class or a namespace. They should be dropped or fixed.

<?php 
namespace {
    
// class B is defined
    
class {}
    
// class C is not defined
}

namespace 
X/{

    use 
A/B;  // This use is valid
    
use A/C;  // This use point to nothing.

    
new B();
    new 
C();
}
?>


Use expression are options for the current namespace.

See also Using namespaces: Aliasing/Importing.

Unused Constants

[Since 0.8.4] - [ -P Constants/UnusedConstants ] - [ Online docs ]

Those constants are defined in the code but never used. Defining unused constants slow down the application, as they are executed and stored in PHP hashtables.

<?php 
// const-defined constant
const USED_CONSTANT  0;
const 
UNUSED_CONSTANT USED_CONSTANT;

// define-defined constant
define('ANOTHER_UNUSED_CONSTANT'3);
?>


It is recommended to comment them out, and only define them when it is necessary.

Undefined Parent

[Since 0.8.4] - [ -P Classes/UndefinedParentMP ] - [ Online docs ]

List of properties and methods that are accessed using parent keyword but are not defined in the parent classes.

This may compile but, eventually yields a fatal error during execution.

<?php 
class theParent {
    
// No bar() method
    // private bar() method is not accessible to theChild 
}

class 
theChild extends theParent {
    function 
foo() {
        
// bar is defined in theChild, but not theParent
        
parent::bar();
    }
    
    function 
bar() {
    
    }
}
?>


Note that if the parent is defined using extends someClass but someClass is not available in the tested code, it will not be reported : it may be in composer, another dependency, or just missing.

See also parent.

Undefined static:: Or self::

[Since 0.8.4] - [ -P Classes/UndefinedStaticMP ] - [ Online docs ]

self and static refer to the current class, or one of its parent. The property or the method may be undefined.

<?php 
class {
    static public function 
definedStatic() {}
    private 
definedStatic 1;
    
    public function 
method() {
        
self::definedStatic();
        
self::undefinedStatic();

        static::
definedStatic;
        static::
undefinedStatic;
    }
}
?>


See also Late Static Bindings.

Accessing Private

[Since 0.8.4] - [ -P Classes/AccessPrivate ] - [ Online docs ]

List of calls to private properties/methods that will compile but yield some fatal error upon execution.

<?php 
class {
    private 
$a;
}

class 
extends {
    function 
c() {
        
$this->a;
    }
}
?>

Access Protected Structures

[Since 0.8.4] - [ -P Classes/AccessProtected ] - [ Online docs ]

It is not allowed to access protected properties or methods from outside the class or its relatives.

<?php 
class foo {
    protected 
$bar 1;
}

$foo = new Foo();
$foo->bar 2;
?>


Parent, Static Or Self Outside Class

[Since 0.8.4] - [ -P Classes/PssWithoutClass ] - [ Online docs ]

Parent, static and self keywords must be used within a class or a trait. They make no sens outside a class or trait scope, as self and static refers to the current class and parent refers to one of parent above.

PHP 7.0 and later detect their usage at compile time, and emits a fatal error.

<?php 
class {
    const 
1;
    
    function 
foo() {
        
// self is \x
        
echo self::Y;
    }
}

const 
1;
// This doesn't compile anymore
echo self::Z;
?>


Static may be used in a function or a closure, but not globally.

ext/0mq

[Since 0.8.4] - [ -P Extensions/Extzmq ] - [ Online docs ]

Extension ext/zmq for 0mq .

ØMQ is a software library that lets you quickly design and implement a fast message-based application.

<?php 
// Example from https://github.com/kuying/ZeroMQ/blob/d80dcc3dc1c14a343ca90bbd656b98fd55366548/zguide/examples/PHP/msgqueue.php
    /*
     *  Simple message queuing broker
     *  Same as request-reply broker but using QUEUE device
     * @author Ian Barber <ian(dot)barber(at)gmail(dot)com>
     */
    
$context = new ZMQContext();
    
//  Socket facing clients
    
$frontend $context->getSocket(ZMQ::SOCKET_ROUTER);
    
$frontend->bind(tcp://*:5559);
    //  Socket facing services
    
$backend $context->getSocket(ZMQ::SOCKET_DEALER);
    
$backend->bind(tcp://*:5560);
    //  Start built-in device
    
new ZMQDevice($frontend$backend);
?>


See also ZeroMQ and ZMQ.

ext/memcache

[Since 0.8.4] - [ -P Extensions/Extmemcache ] - [ Online docs ]

Extension Memcache.

Memcache module provides handy procedural and object oriented interface to memcached, highly effective caching daemon, which was especially designed to decrease database load in dynamic web applications.

<?php 
$memcache = new Memcache;
$memcache->connect('localhost'11211) or die ('Could not connect');

$version $memcache->getVersion();
echo 
'Server\'s version: '.$version.'<br/>';

$tmp_object = new stdClass;
$tmp_object->str_attr 'test';
$tmp_object->int_attr 123;

$memcache->set('key'$tmp_objectfalse10) or die ('Failed to save data at the server');
echo 
'Store data in the cache (data will expire in 10 seconds)<br/>';

$get_result $memcache->get('key');
echo 
'Data from the cache:<br/>';

var_dump($get_result);
?>


See also Memcache on PHP and memcached.

ext/memcached

[Since 0.8.4] - [ -P Extensions/Extmemcached ] - [ Online docs ]

Extension Memcached.

This extension uses the libmemcached library to provide an API for communicating with memcached servers. It also provides a session handler (memcached).

<?php 
$m = new Memcached();
$m->addServer('localhost'11211);

$m->set('foo'100);
var_dump($m->get('foo'));
?>


See also ext/memcached manual and
memcached.

Dynamic Function Call

[Since 0.8.4] - [ -P Functions/Dynamiccall ] - [ Online docs ]

Mark a functioncall made with a variable name.

<?php 
// function definition
function foo() {}

// function name is in a variable, as a string.
$var 'foo'

// dynamic call of a function
$var();

call_user_func($var);
?>


Has Variable Arguments

[Since 0.8.4] - [ -P Functions/VariableArguments ] - [ Online docs ]

Indicates if this function or method accept an arbitrary number of arguments, based on ... or func_get_args() usage.

<?php 
// Variables number of arguments
function fixedNumberOfArguments($a$b, ...$c) {}

// Fixed number of arguments
function fixedNumberOfArguments($a$b) {
    if (`
func_num_args() <https://www.php.net/func_num_args>`2) {
        
$c = `func_get_args() <https://www.php.net/func_get_args>`_;
        
array_shift($c); // $a
        
array_shift($c); // $b
    
}
    
// do something
}

// Fixed number of arguments
function fixedNumberOfArguments($a$b$c 1) {}
?>


Multiple Catch

[Since 0.8.4] - [ -P Structures/MultipleCatch ] - [ Online docs ]

Indicates if a try structure have several catch statement.

<?php 
// This try has several catch
try {
    
doSomething();
} catch (
RuntimeException $e) {
    
processRuntimeException();
} catch (
OtherException $e) {
    
processOtherException();
}
?>

Dynamically Called Classes

[Since 0.8.4] - [ -P Classes/VariableClasses ] - [ Online docs ]

Indicates if a class is called dynamically.

<?php 
// This class is called dynamically
class {
    const 
CONSTANTE 1;
}

$classe 'X';

$x = new $classe();

echo 
$x::CONSTANTE;
?>


Conditioned Function

[Since 0.8.4] - [ -P Functions/ConditionedFunctions ] - [ Online docs ]

Indicates if a function is defined only if a condition is met.


// This is a conditioned function.
// it only exists if the PHP binary doesn't have it already.
if (!function_exists('join')) {
function join($glue, $array) {
return implode($glue, $array);
}

}

Conditioned Constants

[Since 0.8.4] - [ -P Constants/ConditionedConstants ] - [ Online docs ]

Indicates if a constant will be defined only if a condition is met.

<?php 
if (time() > 1519629617) {
    
define('MY_CONST'false);
} else {
    
define('MY_CONST'time() - 1519629617);
}
?>

Is Generator

[Since 0.8.4] - [ -P Functions/IsGenerator ] - [ Online docs ]

Mark as such functions or methods that are using yield and yield from.

<?php 
function generator() {
    yield from 
generator2();
    
    return 
3;
}

function 
generator2() {
    yield 
1;
    yield 
2;
}
?>

Try With Finally

[Since 0.8.4] - [ -P Structures/TryFinally ] - [ Online docs ] - [ PHP 5.5 and more recent ]

Indicates if a try use a finally statement.

<?php 
try {
    
$a doSomething();
} catch (
Throwable $e) {
    
// Fix the problem
} finally {
    
// remove $a anyway
    
unset($a);
}
?>


See also Exceptions, to learn about catching an exception.

Use password_hash()

[Since 0.8.4] - [ -P Php/Password55 ] - [ Online docs ] - [ PHP 5.5 and more recent ]

password_hash() and password_check() are a better choice to replace the use of crypt() to check password.

PHP 5.5 introduced these functions.

<?php 
$password 'rasmuslerdorf';
$hash '$2y$10$YCFsG6elYca568hBi2pZ0.3LDL5wjgxct1N8w/oLR/jfHsiQwCqTS';

// The cost parameter can change over time as hardware improves
$options = array('cost' => 11);

// Verify stored hash against plain-text password
if (password_verify($password$hash)) {
    
// Check if a newer hashing algorithm is available
    // or the cost has changed
    
if (password_needs_rehash($hashPASSWORD_DEFAULT$options)) {
        
// If so, create a new hash, and replace the old one
        
$newHash password_hash($passwordPASSWORD_DEFAULT$options);
    }

    
// Log user in
}
?>


See also Password hashing.

Dereferencing String And Arrays

[Since 0.8.4] - [ -P Structures/DereferencingAS ] - [ Online docs ] - [ PHP older than 5.3]

PHP allows the direct dereferencing of strings and arrays.

This was added in PHP 5.5. There is no need anymore for an intermediate variable between a string and array (or any expression generating such value) and accessing an index.

<?php 
$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];
?>


::class

[Since 0.8.4] - [ -P Php/StaticclassUsage ] - [ Online docs ] - [ PHP 5.5 and more recent ]

PHP has a special class constant to hold the name of the class : class keyword. It represents the class name that is used in the left part of the operator.

Using ::class is safer than relying on a string. It does adapt if the class's name or its namespace is changed'. It is also faster, though it is a micro-optimisation.

It is introduced in PHP 5.5.

<?php 
use A\B\as UsedName;

class 
foo {
    public function 
bar( ) {
        echo 
ClassName::class; 
        echo 
UsedName::class; 
    }
}

$f = new Foo( );
$f->bar( );
// displays ClassName 
// displays A\B\C
?>


Be aware that ::class is a replacement for __CLASS__ magic constant.

See also Class Constant.

Foreach With list()

[Since 0.8.4] - [ -P Structures/ForeachWithList ] - [ Online docs ] - [ PHP 5.5 and more recent ]

Foreach loops have the ability to use list as blind variables. This syntax assign directly array elements to various variables.

PHP 5.5 introduced the usage of list in foreach() loops. Until PHP 7.1, it was not possible to use non-numerical arrays as list() wouldn't support string-indexed arrays.

<?php 
// PHP 5.5 and later, with numerically-indexed arrays
    
foreach($array as list($a$b)) { 
        
// do something 
    
}


    
// PHP 7.1 and later, with arrays
    
foreach($array as list('col1' => $a'col3' => $b)) { // 'col2 is ignored'
        // 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 
    
}
?>


See also The list function & practical uses of array destructuring in PHP.

Empty With Expression

[Since 0.8.4] - [ -P Structures/EmptyWithExpression ] - [ Online docs ] - [ PHP 5.5 and more recent ]

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() <https://www.php.net/empty>`_ usage
if (empty(strtolower($b $c))) {
    
doSomethingWithoutA();
}

// Compatible `empty() <https://www.php.net/empty>`_ usage
$a strtolower($b $c);
if (empty(
$a)) {
    
doSomethingWithoutA();
}
?>


See also empty.

list() May Omit Variables

[Since 0.8.4] - [ -P Structures/ListOmissions ] - [ Online docs ]

Simply omit any unused variable in a list() call.

list() is the only PHP function that accepts to have omitted arguments. If the following code makes no usage of a listed variable, just omit it.

<?php 
// No need for '2', so no assignation
    
list ($a, , $b) = array(123);
        
// works with PHP 7.1 short syntax
         
[$a, , $b] = array(123);

    
// No need for '2', so no assignation
    
list ($a$c$b) = array(123);
?>


See also list.

Or Die

[Since 0.8.4] - [ -P Structures/OrDie ] - [ Online docs ]

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.

See also pg_last_error or
PDO::exec.

Use Const And Functions

[Since 0.8.4] - [ -P Namespaces/UseFunctionsConstants ] - [ Online docs ] - [ PHP 5.6 and more recent ]

Since PHP 5.6 it is possible to import specific functions or constants from other namespaces.

<?php 
namespace {
    const 
1;
    function 
foo() { echo __FUNCTION__; }
}

namespace 
My{
    use function 
A\foo;
    use 
constant A\X;

    echo 
foo(X);
}
?>


See also Using namespaces: Aliasing/Importing.

Constant Scalar Expressions

[Since 0.8.4] - [ -P Structures/ConstantScalarExpression ] - [ Online docs ] - [ PHP 5.6 and more recent ]

Define constant with the result of static expressions. This means that constants may be defined with the const keyword, with the help of various operators but without any functioncalls.

This feature was introduced in PHP 5.6. It also supports array(), and expressions in arrays.

Those expressions (using simple operators) may only manipulate other constants, and all values must be known at compile time.

<?php 
// simple definition
const 1;

// constant scalar expression
const 3;

// constant scalar expression
const = [** 3'3' => B];
?>


See also Constant Scalar Expressions.

Unreachable Code

[Since 0.8.4] - [ -P Structures/UnreachableCode ] - [ Online docs ]

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.

Written Only Variables

[Since 0.8.4] - [ -P Variables/WrittenOnlyVariable ] - [ Online docs ]

Those variables are being written, but never read. This way, they are useless and should be removed, or read at some point.

<?php 
// $a is used multiple times, but never read
$a 'a';
$a .= 'b';

$b 3
//$b is actually read once
$a .= $b 3;
?>

Must Return Methods

[Since 0.8.4] - [ -P Functions/MustReturn ] - [ Online docs ]

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
    
}

}
?>



__debugInfo() Usage

[Since 0.8.4] - [ -P Php/debugInfoUsage ] - [ Online docs ] - [ PHP 5.6 and more recent ]

The magic method __debugInfo() provides a custom way to dump an object.

It has been introduced in PHP 5.6. In the previous versions of PHP, this method is ignored and won't be called when debugging.

<?php 
// PHP 5.6 or later
class foo {
    private 
$bar 1;
    private 
$reallyHidden 2;
    
    function 
__debugInfo() {
        return [
'bar' => $this->bar,
                
'reallyHidden' => 'Secret'];
    }
}

$f = new Foo();
var_dump($f);

/* Displays : 
object(foo)#1 (2) {
  [bar]=>
  int(1)
  [reallyHidden]=>
  string(6) Secret
}
*/
?>


See also Magic methods.

Empty Instructions

[Since 0.8.4] - [ -P Structures/EmptyLines ] - [ Online docs ]

Empty instructions are part of the code that have no instructions.

This may be trailing semi-colon or empty blocks for if-then structures.

Comments that explains the reason of the situation are not taken into account.

<?php 
$condition 3;;;;
    if (
$condition) { }
?>


Mixed Keys Arrays

[Since 0.8.4] - [ -P Arrays/MixedKeys ] - [ Online docs ] - [ PHP 5.6 and more recent ]

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 hold the expected data. If not, reorder the definitions.

<?php 
const ONE 1;

$a = [ 1   => 2,
       
ONE => 3];
?>

ext/imagick

[Since 0.8.4] - [ -P Extensions/Extimagick ] - [ Online docs ]

Extension Imagick for PHP.

Imagick is a native php extension to create and modify images using the ImageMagick API.

<?php 
header('Content-type: image/jpeg');

$image = new Imagick('image.jpg');

// If 0 is provided as a width or height parameter,
// aspect ratio is maintained
$image->thumbnailImage(1000);

echo 
$image;
?>


See also Imagick for PHP and Imagick.

Unused Methods

[Since 0.8.4] - [ -P Classes/UnusedMethods ] - [ Online docs ]

Those methods are never called.

They are probably dead code, unless they are called dynamically.

This analysis omits methods which are in a class that makes dynamical self calls : $this->$m() . That way, any method may be called.

This analysis omits methods which are overwritten by a child class. That way, they are considered to provide a default behavior.

<?php 
class foo {
    public function 
used() {
        
$this->used();
    }

    public function 
unused() {
        
$this->used();
    }
}

class 
bar extends foo {
    public function 
some() {
        
$this->used();
    }
}

$a = new foo();
$a->used();
?>


See also Dead Code: Unused Method.

ext/oci8

[Since 0.8.4] - [ -P Extensions/Extoci8 ] - [ Online docs ]

Extension ext/oci8.

OCI8 gives access Oracle Database 12c, 11g, 10g, 9i and 8i.

<?php 
$conn oci_connect('hr''welcome''localhost/XE');
if (!
$conn) {
    
$e oci_error();
    
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

// Prepare the statement
$stid oci_parse($conn'SELECT * FROM departments');
if (!
$stid) {
    
$e oci_error($conn);
    
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

// Perform the logic of the query
$r oci_execute($stid);
if (!
$r) {
    
$e oci_error($stid);
    
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

// Fetch the results of the query
print '<table border='1'>' PHP_EOL;
while (
$row oci_fetch_array($stidOCI_ASSOC+OCI_RETURN_NULLS)) {
    print 
'<tr>' PHP_EOL;
    foreach (
$row as $item) {
        print 
'    <td>' . ($item !== null htmlentities($itemENT_QUOTES) : '&nbsp;') . '</td>' PHP_EOL;
    }
    print 
'</tr>' PHP_EOL;
}
print 
'</table>' PHP_EOL;

oci_free_statement($stid);
oci_close($conn);
?>


See also Oracle OCI8 and Oracle.

Overwritten Exceptions

[Since 0.8.4] - [ -P Exceptions/OverwriteException ] - [ Online docs ]

In catch blocks, it is good practice not to overwrite the incoming exception, as information about the exception will be lost.

<?php 
try {
    
doSomething();
} catch (
SomeException $e) { 
    
// $e is overwritten 
    
$e = new anotherException($e->getMessage()); 
    throw 
$e;
} catch (
SomeOtherException $e) { 
    
// $e is chained with the next exception 
    
$e = new Exception($e->getMessage(), 0$e); 
    throw 
$e;
}
?>

Foreach Reference Is Not Modified

[Since 0.8.4] - [ -P Structures/ForeachReferenceIsNotModified ] - [ Online docs ]

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.

<?php 
$letters range('a''z');

// $letter is not used here
foreach($letters as &$letter) {
    
$alphabet .= $letter;
}

// $letter is actually used here
foreach($letters as &$letter) {
    
$letter strtoupper($letter);
}
?>


ext/imap

[Since 0.8.4] - [ -P Extensions/Extimap ] - [ Online docs ]

Extension ext/imap.

This extension operate with the IMAP protocol, as well as the NNTP, POP3 and local mailbox access methods.

<?php 
$mbox imap_open('{imap.example.org}''username''password'OP_HALFOPEN)
      or die(
'can't connect' . imap_last_error());

$list = imap_list($mbox, '
{imap.example.org}', '*');
if (is_array($list)) {
    foreach ($list as $val) {
        echo imap_utf7_decode($val) . PHP_EOL;
    }
} else {
    echo '
imap_list failed' . imap_last_error() . PHP_EOL;
}

imap_close($mbox);
?>


See also IMAP.

Overwritten Class Const

[Since 0.8.4] - [ -P Classes/OverwrittenConst ] - [ Online docs ]

Those class constants are overwritten in a parent class. This may lead to confusion, as the value of the constant may change depending on the way it is called.

<?php 
class foo {
    const 
1;
}

class 
bar extends foo {
    const 
2;
    
    function 
x() {
        
// depending on the access to C, value is different.
        
print self::C.' '.static::C.' '.parent::C;
    }
}
?>


Direct Injection

[Since 0.8.4] - [ -P Security/DirectInjection ] - [ Online docs ]

The following code act directly upon PHP incoming variables like $_GET and $_POST . This makes those snippets very unsafe.

<?php 
// Direct injection
echo Hello.$_GET['user']., welcome.;

// less direct injection
foo($_GET['user']);
function 
foo($user) {
    echo 
Hello.$user., welcome.;
}
?>


See also Cross-Site Scripting (XSS)

Dynamic Class Constant

[Since 0.8.4] - [ -P Classes/DynamicConstantCall ] - [ Online docs ]

Dynamic calls to class constants.

Constant may be dynamically called with the constant() function.

<?php 
// Dynamic access to 'E_ALL'
    
echo constant('E_ALL');
    
    interface 
{
        const 
MY_CONSTANT  1;
    }

    
// Dynamic access to 'E_ALL'
    
echo constant('i::MY_CONSTANT');
?>


Dynamic Methodcall

[Since 0.8.4] - [ -P Classes/DynamicMethodCall ] - [ Online docs ]

Dynamic calls to class methods.

<?php 
class {
    static public function 
foo() {}
           public function 
bar() {}
}

$staticmethod 'foo';
// dynamic static method call to x::foo()
x::$staticmethod();

$method 'bar';
// dynamic method call to bar()
$object = new x();
$object->$method();
?>


Dynamic New

[Since 0.8.4] - [ -P Classes/DynamicNew ] - [ Online docs ]

Dynamic instantiation of classes.

<?php 
$object = new $classname()
?>

.

Dynamic Property

[Since 0.8.4] - [ -P Classes/DynamicPropertyCall ] - [ Online docs ]

Dynamic access to class property.

<?php 
class {
    static public 
$foo 1;
           public 
$bar 2;
}

$staticproperty 'foo';
// dynamic static property call to x::$foo
echo x::${$staticproperty};

$property 'bar';
// dynamic property call to bar()
$object = new x();
$object->$property 4;
?>


Don't Change Incomings

[Since 0.8.4] - [ -P Structures/NoChangeIncomingVariables ] - [ Online docs ]

PHP hands over a lot of information using special variables like $_GET, $_POST, etc... Modifying those variables and those values inside 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.

Dynamic Classes

[Since 0.8.4] - [ -P Classes/DynamicClass ] - [ Online docs ]

Dynamic calls of classes.

<?php 
class {
    static function 
staticMethod() {}
}

$class 'x';
$class::staticMethod();
?>


Compared Comparison

[Since 0.8.4] - [ -P Structures/ComparedComparison ] - [ Online docs ]

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.

<?php 
if ($a === strpos($string$needle) > 2) {}

// the expression above apply precedence : 
// it is equivalent to : 
if (($a === strpos($string$needle)) > 2) {}
?>


See also Operators Precedence.

Useless Return

[Since 0.8.4] - [ -P Functions/UselessReturn ] - [ Online docs ]

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;
}
?>

Multiple Classes In One File

[Since 0.8.4] - [ -P Classes/MultipleClassesInFile ] - [ Online docs ]

It is regarded as a bad practice to store several classes in the same file. This is usually done to make life of __autoload() easier.

It is often unexpected to find class foo in the bar.php file. This is also the case for interfaces and traits.

<?php 
// three classes in the same file
class foo {}
class 
bar {}
class 
foobar{}
?>


One good reason to have multiple classes in one file is to reduce include time by providing everything into one nice include.

See also Is it a bad practice to have multiple classes in the same file?.

File Uploads

[Since 0.8.4] - [ -P Structures/FileUploadUsage ] - [ Online docs ]

This code makes usage of file upload features of PHP.

Upload file feature is detected through the usage of specific functions :

<?php 
$uploaddir '/var/www/uploads/';
$uploadfile $uploaddir basename($_FILES['userfile']['name']);

echo 
'<pre>';
if (
move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    echo 
'File is valid, and was successfully uploaded.'.PHP_EOL;
} else {
    echo 
'Possible file upload attack!'.PHP_EOL;
}

echo 
'Here is some more debugging info:';
print_r($_FILES);

print 
'</pre>';
?>


See also Handling file uploads.

Return With Parenthesis

[Since 0.8.4] - [ -P Php/ReturnWithParenthesis ] - [ Online docs ]

return statement doesn't need parenthesis. PHP tolerates them with return statement, but it is recommended not to use them.

From the PHP Manual : 'Note: Note that since return is a language construct and not a function, the parentheses surrounding its argument are not required and their use is discouraged.'.

<?php 
function foo() {
    
$a rand(010);

    
// No need for parenthesis
    
return $a;

    
// Parenthesis are useless here
    
return ($a);

    
// Parenthesis are useful here: they are needed by the multplication.
    
return ($a 1) * 3;
}
?>


See also PHP return(value); vs return value; and
return.

Unused Classes

[Since 0.8.4] - [ -P Classes/UnusedClass ] - [ Online docs ]

The following classes are never explicitly 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.

<?php 
class unusedClasss {}
class 
usedClass {}

$y = new usedClass();
?>


ext/intl

[Since 0.8.4] - [ -P Extensions/Extintl ] - [ Online docs ]

Extension international.

Internationalization extension (further is referred as Intl) is a wrapper for ICU library, enabling PHP programmers to perform various locale-aware operations including but not limited to formatting, transliteration, encoding conversion, calendar operations, UCA-conformant collation, locating text boundaries and working with locale identifiers, timezones and graphemes.

<?php 
$coll = new Collator('en_US');
$al   $coll->getLocale(Locale::ACTUAL_LOCALE);
echo 
Actual locale$al\n;

$formatter = new NumberFormatter('en_US'NumberFormatter::DECIMAL);
echo 
$formatter->format(1234567);
?>


See also Internationalization Functions.

ext/cairo

[Since 0.8.4] - [ -P Extensions/Extcairo ] - [ Online docs ]

Extension ext/cairo.

Cairo is a native PHP extension to create and modify graphics using the Cairo Graphics Library.

<?php 
// Example from https://github.com/gtkforphp/cairo/blob/master/examples/big-line.php
$width 100;
$height 100;
$sur = new CairoPSSurface(temp.ps$width$height);

$con = new CairoContext($sur);
$con->setSourceRgb(0,0,1);
$con->moveTo(50,50);
$con->lineTo(50000,50000);
$con->stroke();
$con->setSourceRgb(0,1,0);
$con->moveTo(50,50);
$con->lineTo(-50000,50000);
$con->stroke();
$con->setSourceRgb(1,0,0);
$con->moveTo(50,50);
$con->lineTo(50000,-50000);
$con->stroke();
$con->setSourceRgb(1,1,0);
$con->moveTo(50,50);
$con->lineTo(-50000,-50000);
$con->stroke();

$sur->writeToPng(dirname(__FILE__)  . /big-line-php.png);
?>


See also Cairo, gtkforphp/cairo.

Dynamic Code

[Since 0.8.4] - [ -P Structures/DynamicCode ] - [ Online docs ]

List of instructions that were left during analysis, as they rely on dynamic data.

<?php 
// Dynamic call to 'method';
$name 'method';
$object->$name();

// Hard coded call to 'method';
$object->method();
?>


Any further analysis will need to start from here.

See also Variable functions.

Unpreprocessed Values

[Since 0.8.4] - [ -P Structures/Unpreprocessed ] - [ Online docs ]

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 comfort 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.

ext/pspell

[Since 0.8.4] - [ -P Extensions/Extpspell ] - [ Online docs ]

Extension pspell.

These functions allow you to check the spelling of a word and offer suggestions.

<?php 
$pspell_link pspell_new('en');

if (
pspell_check($pspell_link'testt')) {
    echo 
'This is a valid spelling';
} else {
    echo 
'Sorry, wrong spelling';
}
?>


See also Pspell and pspell.

No Direct Access

[Since 0.8.4] - [ -P Structures/NoDirectAccess ] - [ Online docs ]

This expression protects files against direct access. It will kill the process if it realizes this is not supposed to be directly accessed.

Those expressions are used in applications and framework, to prevent direct access to definition files.

<?php 
// CONSTANT_EXEC is defined in the main file of the application
  
defined('CONSTANT_EXEC') or die('Access not allowed'); : Constant used!
?>

ext/opcache

[Since 0.8.4] - [ -P Extensions/Extopcache ] - [ Online docs ]

Extension opcache.

OPcache improves PHP performance by storing precompiled script bytecode in shared memory, thereby removing the need for PHP to load and parse scripts on each request.

<?php 
echo opcache_compile_file('/var/www/index.php');

print_r(opcache_get_status());
?>


See also OPcache functions.

ext/expect

[Since 0.8.4] - [ -P Extensions/Extexpect ] - [ Online docs ]

Extension Expect.

This extension allows to interact with processes through PTY . You may consider using the expect:// wrapper with the filesystem functions which provide a simpler and more intuitive interface.

<?php 
ini_set('expect.loguser''Off');

$stream fopen('expect://ssh root@remotehost uptime''r');

$cases = array (
    array (
=> 'password:'=> PASSWORD)
);

switch (
expect_expectl ($stream$cases)) {
    case 
PASSWORD:
        
fwrite ($stream'password'.PHP_EOL);
        break;
 
    default:
        die (
'Error was occurred while connecting to the remote host!'.PHP_EOL);
}

while (
$line fgets($stream)) {
      print 
$line;
}
fclose ($stream);
?>


See also expect.

Undefined Properties

[Since 0.8.4] - [ -P Classes/UndefinedProperty ] - [ Online docs ]

List of properties that are not explicitly defined in the class, its parents or traits.

<?php 
class foo {
    
// property definition
    
private bar 2;
    
    function 
foofoo() {
        
// $this->bar is defined in the class
        // $this->barbar is NOT defined in the class
        
return $this->bar $this->barbar;
    }
}
?>


It is possible to spot unidentified properties by using the PHP's magic methods __get and __set . Even if the class doesn't use magic methods, any call to an undefined property will be directed to those methods, and they can be used as a canary, warning that the code is missing a definition.

<?php 
trait NoUnefinedProperties {
    function 
__get($name) {
        
assert(false"Attempt to read the $name property, on the class ".__CLASS__;
    }

    function 
__set($name$value) {
        
assert(false"Attempt to read the $name property, on the class ".__CLASS__;
    }
}
?>


See also Properties.

ext/recode

[Since 0.8.4] - [ -P Extensions/Extrecode ] - [ Online docs ]

Extension GNU Recode.

This module contains an interface to the GNU Recode library. The GNU Recode library converts files between various coded character sets and surface encodings.

<?php 
echo recode_string('us..flat''The following character has a diacritical mark: á');
?>


This extension is not available on Windows.

See also ext/recode and Recode.

ext/parsekit

[Since 0.8.4] - [ -P Extensions/Extparsekit ] - [ Online docs ]

Extension Parsekit.

These functions allow runtime analysis of opcodes compiled from PHP scripts.

<?php 
var_dump(parsekit_compile_file('hello_world.php'$errorsPARSEKIT_SIMPLE));
?>


See also Parsekit.

ext/runkit

[Since 0.8.4] - [ -P Extensions/Extrunkit ] - [ Online docs ]

Extension Runkit.

The runkit extension provides means to modify constants, user-defined functions, and user-defined classes. It also provides for custom superglobal variables and embeddable sub-interpreters via sandboxing.

<?php 
class Example {
    function 
foo() {
        echo 
'foo!'.PHP_EOL;
    }
}

// create an Example object
$e = new Example();

// Add a new public method
runkit_method_add(
    
'Example',
    
'add',
    
'$num1, $num2',
    
'return $num1 + $num2;',
    
RUNKIT_ACC_PUBLIC
);

// add 12 + 4
echo $e->add(124);
?>


See also runkit.

ext/gettext

[Since 0.8.4] - [ -P Extensions/Extgettext ] - [ Online docs ]

Extension Gettext.

The gettext functions implement an NLS (Native Language Support) API which can be used to internationalize your PHP applications.

<?php 
// Set language to German
putenv('LC_ALL=de_DE');
setlocale(LC_ALL'de_DE');

// Specify location of translation tables
bindtextdomain('myPHPApp''./locale');

// Choose domain
textdomain('myPHPApp');

// Translation is looking for in ./locale/de_DE/LC_MESSAGES/myPHPApp.mo now

// Print a test message
echo gettext('Welcome to My PHP Application');

// Or use the alias _() for gettext()
echo _('Have a nice day');
?>


See also Gettext and ext/gettext

Short Open Tags

[Since 0.8.4] - [ -P Php/ShortOpenTagRequired ] - [ Online docs ]

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 <? tags are found in the code.

Strict Comparison With Booleans

[Since 0.8.4] - [ -P Structures/BooleanStrictComparison ] - [ Online docs ]

Strict comparisons prevent from mistaking an error with a false.

Boolean values 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.

<?php 
// distinguish between : $b isn't in $a, and, $b is at the beginning of $a 
if (strpos($a$b) === 0) {
    
doSomething();
}

// DOES NOT distinguish between : $b isn't in $a, and, $b is at the beginning of $a 
if (strpos($a$b)) {
    
doSomething();
}

// will NOT mistake 1 and true
$a = array(012true);
if (
in_array($atruetrue)) {
    
doSomething();
}

// will mistake 1 and true
$a = array(012true);
if (
in_array($atrue)) {
    
doSomething();
}
?>


switch() structures always uses == comparisons.

Native function in_array() has a third parameter to make it use strict comparisons.

Lone Blocks

[Since 0.8.4] - [ -P Structures/LoneBlock ] - [ Online docs ]

Any grouped code without a commanding structure is useless.

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 
// Lone block
    //foreach($a as $b) 
    
{
        
$b++;
    }
?>


$this Is Not For Static Methods

[Since 0.8.4] - [ -P Classes/ThisIsNotForStatic ] - [ Online docs ]

Static methods shouldn't use $this variable.

$this variable represents an object, the current object. It is not compatible with a static method, which may operate without any object.

While executing a static method, $this is actually set to NULL.

<?php 
class foo {
    static 
$staticProperty 1;

    
// Static methods should use static properties
    
static public function `count() <https://www.php.net/count>`{
        return 
self::$staticProperty++;
    }
    
    
// Static methods can't use $this
    
static public function bar() {
        return 
$this->a;   // No $this usage in a static method
    
}
}
?>


See also Static Keyword.

Avoid sleep()/usleep()

[Since 0.8.4] - [ -P Security/NoSleep ] - [ Online docs ]

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 resources 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 ).

Super Global Usage

[Since 0.8.4] - [ -P Php/SuperGlobalUsage ] - [ Online docs ]

Spot usage of Super global variables, such as $_GET, $_POST or $_REQUEST.

<?php 
echo htmlspecialchars($_GET['name'], UTF-8);
?>


See also Superglobals.

Global Usage

[Since 0.8.4] - [ -P Structures/GlobalUsage ] - [ Online docs ]

List usage of globals variables, with global keywords or direct access to $GLOBALS.

<?php 
$a 1/* global scope */ 

function test()

    echo 
$a/* reference to local scope variable */ 


test();
?>

It is recommended to avoid using global variables, at it makes it very difficult to track changes in values across the whole application.

See also Variable scope.

PHP Keywords As Names

[Since 0.8.4] - [ -P Php/ReservedNames ] - [ Online docs ]

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.

<?php 
// This keyword is reserved since PHP 7.2
class object {
    
// _POST is used by PHP for the $_POST variable
    // This methods name is probably confusing, 
    // and may attract more than its share of attention
    
function _POST() {
    
    }
}
?>


See also List of Keywords,
Predefined Classes,
Predefined Constants,
List of other reserved words and
Predefined Variables.

Logical Should Use Symbolic Operators

[Since 0.8.4] - [ -P Php/LogicalInLetters ] - [ Online docs ]

Logical operators come in two flavors : and / &&, || / or, ^ / xor. However, they are not exchangeable, as && and and have different precedence.

<?php 
// Avoid lettered operator, as they have lower priority than expected
$a $b and $c;
// $a === 3 because equivalent to ($a = $b) and $c;

// safe way to write the above : 
$a = ($b and $c);

$a $b && $c;
// $a === 1
?>


It is recommended to use the symbol operators, rather than the letter ones.

See also Logical Operators.

Could Use self

[Since 0.8.4] - [ -P Classes/ShouldUseSelf ] - [ Online docs ]

self keyword refers to the current class, or any of its parents. Using it is just as fast as the full class name, 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 {
    const 
FOO 1;
    
    public function 
bar() {
        return 
self::FOO;
// same as return x::FOO;
    
}
}
?>


See also Scope Resolution Operator (::).

Const With Array

[Since 0.8.4] - [ -P Php/ConstWithArray ] - [ Online docs ] - [ PHP 5.5 and more recent ]

The const keyword supports array. This feature was added in PHP 5.6.

The array must be filled with other constants. It may also be build using the '+' operator.

<?php 
const PRIMES = [2357];

class 
{
    const 
TWENTY_THREE 23;
    const 
MORE_PRIMES PRIMES + [11131719];
    const 
EVEN_MORE_PRIMES self::MORE_PRIMES + [self::TWENTY_THREE];
}
?>


See also Class Constants and
Constants Syntax.

Catch Overwrite Variable

[Since 0.8.4] - [ -P Structures/CatchShadowsVariable ] - [ Online docs ]

The try/catch structure uses some variables that are 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.

<?php 
// variables and caught exceptions are distinct
$argument 1;
try {
    
methodThatMayRaiseException($argument);
} (
Exception $e) {
    
// here, $e has been changed to an exception.
}

// variables and caught exceptions are overlapping
$e 1;
try {
    
methodThatMayRaiseException();
} (
Exception $e) {
    
// here, $e has been changed to an exception.
}
?>


It is recommended to use another name for these catch variables.

Namespaces

[Since 0.8.4] - [ -P Namespaces/NamespaceUsage ] - [ Online docs ]

Inventory of all namespaces.

Avoid array_unique()

[Since 0.8.4] - [ -P Structures/NoArrayUnique ] - [ Online docs ]

The native function array_unique() is much slower than using other alternatives, such as array_count_values(), array_flip()/array_keys(), or even a foreach() loops.

<?php 
// using `array_unique() <https://www.php.net/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;
    }
}
?>


See also array_unique.

Deep Definitions

[Since 0.8.4] - [ -P Functions/DeepDefinitions ] - [ Online docs ]

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, with spl_register_autoload(), there is no need for that kind of code. Structures should be defined, and accessible to the autoloading. Inclusions and deep definitions should be avoided, as they compel code to load some definitions, while autoloading will only load them if needed.

<?php 
class {
    function 
init() {
        
// myFunction is defined when and only if X::init() is called.
        
if (!function_exists('myFunction'){
            function 
myFunction($a) {
                return 
$a 1;
            }
        })
    }
}
?>


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.

Definitions inside a if/then statement, that include PHP version check are accepted here.

See also Autoloading Classes.

Constant Class

[Since 0.8.4] - [ -P Classes/ConstantClass ] - [ Online docs ]

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.

<?php 
class ConstantClass {
    const 
KBIT 1000;
    const 
MBIT self::KBIT 1000;
    const 
GBIT self::MBIT 1000;
    const 
PBIT self::GBIT 1000;
}
?>


As such, they should be PHP constants (build with define or const), or included in a class with other methods and properties.

See also PHP Classes containing only constants.

Not Definitions Only

[Since 0.8.4] - [ -P Files/NotDefinitionsOnly ] - [ Online docs ]

Files should only include definitions (class, functions, traits, interfaces, constants), or global instructions, but not both.

<?php 
// This whole script is a file

// It contains definitions and global code
class foo {
    static public 
$foo null;
}
//This can be a singleton creation
foo::$foo = new foo();

trait 
{}

class 
bar {}
?>


Within this context, globals, use, and namespaces instructions are not considered a warning.

Preprocess Arrays

[Since 0.8.4] - [ -P Arrays/ShouldPreprocess ] - [ Online docs ]

Using long list of assignations for initializing arrays is significantly slower than the declaring them as an array.

<?php 
// Slow way
$a = []; // also with $a = array();
$a[1] = 2;
$a[2] = 3;
$a[3] = 5;
$a[4] = 7;
$a[5] = 11;

// Faster way
$a = [=> 2
      
=> 3,
      
=> 5,
      
=> 7,
      
=> 11];

// Even faster way if indexing is implicit
$a = [235711];
?>


If the array has to be completed rather than created, it is also faster to use += when there are more than ten elements to add.

<?php 
// Slow way
$a = []; // also with $a = array();
$a[1] = 2;
$a[2] = 3;
$a[3] = 5;
// some expressions to get $seven and $eleven
$a[4] = $seven;
$a[5] = $eleven;

// Faster way
$a = [=> 2
      
=> 3,
      
=> 5];
// some expressions to get $seven and $eleven
$a += [=> $seven
       
=> $eleven];

// Even faster way if indexing is implicit
$a = [235];
// some expressions to get $seven and $eleven
$a += [$seven$eleven];
?>

Repeated print()

[Since 0.8.4] - [ -P Structures/RepeatedPrint ] - [ Online docs ]

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';
?>


Avoid Parenthesis

[Since 0.8.4] - [ -P Structures/PrintWithoutParenthesis ] - [ Online docs ]

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.

<?php 
// normal usage of include
include 'file.php';

// This looks like a function and is not
include('file2.php');
?>


The usage of parenthesis actually give some feeling of comfort, 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.

Objects Don't Need References

[Since 0.8.4] - [ -P Structures/ObjectReferences ] - [ Online docs ]

There is no need to create references for objects, as those are always passed by reference when used as arguments.

Note that when the argument is assigned another value, including another object, then the reference is needed : PHP forgets about reference when they are replaced.

<?php 
$object = new stdClass();
    
$object->name 'a';
    
    
foo($object);
    print 
$object->name// Name is 'b'
    
    // No need to make $o a reference
    
function foo(&$o) {
        
$o->name 'b';
    }

    
    
// $o is assigned inside the function : it must be called with a &, or the object won't make it out of the foo3 scope
    
function foo3(&$o) {
        
$o = new stdClass;
    }
    
    
$array = array($object);
    foreach(
$array as &$o) { // No need to make this a reference
        
$o->name 'c';
    }
?>


See also Passing by reference.

Redefined Property

[Since 0.8.4] - [ -P Classes/RedefinedProperty ] - [ Online docs ]

Property redefined in a parent class.

Using heritage, it is possible to define several times the same property, at different levels of the hierarchy.

<?php 
class foo {
    protected 
$aProperty 1;
}

class 
bar extends foo {
    
// This property is redefined in the parent class, leading to potential confusion
    
protected $aProperty 1;
}
?>


When this is the case, it is difficult to understand which class will actually handle the property.

In the case of a private property, the different instances will stay distinct. In the case of protected or public properties, they will all share the same value.

It is recommended to avoid redefining the same property in a hierarchy.

Locally Unused Property

[Since 0.8.4] - [ -P Classes/LocallyUnusedProperty ] - [ Online docs ]

Those properties are defined in a class, and this class doesn't have any method that makes use of them.

While this is syntactically correct, it is unusual that defined resources are used in a child class. It may be worth moving the definition to another class, or to move accessing methods to the class.

<?php 
class foo {
    public 
$unused$used;// property $unused is never used in this class
    
    
function bar() {
        
$this->used++; // property $used is used in this method
    
}
}

class 
foofoo extends foo {
    function 
bar() {
        
$this->unused++; // property $unused is used in this method, but defined in the parent class
    
}
}
?>


Lost References

[Since 0.8.4] - [ -P Variables/LostReferences ] - [ Online docs ]

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.

Constants Created Outside Its Namespace

[Since 0.8.4] - [ -P Constants/CreatedOutsideItsNamespace ] - [ Online docs ]

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\{
    
// define A\B\C as 1
    
define('C'1);
}

namespace 
D\{
    
// 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.

Fully Qualified Constants

[Since 0.8.4] - [ -P Namespaces/ConstantFullyQualified ] - [ Online docs ]

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, \a\b\c 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.

Never Used Properties

[Since 0.8.4] - [ -P Classes/PropertyNeverUsed ] - [ Online docs ]

Properties that are never used. They are defined in a class or a trait, but they never actually used.

Properties are considered used when they are used locally, in the same class as their definition, or in a parent class : a parent class is always included with the current class.

On the other hand, properties which are defined in a class, but only used in children classes is considered unused, since children may also avoid using it.

<?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;
?>


No Real Comparison

[Since 0.8.4] - [ -P Type/NoRealComparison ] - [ Online docs ]

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$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_dumpabs(((0.1 0.7) * 10) - 8) < 0.0001);
?>


Use precision formulas with abs() to approximate values with a given precision, or avoid reals altogether.

See also Floating point numbers.

Should Use Local Class

[Since 0.8.4] - [ -P Classes/ShouldUseThis ] - [ Online docs ]

Methods should use the defining 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 $b;
    }
}
?>


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

Usage Of class_alias()

[Since 0.8.4] - [ -P Classes/ClassAliasUsage ] - [ Online docs ]

class_alias creates dynamically an alias for classes.

<?php 
class foo { }

class_alias('foo''bar');

$a = new foo;
$b = new bar;

// the objects are the same
var_dump($a == $b$a === $b);
var_dump($a instanceof $b);

// the classes are the same
var_dump($a instanceof foo);
var_dump($a instanceof bar);

var_dump($b instanceof foo);
var_dump($b instanceof bar);
?>


See also class_alias.

Custom Class Usage

[Since 0.8.4] - [ -P Classes/AvoidUsing ] - [ Online docs ]

List of usage of custom classes throughout the code.

ext/apache

[Since 0.8.4] - [ -P Extensions/Extapache ] - [ Online docs ]

Extension Apache.

These functions are only available when running PHP as an Apache module.

<?php 
$ret apache_getenv(SERVER_ADDR);
  echo 
$ret;
?>


See also Extension Apache and Apache server.

ext/eaccelerator

[Since 0.8.4] - [ -P Extensions/Exteaccelerator ] - [ Online docs ]

Extension Eaccelerator.

eAccelerator is a free open-source PHP accelerator & optimizer.

See also Eaccelerator and eaccelerator/eaccelerato.

ext/fpm

[Since 0.8.4] - [ -P Extensions/Extfpm ] - [ Online docs ]

Extension FPM, FastCGI Process Manager.

FPM (FastCGI Process Manager) is an alternative PHP FastCGI implementation with some additional features (mostly) useful for heavy-loaded sites.

<?php 
echo $text;
    
fastcgi_finish_request( );
?>


See also FastCGI Process Manager.

ext/iis

[Since 0.8.4] - [ -P Extensions/Extiis ] - [ Online docs ]

Extension IIS Administration.

It provides functions to administrate Microsoft Internet Information Server (IIS).

<?php 
$path iis_get_server_by_path('/path/to/root/folder/')
?>


This extension is available for Windows only.

See also IIS Administration.

ext/xcache

[Since 0.8.4] - [ -P Extensions/Extxcache ] - [ Online docs ]

Extension Xcache.

XCache is a open-source opcode cacher, which means that it accelerates the performance of PHP on servers.

<?php 
if (!xcache_isset(count)) {
  
xcache_set(countload_count_from_mysql());
}
?>

This guest book has been visited
<?php 
echo $count xcache_inc(count); ?> times.
<?php
// save every 100 hits
if (($count 100) == 0) {
  
save_count_to_mysql($count);
}
?>


See also xcache.

ext/wincache

[Since 0.8.4] - [ -P Extensions/Extwincache ] - [ Online docs ]

Extension Wincache.

The Wincache extension for PHP is a PHP accelerator that is used to increase the speed of PHP applications running on Windows and Windows Server.

<?php 
$fp fopen('/tmp/lock.txt''r+');
if (
wincache_lock(“lock_txt_lock”)) { // do an exclusive lock
    
ftruncate($fp0); // truncate file
    
fwrite($fp'Write something here\n');
    
wincache_unlock(“lock_txt_lock”); // release the lock
} else {
    echo 
'Couldn't get the lock!';
}
fclose($fp);
?>


See also WinCache Extension for PHP.

parse_str() Warning

[Since 0.8.4] - [ -P Security/parseUrlWithoutParameters ] - [ Online docs ]

The parse_str() function parses a query string and assigns the resulting variables to the local scope. This may create a unexpected number of variables, and even overwrite the existing one.

<?php 
function foo( ) {
    global 
$a;
    
    echo 
$a;
  }

  
parse_str('a=1'); // No second parameter
  
foo( );
  
// displays 1
?>


Always use an empty variable a second parameter to parse_str(), so as to collect the incoming values, and then, filter them in that array.

No Direct Call To Magic Method

[Since 0.8.4] - [ -P Classes/DirectCallToMagicMethod ] - [ Online docs ]

PHP features magic methods, which are methods related to operators.

Magic methods, such as __get(), related to =, or __clone(), related to clone , are supposed to be used in an object environment, and not with direct call.

It is recommended to use the magic method with its intended usage, and not to call it directly. For example, typecast to string instead of calling the __toString() method.

<?php 
// Write
  
print $x->a;
// instead of 
  
print $x->__get('a'); 

class 
Foo {
    private 
$b secret;

    public function 
__toString() {
        return 
strtoupper($this->b);
    }
}

$bar = new Foo();
echo (string) 
$bar;
?>


Accessing those methods in a static way is also discouraged.

See also Magic Methods and
Magical PHP: __call.

String May Hold A Variable

[Since 0.8.4] - [ -P Type/StringHoldAVariable ] - [ Online docs ]

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;
?>

Echo With Concat

[Since 0.8.4] - [ -P Structures/EchoWithConcat ] - [ Online docs ]

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 visible 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;
?>


Unused Global

[Since 0.8.4] - [ -P Structures/UnusedGlobal ] - [ Online docs ]

A global keyword is used in a method, yet the variable is not actually used. This makes PHP import values for nothing, or may create interference

<?php 
function foo() {
        global 
bar;
        
        return 
1;
    }
?>


Useless Global

[Since 0.8.4] - [ -P Structures/UselessGlobal ] - [ Online docs ]

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.

Preprocessable

[Since 0.8.4] - [ -P Structures/ShouldPreprocess ] - [ Online docs ]

The following expression are made of literals or already known values : they may be fully calculated before running PHP.

<?php 
// Building an array from a string
$name 'PHP'.' '.'7.2';

// Building an array from a string
$list explode(',''a,b,c,d,e,f');

// Calculating a power
$kbytes $bytes pow(210);

// This will never change
$name ucfirst(strtolower('PARIS'));
?>


By doing so, this will reduce the amount of work of PHP.

Slow Functions

[Since 0.8.4] - [ -P Performances/SlowFunctions ] - [ Online docs ]

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 FunctionFaster
array_diff()foreach()
array_intersect()foreach()
array_key_exists()isset() and array_key_exists()
array_map()foreach()
array_search()array_flip() and isset()
array_udiff()Use another way
array_uintersect()Use another way
array_unshift()Use another way
array_walk()foreach()
in_array()isset()
preg_replace()strpos()
strstr()strpos()
uasort()Use another way
uksort()Use another way
usort()Use another way
array_unique()array_keys() and array_count_values()
array_unique() has been accelerated in PHP 7.2 and may be used directly from this version on : Optimize `array_unique() `_.

array_key_exists() has been accelerated in PHP 7.4 and may be used directly from this version on : Implement ZEND_ARRAY_KEY_EXISTS opcode to speed up `array_key_exists() `_.

Useless Final

[Since 0.8.4] - [ -P Classes/UselessFinal ] - [ Online docs ]

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() { }
    }
?>


See also Final Keyword, and When to declare final.

Use Constant

[Since 0.8.4] - [ -P Structures/UseConstant ] - [ Online docs ]

The following functioncall have a constant equivalent, that is faster to use than calling the functions.

This applies to the following functions :


<?php 
// recommended way 
echo PHP_VERSION;

// slow version
echo php_version();
?>


See also PHP why `pi() and M_PI `_.

Resources Usage

[Since 0.8.4] - [ -P Structures/ResourcesUsage ] - [ Online docs ]

List of situations that are creating resources.

<?php 
// This functioncall creates a resource to use
    
$fp fopen('/tmp/file.txt''r');
    
    if (!
is_resource($fp)){
        
thrown new RuntimeException('Could not open file.txt');
    }
?>


Useless Unset

[Since 0.8.4] - [ -P Structures/UselessUnset ] - [ Online docs ]

There are situations where trying to remove a variable is actually useless.

PHP ignores any command that tries to unset a global variable, a static variable, or a blind variable from a foreach loop.

This is different from the garbage collector, which is run on its own schedule. It is also different from an explicit unset, aimed at freeing memory early : those are useful.

<?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;
    }
    
// Unsetting a blind variable AFTER the loop is good.
    
unset($e);
}
?>


See also unset.

Buried Assignation

[Since 0.8.4] - [ -P Structures/BuriedAssignation ] - [ Online docs ]

Those assignations are buried in the code, and placed in unexpected situations.

They are difficult to spot, and may be confusing. It is advised to place them in a more visible place.

<?php 
// $b may be assigned before processing $a
$a $c && ($b 2);

// Display property p immeiately, but also, keeps the object for later
echo ($o = new x)->p;

// legit syntax, but the double assignation is not obvious.
for($i 2$j 3$j 10$j++) {
    
}
?>


No array_merge() In Loops

[Since 0.8.4] - [ -P Performances/ArrayMergeInLoops ] - [ Online docs ]

array_merge() is memory intensive : every call will duplicate the arguments in memory, before merging them.

To handle arrays that 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 
// A large multidimensional array
$source = ['a' => ['a''b'/*...*/],
           
'b' => ['b''c''d'/*...*/],
           
/*...*/
           
];

// 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))

// Slow way to merge it all
$b = array();
foreach(
$source as $key => $values) {
    
$b array_merge($b$values);
}
?>


Note that array_merge_recursive() and file_put_contents() are affected and reported the same way.

Useless Parenthesis

[Since 0.8.4] - [ -P Structures/UselessParenthesis ] - [ Online docs ]

Situations where parenthesis are not necessary, and may be removed.

Parenthesis group several elements together, and allows for a more readable expression. They are used with logical and mathematical expressions. They are necessary when the precedence of the operators are not the intended execution order : for example, when an addition must be performed before the multiplication.

Sometimes, the parenthesis provide the same execution order than the default order : they are deemed useless.

<?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 = ( 2) ) {}
?>


See also Operators Precedence.

Shell Usage

[Since 0.8.4] - [ -P Structures/ShellUsage ] - [ Online docs ]

List of shell calls to system.

<?php 
// Using backtick operator
    
$a = `ls -hla`;
    
    
// Using one of PHP native or extension functions
    
$a shell_exec('ls -hla');
    
$b = \pcntl_exec('/path/to/command');
?>


See also shell_exec and
Execution Operators.

File Usage

[Since 0.8.4] - [ -P Structures/FileUsage ] - [ Online docs ]

The application makes usage of files on the system (read, write, delete, etc.).

Files usage is based on the usage of file functions.

<?php 
$fp fopen('/tmp/file.txt''w+');
    
// ....
?>


See also filesystem.

Mail Usage

[Since 0.8.4] - [ -P Structures/MailUsage ] - [ Online docs ]

Report usage of mail from PHP.

The analysis is based on mail() function and various classes used to send mail.

<?php 
// The message
$message Line 1\r\nLine 2\r\nLine 3;

// In case any of our lines are larger than 70 characters, we should use `wordwrap() <https://www.php.net/wordwrap>`_
$message wordwrap($message70, \r\n);

// Send
mail('caffeinated@example.com''My Subject'$message);
?>


See also mail.

Dynamic Calls

[Since 0.8.4] - [ -P Structures/DynamicCalls ] - [ Online docs ]

List of dynamic calls. They will probably need to be review manually.

<?php 
$a 'b';

// Dynamic call of a constant
echo constant($a);

// Dynamic variables
$$a 2;
echo 
$b;

// Dynamic call of a function
$a('b'); 

// Dynamic call of a method
$object->$a('b'); 

// Dynamic call of a static method
A::$a('b');
?>


See also Variable functions.

Unresolved Instanceof

[Since 0.8.4] - [ -P Classes/UnresolvedInstanceof ] - [ Online docs ]

The instanceof operator doesn't confirm if the 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 {
    class 
{}
    
    
// 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.

See also Instanceof.

Use PHP Object API

[Since 0.8.4] - [ -P Php/UseObjectApi ] - [ Online docs ]

OOP API is the modern version of the PHP 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, and some others.

<?php 
/// OOP version
$mysqli = new mysqli(localhostmy_usermy_passwordworld);

/* 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(localhostmy_usermy_passwordworld);

/* check connection */
if (mysqli_connect_errno()) {
    
printf(Connect failed: %s\nmysqli_connect_error());
    exit();
}

/* Create table doesn't return a resultset */
if (mysqli_query($linkCREATE TEMPORARY TABLE myCity LIKE City) === TRUE) {
    
printf(Table myCity successfully created.\n);
}
?>


Unthrown Exception

[Since 0.8.4] - [ -P Exceptions/Unthrown ] - [ Online docs ]

These are exceptions that are defined in the code but never thrown.

<?php 
//This exception is defined but never used in the code.
class myUnusedException extends \Exception {}

//This exception is defined and used in the code.
class myUsedException extends \Exception {}

throw new 
myUsedException('I was called');
?>


See also Exceptions.

Old Style __autoload()

[Since 0.8.4] - [ -P Php/oldAutoloadUsage ] - [ Online docs ]

Avoid __autoload(), only use spl_register_autoload().

__autoload() is deprecated since PHP 7.2 and possibly removed in later versions. spl_register_autoload() was introduced in PHP 5.1.0.

__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.

Altering Foreach Without Reference

[Since 0.8.4] - [ -P Structures/AlteringForeachWithoutReference ] - [ Online docs ]

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.

See also foreach.

Test Class

[Since 0.8.4] - [ -P Classes/TestClass ] - [ Online docs ]

Those are test classes, based on popular UT frameworks.

Mark Callable

[Since 0.8.4] - [ -P Functions/MarkCallable ] - [ Online docs ]

Create an attribute that guess what are the called function or methods, when possible.

Magic Visibility

[Since 0.8.4] - [ -P Classes/toStringPss ] - [ Online docs ] - [ PHP older than 5.4]

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 also Magic methods.

Use Pathinfo

[Since 0.8.4] - [ -P Php/UsePathinfo ] - [ Online docs ]

Use pathinfo() function instead of string manipulations.

pathinfo() is more efficient and readable and string functions.

<?php 
$filename '/path/to/file.php';

// With `pathinfo() <https://www.php.net/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.

Should Use Constants

[Since 0.8.4] - [ -P Functions/ShouldUseConstants ] - [ Online docs ]

The following functions have related constants that should be used as arguments, instead of scalar literals, such as integers or strings.

<?php 
// The file is read and new lines are ignored.
$lines file('file.txt'FILE_IGNORE_NEW_LINES)

// What is this doing, with 2 ? 
$lines file('file.txt'2);
?>


See also Bitmask Constant Arguments in PHP.

Hash Algorithms

[Since 0.8.4] - [ -P Php/HashAlgos ] - [ Online docs ]

There is a long but limited list of hashing algorithm available to PHP. The one found doesn't seem to be existing.

<?php 
// This hash has existed in PHP. Check with hash_algos() if it is available on your system. 
echo hash('ripmed160''The quick brown fox jumped over the lazy dog.');

// This hash doesn't exist
echo hash('ripemd160''The quick brown fox jumped over the lazy dog.');
?>


See also hash_algos.

Avoid Those Hash Functions

[Since 0.8.4] - [ -P Security/AvoidThoseCrypto ] - [ Online docs ]

The following cryptography algorithms are considered insecure, 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 cryptography is 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 Secure Hash Algorithms.

ext/dio

[Since 0.8.4] - [ -P Extensions/Extdio ] - [ Online docs ]

Extension DIO : Direct Input Output.

PHP supports the direct io functions as described in the Posix Standard (Section 6) for performing I/O functions at a lower level than the C-Language stream I/O functions

<?php 
$fd dio_open('/dev/ttyS0'O_RDWR O_NOCTTY O_NONBLOCK);

dio_close($fd);
?>


See also DIO.

No Parenthesis For Language Construct

[Since 0.8.4] - [ -P Structures/NoParenthesisForLanguageConstruct ] - [ Online docs ]

Some PHP language constructs, such are include , print , echo don't need parenthesis. They accept parenthesis, but it is may lead to strange situations.

<?php 
// This is an attempt to load 'foo.inc', or kill the script
include('foo.inc') or die();
// in fact, this is read by PHP as : include 1 
// include  'foo.inc' or die();
?>


It it better to avoid using parenthesis with echo , print , return , throw , yield , yield from , include , require , include_once , require_once .

See also include.

Unused Label

[Since 0.8.4] - [ -P Structures/UnusedLabel ] - [ Online docs ]

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.

No Hardcoded Path

[Since 0.8.4] - [ -P Structures/NoHardcodedPath ] - [ Online docs ]

It is not recommended to use hardcoded literals when designating files. Full paths are usually tied to one file system organization. As soon as the organisation changes or must be adapted to any external constraint, the path is not valid anymore.

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 the moving of the script to another folder; finally functions like sys_get_temp_dir() produce a viable temporary folder.

Relative paths are relative to the current execution directory, and not the current file. This means they may differ depending on the location of the start of the application, and are sensitive to chdir() and chroot() usage.

<?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() <https://www.php.net/glob>`_ with special chars * and ? are not reported
    
glob('./*/foo/bar?.txt');
    
// `glob() <https://www.php.net/glob>`_ without special chars * and ? are reported
    
glob('/foo/bar/');
?>


Methodcall On New

[Since 0.8.4] - [ -P Php/MethodCallOnNew ] - [ Online docs ] - [ PHP 5.4 and more recent ]

It is possible to call a method right at object instantiation.

This syntax was added in PHP 5.4+. Before, this was not possible : the object had to be stored in a variable first.

<?php 
// Data is collected
$data data_source();

// Data is saved, but won't be reused from this databaseRow object. It may be ignored.
$result = (new databaseRow($data))->save();

// The actual result of the save() is collected and tested.
if ($result !== true) {
    
processSaveError($data);
}
?>


This syntax is interesting when the object is not reused, and may be discarded

No Hardcoded Port

[Since 0.8.4] - [ -P Structures/NoHardcodedPort ] - [ Online docs ]

When connecting to a remove server, 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.

<?php 
// Both configurable IP and hostname
    
$connection ssh2_connect($_ENV['SSH_HOST'], $_ENV['SSH_PORT'], $methods$callbacks);
    
    
// Both hardcoded IP and hostname
    
$connection ssh2_connect('shell.example.com'22$methods$callbacks);

    if (!
$connection) die('Connection failed');
?>


ext/phalcon

[Since 0.8.4] - [ -P Extensions/Extphalcon ] - [ Online docs ]

Extension Phalcon : High Performance PHP Framework.

Phalcon's autoload examples from the docs : Tutorial 1: Let’s learn by example

<?php 
use Phalcon\Loader;

// ...

$loader = new Loader();

$loader->registerDirs(
    [
        ../
app/controllers/,
        ../
app/models/,
    ]
);

$loader->register();
?>


See also PhalconPHP.

Use Constant As Arguments

[Since 0.8.4] - [ -P Functions/UseConstantAsArguments ] - [ Online docs ]

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.

<?php 
// Turn off all error reporting
// 0 and -1 are accepted 
error_reporting(0);

// Report simple running errors
error_reporting(E_ERROR E_WARNING E_PARSE);

// The first argument can be one of INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, or INPUT_ENV.
$search_html filter_input(INPUT_GET'search'FILTER_SANITIZE_SPECIAL_CHARS);

// sort accepts one of SORT_REGULAR, SORT_NUMERIC, SORT_STRING, SORT_LOCALE_STRING, SORT_NATURAL
// SORT_FLAG_CASE may be added, and combined with SORT_STRING or SORT_NATURAL
sort($fruits);
?>


Here is the list of function that use a unique PHP constant as argument :

+ array_change_key_case()
+ array_multisort()
+ array_unique()
+ count()
+ dns_get_record()
+ easter_days()
+ extract()
+ filter_input()
+ filter_var()
+ fseek()
+ get_html_translation_table()
+ gmp_div_q()
+ gmp_div_qr()
+ gmp_div_r()
+ html_entity_decode()
+ htmlspecialchars_decode()
+ http_build_query()
+ http_parse_cookie()
+ http_parse_params()
+ http_redirect()
+ http_support()
+ parse_ini_file()
+ parse_ini_string()
+ parse_url()
+ pathinfo()
+ pg_select()
+ posix_access()
+ round()
+ scandir()
+ socket_read()
+ str_pad()
+ trigger_error()

Here is the list of functions that use a combination of PHP native functions as argument.

+ arsort()
+ asort()
+ error_reporting()
+ filter_input()
+ filter_var()
+ get_html_translation_table()
+ htmlentities()
+ htmlspecialchars()
+ http_build_url()
+ jdtojewish()
+ krsort()
+ ksort()
+ pg_result_status()
+ phpcredits()
+ phpinfo()
+ preg_grep()
+ preg_match()
+ preg_split()
+ rsort()
+ runkit_import()
+ sort()
+ stream_socket_client()
+ stream_socket_server()

Implied If

[Since 0.8.4] - [ -P Structures/ImpliedIf ] - [ Online docs ]

It is confusing to emulate if/then with boolean operators.

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);

// Defines a default value if provided is empty-ish 
// Warning : this is 
$user $_GET['user'] || 'anonymous';
?>


It is recommended to use a real 'if then' structures, to make the condition readable.

Overwritten Literals

[Since 0.8.4] - [ -P Variables/OverwrittenLiterals ] - [ Online docs ]

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);
}
?>

Assign Default To Properties

[Since 0.8.4] - [ -P Classes/MakeDefault ] - [ Online docs ]

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.

No Public Access

[Since 0.8.4] - [ -P Classes/NoPublicAccess ] - [ Online docs ]

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();
?>

Composer Usage

[Since 0.8.4] - [ -P Composer/UseComposer ] - [ Online docs ]

Mark the usage of composer, mostly by having a composer.json file.

Composer's autoload

[Since 0.8.4] - [ -P Composer/Autoload ] - [ Online docs ]

Is this code using the autoload from Composer.

Composer Namespace

[Since 0.8.4] - [ -P Composer/IsComposerNsname ] - [ Online docs ]

Mark this namespace as a Composer namespace.

When the namespace is found in the composer database, it is marked as such.

<?php 
namespace Monolog;

use 
Monolog\Processor\WebProcessor;
use 
Monolog\Handler\TestHandler;

class 
MyLogger extends WebProcessor {
    
/**/
}
?>


See also Packagist.

Should Chain Exception

[Since 0.8.4] - [ -P Structures/ShouldChainException ] - [ Online docs ]

Chain exception to provide more context.

When catching an exception and rethrowing another one, it is recommended to chain the exception : this means providing the original exception, so that the final recipient has a chance to track the origin of the problem. This doesn't change the thrown message, but provides more information.

Note : Chaining requires PHP > 5.3.0.

<?php 
try {
        throw new 
Exception('Exception 1'1);
    } catch (\
Exception $e) {
        throw new 
Exception('Exception 2'2$e); 
        
// Chaining here. 

    
}
?>


See also Exception::__construct and
What are the best practices for catching and re-throwing exceptions?.

Unused Interfaces

[Since 0.8.4] - [ -P Interfaces/UnusedInterfaces ] - [ Online docs ]

Those interfaces are defined and never used. They should be removed, as they are dead code.

Interfaces may be use as parent for other interfaces, as typehint (argument, return and property), in instance of.

<?php 
interface used {}
interface 
unused {}

// Used by implementation
class implements used {}

// Used by extension
interface implements used {}

$x = new c;

// Used in a instanceof
var_dump($x instanceof used); 

// Used in a typehint
function foo(Used $x) {}
?>


Useless Interfaces

[Since 0.8.4] - [ -P Interfaces/UselessInterfaces ] - [ Online docs ]

The interfaces below are defined and are implemented by some classes.

However, they are never used to enforce an object's class in the code, using instanceof or in a typehint.
As they are currently used, those interfaces may be removed without change in behavior.

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


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

<?php 
interface {};
    
    function 
foo(i $arg) { 
        
// Now, $arg is always an 'i'
    
}
    
    function 
bar($arg) { 
        if (!(
$arg instanceof i)) {
            
// Now, $arg is always an 'i'
        
}
    }
?>


Undefined Interfaces

[Since 0.8.4] - [ -P Interfaces/UndefinedInterfaces ] - [ Online docs ]

Some typehints 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
}
?>


See also Object interfaces,
Type declarations, and
Instanceof.

Concrete Visibility

[Since 0.8.4] - [ -P Interfaces/ConcreteVisibility ] - [ Online docs ]

Methods that implements an interface in a class must be public.

PHP does lint this, unless the interface and the class are in the same file. At execution, it stops immediately with a Fatal error : 'Access level to c::iPrivate() must be public (as in class i) ';

<?php 
interface {
    function 
iPrivate() ;
    function 
iProtected() ;
    function 
iPublic() ;
}

class 
implements {
    
// Methods that implements an interface in a class must be public.  
    
private function iPrivate() {}
    protected function 
iProtected() {}
    public function 
iPublic() {}
}
?>


See also Interfaces.

ext/apcu

[Since 0.8.4] - [ -P Extensions/Extapcu ] - [ Online docs ]

Extension APCU .

APCu is APC stripped of opcode caching. The Alternative PHP Cache (APC) is a free and open opcode cache for PHP. Its goal is to provide a free, open, and robust framework for caching and optimizing PHP intermediate code.

<?php 
$bar 'BAR';
apcu_add('foo'$bar);
var_dump(apcu_fetch('foo'));
echo \
n;
$bar 'NEVER GETS SET';
apcu_add('foo'$bar);
var_dump(apcu_fetch('foo'));
echo \
n;
?>


See also APCU,
ext/apcu and
krakjoe/apcu.

Double Instructions

[Since 0.8.4] - [ -P Structures/DoubleInstruction ] - [ Online docs ]

Twice the same call in a row. This is worth a check.

<?php 
// repetition of the same command, with the same effect each time. 
$a array_merge($b$c);
$a array_merge($b$c);

// false positive : commands are identical, but the effect is compounded 
$a array_merge($a$c);
$a array_merge($a$c);
?>

Should Use Prepared Statement

[Since 0.8.4] - [ -P Security/ShouldUsePreparedStatement ] - [ Online docs ]

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

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

<?php 
/* Execute a prepared statement by passing an array of values */

$sql 'SELECT name, colour, calories
    FROM fruit
    WHERE calories < :calories AND colour = :colour'
;
$sth $conn->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute(array(':calories' => 150':colour' => 'red'));
$red $sth->fetchAll();
?>


Same code, without preparation :

<?php 
$sql 'SELECT name, color, calories FROM fruit WHERE calories < '.$conn-quote(150).' AND colour = '.$conn->quotes('red').' ORDER BY name';
    
$sth $conn->query($sql) as $row);
}
?>


See also Prepared Statements,
PHP MySQLi Prepared Statements Tutorial to Prevent SQL Injection,
The Best Way to Perform MYSQLI Prepared Statements in PHP.

Hash Algorithms Incompatible With PHP 5.3

[Since 0.8.4] - [ -P Php/HashAlgos53 ] - [ Online docs ]

List of hash algorithms incompatible with PHP 5.3.

<?php 
// Compatible only with 5.3 and more recent
echo hash('md2''The quick brown fox jumped over the lazy dog.');

// Always compatible
echo hash('ripemd320''The quick brown fox jumped over the lazy dog.');
?>


See also hash_algos.

Hash Algorithms Incompatible With PHP 5.4/5.5

[Since 0.8.4] - [ -P Php/HashAlgos54 ] - [ Online docs ] - [ PHP older than 5.4]

List of hash algorithms incompatible with PHP 5.4 and 5.5.

<?php 
// Compatible only with 5.4 and more recent
echo hash('fnv132''The quick brown fox jumped over the lazy dog.');

// Always compatible
echo hash('ripemd320''The quick brown fox jumped over the lazy dog.');
?>


See also hash_algos.

Print And Die

[Since 0.8.4] - [ -P Structures/PrintAndDie ] - [ Online docs ]

Die() also prints.

When stopping a script with die(), it is possible to provide a message as first argument, that will be displayed at execution. There is no need to make a specific call to print or echo.

<?php 
//  die may do both print and die.
echo 'Error message';
die();

//  exit may do both print and die.
print 'Error message';
exit;

//  exit cannot print integers only : they will be used as status report to the system.
print 'Error message';
exit 
1;
?>


Unchecked Resources

[Since 0.8.4] - [ -P Structures/UncheckedResources ] - [ Online docs ]

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;
}

// unsafe one-liner : using bzclose on an unchecked resource
bzclose(bzopen('file'));
?>


See also resources.

Class Const With Array

[Since 0.8.4] - [ -P Php/ClassConstWithArray ] - [ Online docs ] - [ PHP 5.5 and more recent ]

Constant defined with const keyword may be arrays but only stating with PHP 5.6. Define never accept arrays : it only accepts scalar values.

ext/trader

[Since 0.8.4] - [ -P Extensions/Exttrader ] - [ Online docs ]

Extension trader.

The trader extension is a free open source stock library based on TA-Lib. It's dedicated to trading software developers requiring to perform technical analysis of financial market data.

<?php 
// get_data() reads the data from a source 
var_dump(trader_avgprice(
    
get_data(open$data0),
    
get_data(high$data0),
    
get_data(low$data0),
    
get_data(close$data0)
));
?>


See also trader, 'TA-lib _ and `Trader.

ext/mailparse

[Since 0.8.4] - [ -P Extensions/Extmailparse ] - [ Online docs ]

Extension mailparse.

Mailparse is an extension for parsing and working with email messages. It can deal with RFC 822 (MIME) and RFC 2045 (MIME) compliant messages.

<?php 
$mail mailparse_msg_create();
mailparse_msg_parse($mail$mailInString);
$parts mailparse_msg_get_structure($mail); 

foreach(
$parts as $part) { 
    
$section mailparse_msg_get_part($mail$part); 
    
$info mailparse_msg_get_part_data($section); 
}
?>


See also Mailparse.

ext/mail

[Since 0.8.4] - [ -P Extensions/Extmail ] - [ Online docs ]

Extension for mail.

The mail() function allows you to send mail.

<?php 
// The message
$message "Line 1\r\nLine 2\r\nLine 3";

// In case any of our lines are larger than 70 characters, we should use `wordwrap() <https://www.php.net/wordwrap>`_
$message wordwrap($message70"\r\n");

// Send
mail('caffeinated@example.com''My Subject'$message);
?>


See also Mail related functions.

Unresolved Catch

[Since 0.8.4] - [ -P Classes/UnresolvedCatch ] - [ Online docs ]

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
}
?>


No Hardcoded Ip

[Since 0.8.4] - [ -P Structures/NoHardcodedIp ] - [ Online docs ]

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.

See also Use of Hardcoded IPv4 Addresses and
Never hard code sensitive information.

Variable Global

[Since 0.8.3] - [ -P Structures/VariableGlobal ] - [ Online docs ] - [ PHP older than 7.0]

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};
?>


Else If Versus Elseif

[Since 0.8.4] - [ -P Structures/ElseIfElseif ] - [ Online docs ]

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 == 2doSomethingElseIf(); 
else  
doSomethingElse();
?>


See also elseif/else if.

Reserved Keywords In PHP 7

[Since 0.8.4] - [ -P Php/ReservedKeywords7 ] - [ Online docs ] - [ PHP older than 7.0]

PHP reserved names for class/trait/interface. They won't be available anymore in user space starting with PHP 7.

For example, string, float, false, true, null, resource,... are not acceptable as class name.

<?php 
// This doesn't compile in PHP 7.0 and more recent
class null { }
?>


See also List of other reserved words.

Unset In Foreach

[Since 0.8.4] - [ -P Structures/UnsetInForeach ] - [ Online docs ]

Unset applied to the variables of a foreach loop are useless. Those variables are copies and not the actual value. Even if the value is a reference, unsetting it has no effect on the original array : the only effect may be indirect, on elements inside an array, or on properties inside an object.

<?php 
// When unset is useless
$array = [123];
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] ]
?>


See also foreach.

Could Be Class Constant

[Since 0.8.4] - [ -P Classes/CouldBeClassConstant ] - [ Online docs ]

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.

Could Be Static

[Since 0.8.4] - [ -P Structures/CouldBeStatic ] - [ Online docs ]

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
}
?>

Multiple Class Declarations

[Since 0.8.4] - [ -P Classes/MultipleDeclarations ] - [ Online docs ]

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.

Compare Hash

[Since 0.8.4] - [ -P Security/CompareHash ] - [ Online docs ]

When comparing hash values, it is important to use the strict comparison : hash_equals(), === 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.'.PHP_EOL;
}

// hash returns a string, that is mistaken with 0 by PHP
// The strength of the hashing algorithm is not a problem
if (hash('ripemd160','20583002034',false) == '0') {
  print 
'Matched.'.PHP_EOL;
}

if (
hash('md5','240610708',false) !== $hashed_password) {
  print 
'NOT Matched.'.PHP_EOL;
}

// Display true
var_dump(md5('240610708') == md5('QNKCDZO') );
?>


You may also use password_hash() and password_verify() : they work together without integer conversion problems, and they can't be confused with a number.

See also Magic Hashes
What is the best way to compare hashed strings? (PHP) and
md5('240610708') == md5('QNKCDZO').

Empty Namespace

[Since 0.8.4] - [ -P Namespaces/EmptyNamespace ] - [ Online docs ]

Declaring a namespace in the code and not using it for structure declarations or global instructions is useless.

Using simple style :

<?php 
namespace Y;

class 
foo {}


namespace 
X;
// This is useless
?>


Using bracket-style syntax :

<?php 
namespace {
    
// This is useless
}

namespace 
{

    class 
foo {}

}
?>



Could Use Short Assignation

[Since 0.8.4] - [ -P Structures/CouldUseShortAssignation ] - [ Online docs ]

Use short assignment operator, to speed up code, and keep syntax clear.

Some operators, like * or +, have a compact and fast '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.

Depending on the operator, not all permutations of arguments are possible.

Addition and short assignation of addition have a different set of features when applied to arrays. Do not exchange one another in that case.

<?php 
$a 10 $a;
$a += 10;

$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;

// PHP 7.4 and more recent
$l $l ?? 'value';
$l ??= 'value';
?>


Short operators are faster than the extended version, though it is a micro-optimization.

See also Assignation Operators.

Useless Abstract Class

[Since 0.8.4] - [ -P Classes/UselessAbstract ] - [ Online docs ]

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() {}
}
?>


Null On New

[Since 0.8.4] - [ -P Classes/NullOnNew ] - [ Online docs ] - [ PHP older than 7.0]

Until PHP 7, 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

See also PHP RFC: Constructor behaviour of internal classes.

Scalar Typehint Usage

[Since 0.8.4] - [ -P Php/ScalarTypehintUsage ] - [ Online docs ] - [ PHP 7.0 and more recent ]

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

Scalar typehint are PHP 7.0 and more recent. Some, like object , is 7.2.

Scalar typehint were not supported in PHP 5 and older. Then, the typehint is treated as a class name.

<?php 
function withScalarTypehint(string $x) {}

function 
withoutScalarTypehint(someClass $x) {}
?>


See also PHP RFC: Scalar Type Hints and Type declarations.

Return Typehint Usage

[Since 0.8.4] - [ -P Php/ReturnTypehintUsage ] - [ Online docs ] - [ PHP 7.0 and more recent ]

Spot usage of return typehint. It is a PHP 7.0 feature.

Return typehint were introduced in PHP 7.0, and are backward incompatible with PHP 5.x.

<?php 
function foo($a) : stdClass {
    return new \
stdClass();
}
?>


See also RFC: Return Type Declarations and
Return Type Declarations.

ext/ob

[Since 0.8.4] - [ -P Extensions/Extob ] - [ Online docs ]

Extension Output Buffering Control.

The Output Control functions allow you to control when output is sent from the script.

<?php 
`ob_start() <https://www.php.net/ob_start>`_;
echo 
Hello\n;

setcookie(cookienamecookiedata);

`
ob_end_flush() <https://www.php.net/ob_end_flush>`_;
?>



See also Output Buffering Control.

Static Loop

[Since 0.8.4] - [ -P Structures/StaticLoop ] - [ Online docs ]

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;
}

// The above loop may be replaced by (with some math help)
$total 10 * (10  1) / 2;

// Non-Static loop (the loop depends on the size of the array