Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

PHP dictionary is an exhaustive list of words and notions, from the PHP ecosystem.

Do you know what is the ‘dangling reference’ problem? Or the Last Static binding? or the ‘garbage collection’?

The PHP dictionary provides a list of words, concepts, keywords and expressions used commonly in the PHP ecosystem, with a short definition and extra links to more resources.

The dictionary’s goal is to provide a place for each PHP notions, and help anyone reading an article understand it.

The dictionary doesn’t aim to provide a complete presentation of the definitions : this is why there are external links to blogs, vlogs, documentation and disambiguation. Links to software are also provided without the guarantee to be systematic nor complete.

Contributions

Contributions are welcomed, by submitting PR to the repository

  • New or missing words to be added, preferably with their definition
  • Extra links to external resources
  • Documentation complements
  • Checks on the related notions and thesaurus

Thesaurus

Acronym

List of acronyms, used in this dictionary.

Attribute

List of PHP native attributes.

Concept

List of concept, which are applied to PHP, but not exclusive to it.

Control flow

List of command to control the flow of a program.

Directive

List of configuration directives of PHP. They may be used in php.ini, ini_set()/ini_get() or other configuration files.

Exception

List of exceptions, available in PHP.

Keyword

List of PHP keywords and reserved names.

Language construct

List of the PHP language construct: they look like a function, but are more special.

Type

List of PHP types, used with the type system. They usually are not related to a class.

Magic method

List of PHP magic method, which are providing special behavior throught the definition of a method with a special signature.

Classic bug

List of named bugs.

Extension

List of special PHP extensions.

Token

List of strings (characters, names), which are PHP tokens: they are useful to parse code.

Folklore

List of things that seems unrelated to PHP, but, suprisingly, are.

Static analysis

List of concepts related to static code analysis.

Character

List of single characters, and their special usage.

Disambiguation

List of concepts that cover several fields, and usually require extra details to avoid confusion.

Unsupported

List of features supported in other languages, but not natively by PHP +

Adjective

List of adjective that are used with several distinct noun, and carry similar concept in different aspects of software science.

Animal

List of animals in the PHP ecosystem and its folklore.

Authors

People mentioned across the PHP Dictionary, with a link to their homepage or profile.

Brands

Tools, services and products mentioned across the PHP Dictionary, with a link to their homepage or repository.

$HTTP_RAW_POST_DATA

$HTTP_RAW_POST_DATA used to contain the raw POST data of an HTTP request.

$HTTP_RAW_POST_DATA was removed in version 7.0: it is replaced by php://input.

<?php

    // $a->file was filled with $_FILES at some point
    move_uploaded_file($a->file['tmp_name'], $target);

?>

Documentation

See Also

$_FILES

The $_FILES variable is a special superglobal variable that is used to retrieve information about files uploaded to the server via HTML forms with the enctype="multipart/form-data" attribute. It provides access to the uploaded file’s properties such as name, size, type, and temporary location on the server.

When a file upload form is submitted, PHP populates the $_FILES variable with an array structure that contains information about the uploaded files. The array is organized based on the input field names used in the form.

  • $_FILES['userfile']['name']: the original name of the file on the client machine
  • $_FILES['userfile']['type']: the mime type of the file, if the browser provided this information. An example would be "image/gif". This mime type is however not checked on the PHP side and therefore don’t take its value for granted
  • $_FILES['userfile']['size']: the size, in bytes, of the uploaded file
  • $_FILES['userfile']['tmp_name']: the temporary filename of the file in which the uploaded file was stored on the server
  • $_FILES['userfile']['error']: the error code associated with this file upload
  • $_FILES['userfile']['full_path']: the full path as submitted by the browser. This value does not always contain a real directory structure, and cannot be trusted. Available as of PHP 8.1.0

$_FILES is associated to the functions move_uploaded_file() and is_uploaded_file().

<?php

    // $a->file was filled with $_FILES at some point
    move_uploaded_file($a->file['tmp_name'], $target);

?>

Documentation

See Also

$_COOKIE

The $_COOKIE variable is a special superglobal variable that stores the name and values of the cookies that were transmitted to the webserver.

The $_COOKIE variable is an associative array where the keys are the cookies names and the values are the corresponding values passed in the HTTP headers.

$_COOKIE is a superglobal: it is always available, in every scope.

Values inside $_COOKIE are always strings or arrays.

<?php

    echo $_COOKIE['username'];

?>

Documentation

See Also

$_ENV

The $_ENV variable is a special superglobal variable that is used to retrieve the environment values.

The $_ENV variable is an associative array where the keys are the global variables and the values are the corresponding values.

$_ENV is a superglobal: it is always available, in every scope.

Values inside $_ENV are always strings.

The values in the $_ENV are collected at the start of the script, and do not change during the lifetime of the script. To get an up-to-date value, the function getenv() is preferable.

The content of the $_ENV array varies from installation to installation: there is no default list of keys in that array. It entirely depends on the underlying system.

<?php

    // Displays the name of the user
    echo $_ENV['USER'];

    print_r($_ENV);
    // Results is similar to this 
    /**
    Array
    (
        [TERM] => xterm
        [PATH] => /usr/bin:/bin
        [LANG] => C
        [SHELL] => /bin/sh
        [MAIL] => /var/mail/nobody
        [LOGNAME] => nobody
        [USER] => nobody
        [HOME] => /tmp
    )
    */

?>

Documentation

See Also

$_GET

The $_GET variable is a special superglobal variable that is used to retrieve data from the query string or URL parameters. When a user submits a form using the HTTP GET method or includes parameters in the URL, PHP populates the $_GET variable with key-value pairs representing those parameters.

The $_GET variable is an associative array where the keys are the parameter names and the values are the corresponding values passed in the URL.

The received values are strings or arrays. They are strings by default, and other scalar types need to be cast to have the correct type. The values are arrays when the URL uses the [] format: that format handles arrays and maps.

$_GET is a superglobal, or auto-global: it is always available, in every scope.

Values inside $_GET are always strings, or arrays. https://www.site.com/index.php?x=1 or https://www.site.com/index.php?x[2]=1.

<?php

    // https://www.example.com/index.php?x=1
    $_GET['x'] === '1';
    
    // https://www.example.com/index.php?y=abc
    $_GET['y'] === 'abc';
    
    // https://www.example.com/index.php?z[]=def&z[][]=ghi
    $_GET['z'] === ['def', ['ghi']];

?>

Documentation

See Also

$_POST

$_POST is an associative array of variables, transmitted to the current script via the HTTP POST method, with the MIME types application/x-www-form-urlencoded or multipart/form-data.

The received values are all strings or arrays. They are strings by default, and other scalar types need a casting. The values are arrays when the URL uses the [] format.

$_POST is a superglobal: it is always available, in every scope.

Values inside $_POST are always strings, or arrays.

<?php

    // POST x=1
    $_POST['x'] === '1';
    
    // POST y=abc
    $_POST['y'] === 'abc';
    
    // POST z[]=def
    // POST z[]=ghi
    $_POST['z'] === ['def', 'ghi'];

?>

Documentation

See Also

$_REQUEST

An associative array of variables, transmitted to the current script via the HTTP GET and HTTP methods.

When the same name is used both in GET and POST method, the priority is defined by the variable_order directive.

The received values are all strings or arrays. They are strings by default, and other scalar types needs a casting. The values are arrays when the URL uses the [] format.

$_REQUEST is a superglobal: it is always available, in every scope.

<?php

    // https://www.example.com/index.php?x=1
    $_REQUEST['x'] === '1';
    
    // POST y=abc
    $_REQUEST['y'] === 'abc';
    
    // https://www.example.com/index.php?z[]=def&z[]=ghi
    $_REQUEST['z'] === ['def', 'ghi'];

?>

Documentation

See Also

$_SERVER

The $_SERVER variable is a special superglobal variable that holds information about the headers, scripts and path locations.

The entries in this array are created by the web server, therefore there is no guarantee that every web server provides any of these.

The $_SERVER variable is an associative array where the keys are the variable names and the values are the corresponding values.

$_SERVER is a superglobal: it is always available, in every scope.

<?php

    echo $_SERVER['PHP_SELF'];

?>

Documentation

See Also

$argc

$argc is a predefined variable that holds the number of arguments passed to the script when it is executed from the command line. It represents the argument count, hence the name $argc.

When a PHP script is run from the command line, the script’s filename is counted as the first argument, and any additional arguments passed after the filename are also counted. The value of $argc is an integer indicating the total number of arguments.

<?php

    echo $argc;

?>

Documentation

See Also

$argv

$argv is a PHP variable that contains an array of the arguments passed to the PHP script, in the command line. $argv is not defined when PHP is run in a webserver.

$argv is not a superglobal: it has to be imported in a non-global scope with the global keyword.

<?php

    print_r($argv);

?>

Documentation

See Also

$GLOBALS

This super-global is a PHP predefined variable, which holds a reference to every global variable in the application. It behaves as an associative array, where each key is the name of a global variable and each value is a reference to that variable, so reading or writing $GLOBALS['x'] inside a function is equivalent to declaring global $x; first. Because it bypasses normal variable scoping, relying on $GLOBALS makes code harder to test and reason about, and it is generally considered a code smell in modern PHP, where dependency injection or object properties are preferred. Since PHP 8.1, some indirect writes to $GLOBALS – through list assignment, by-reference foreach, or array functions – are restricted, since they no longer directly modify the underlying global variable.

<?php

    // implicit global variable
    $aGlobalVariable = 1; 
    
    function trumpet() {
        echo $GLOBALS['aGlobalVariable'];
        $GLOBALS['aGlobalVariable'] = 2;
    }

    trumpet(); // displays 1
    echo aGlobalVariable; // 2

?>

Documentation

See Also

$http_response_header

$http_response_header contains the list of HTTP headers, as returned after a remote URI call, with fopen() or file_get_contents(). It is the same as the result of the function get_headers().

$http_response_header is not a superglobal: it is created in the local scope where the HTTP call was made, and is not automatically available in the calling scope.

This feature is deprecated in version 8.5.

<?php

    // Example extracted from the manual
    function get_contents() {
        file_get_contents('http://example.com');
        var_dump($http_response_header); // variable is populated in the local scope
    }

    get_contents();
    var_dump($http_response_header); // a call to get_contents() does not populate the variable outside the function scope

?>

Documentation

See Also

$php_errormsg

$php_errormsg contains the last error message, emitted by PHP.

In general, error_get_last() should be used instead of $php_errormsg, although this function returns an array, not a string.

This feature was removed in version 8.0.

<?php

    // Warning: Undefined variable $php_errormsg 
    // in PHP 8.0 (sic)
    echo $php_errormsg;

    print_r(error_get_last());

?>

Documentation

See Also

$this

$this is a variable that represents the current object instance. Its value is different for each object, and remains the same throughout every non-static method call made on that object.

$this is also called a pseudo-variable. It is never explicitly set, but is available as soon as a non-static method starts. It is also never available, nor can even be created, outside a method.

$this cannot be unset, nor assigned a different value than the current object. This means it cannot be used as the name of a function or method parameter, as a global variable global $this;, or as an explicit lexical variable in a closure use ($this).

Closures and arrow functions defined inside a non-static method automatically have access to $this, without needing to import it with use. A closure declared with the static keyword has no access to $this. A named function declared inside a method, on the other hand, is not a closure, and does not have access to $this either.

$this is not available in static methods, as they do not require an object to be invoked.

When a non-static method is invoked with the :: syntax from another method of a related class, for example parent::method() or self::method(), $this still refers to the calling object.

In a trait, $this refers to the object of the class that uses the trait, not to the trait itself.

$this may use the array syntax, if the underlying class supports the ArrayAccess interface.

There is no special variable called $that.

<?php

    class Elephpant {
        private $trunkLength = 1;

        function trumpet() {
            return $this->trunkLength;
        }
    }

?>

Documentation

See Also

__autoload

__autoload() was the name of the userland function, used to load classes when they were not found yet in the current execution environment.

__autoload() was later replaced with spl_autoload_register(), which allows the composition of multiple autoloading methods.

<?php

    function __autoload($name) {
        if (file_exists(classes/$name.php)) {
            include classes/$name.php;
        }
    }

?>

Documentation

See Also

__call() Method

__call() is a magic method: it is called when a method cannot be accessed, either because it doesn’t exist, or because its visibility prevents it.

That way, it is possible to dynamically create methods, without hardcoding them.

The __call() method receives the name of the target-method, and a list of arguments, as an array.

The __call() method has a related version for static methods, called __callStatic().

<?php

    class Elephpant {
        private $values = ['a' => 1,
                           'b' => 2,
                           ];

        // Checks the dictionary, or return 0
        function __call($name, $args) {
            if (method_exists($this, $name)) {
                return $this->$name(...$args);
            }
            
            return 0;
        }
    }

?>

Documentation

See Also

__callStatic() Method

__callStatic() is a magic method: it is called when a static method cannot be accessed: either because it doesn’t exist or because its visibility prevents it.

__callStatic() is not called when the method exists and is not static.

That way, it is possible to create dynamically static methods, without hardcoding them.

The __callStatic() method receives the name of the target-method, and a list of arguments.

The __callStatic() method has a related version for non-static methods, called __call().

<?php

    class Elephpant {
        // Checks the dictionary, or return 0
        static function __callStatic($name, $args) {
            if (method_exists(self::class, $name)) {
                return Elephpant::$name(...$args);
            }

            return 0;
        }

        private static function trumpet() {
            print __METHOD__;
        }
    }

    Elephpant::trumpet(); // Elephpant::trumpet
    Elephpant::forage(); // nothing

?>

Documentation

See Also

__CLASS__

__CLASS__ holds the current class name: this is the class of definition, not the called class. It is not the same as self::class, which may change depending on the calling context.

The class name includes the namespace it was declared in, such as N\X. It does not include the leading \.

When used inside a trait method or property default, __CLASS__ is the name of the class the trait is used in. When used outside a function, this constant holds an empty string, and does not emit any warning.

This constant is written in uppercase, by convention. It is case-insensitive, and may be used with any combination of uppercase and lowercase.

<?php

    namespace N; 
    
    class Elephpant {
        function trumpet() {
            echo __CLASS__;  // N\Elephpant
        }
    }

?>

Documentation

See Also

__clone() Method

To clone an object is to create a new distinct object, from an existing one. This is basically a copy, although the object itself is multiplied by calling the clone operator.

By default PHP does a shallow clone, duplicating the scalars, like string, integer…, and keeping the same reference to objects. To make a deep clone, the class must define the __clone magic method.

Cloning is similar to creating another object of the same class, without requiring all the constructor arguments.

<?php

    $spike = new Dog('Spike', 'Teckel', 'red');
    $medor = clone $spike;
    
    $medor->setCollar('green'); // distinguish spike and medor by collar

?>

Documentation

See Also

__debugInfo() Method

__debugInfo() is called by var_dump() to customize the information displayed for an object.

By default, var_dump() shows every property of an object, including private and protected ones. When __debugInfo() is defined, its return value is shown instead, allowing sensitive properties to be hidden, computed values to be added, or the output to be simplified.

__debugInfo() must return an array. The keys become the displayed property names, and are not required to match actual property names.

__debugInfo() was introduced in version 5.6. Before that version, var_dump() always displays the object’s actual properties, and the method, if present, is simply ignored.

__debugInfo() is a magic method.

<?php

    class Elephpant {
        private $public = 'a';
        private $secret = 'password';

        function __debugInfo() {
            return ['public' => $this->public,
                    'secret' => '***redacted***'];
        }
    }

    var_dump(new Elephpant);

?>

Documentation

See Also

__DIR__

__DIR__ holds the directory of the current file.

It is equivalent to dirname(__FILE__). The directory name does not have a trailing slash unless it is the root directory.

When used inside an include, the directory of the included file is returned.

This constant is case insensitive, and may be used with any combination of uppercase and lowercase.

<?php

    // Assume file is at /var/www/html/index.php
    echo __DIR__; // /var/www/html

    // Useful for requiring files relative to current script
    require __DIR__ . '/config.php';

?>

Documentation

See Also

__FILE__

__FILE__ holds the current file name.

The file name includes its absolute path, e.g. /tmp/path/to/file.txt. It also uses the file’s actual case.

When used without a file, aka in the command line, __FILE__ contains Command line code.

__FILE__ is often used with __LINE__, which holds the line number.

__FILE__ is also often used with __DIR__, which holds the directory of the file. It is akin to using dirname() on __FILE__.

This constant is written in uppercase, by convention. It is case-insensitive, and may be used with any combination of uppercase and lowercase.

<?php

    function trumpet() {
        echo __FILE__; // /tmp/test.php
    }

    trumpet();

?>

Documentation

See Also

__FUNCTION__

__FUNCTION__ holds the current function or method name.

The function name includes the namespace it was declared in, e.g. N\X\foo. It also uses the definition’s case.

When used inside a method, __FUNCTION__ is the name of the method it is used in. When used outside a function, this constant holds an empty string, and does not emit any warning.

__METHOD__ and __FUNCTION__ are almost identical.

This constant is written in uppercase, by convention. It is case insensitive, and may be used with any combination of uppercase and lower case.

<?php

    function trumpet() {
        echo __FUNCTION__; // trumpet
    }

    function STAMPEDE() {
        echo __function__; // STAMPEDE
    }

    class Elephpant {
        function trumpet() {
            echo __FUNCTION__; // trumpet
        }
    }

    trumpet();
    (new Elephpant)->trumpet();

?>

Documentation

See Also

__get() Method

__get() is a magic method: it is utilized for reading data from inaccessible, either protected or private, or non-existing properties.

That way, it is possible to dynamically create properties, without hardcoding them.

The __get() method is usually paired with the __set() method.

The method signature is public function __get(string $name): mixed. The $name argument is the name of the property being interacted with.

The method must be declared as public, or it is implicit. Arguments cannot be passed by reference. Property overloading only works in object context and will not be triggered in static context.

__get() is never called when chaining assignments together like $a = $obj->b = 8;. PHP will not call an overloaded method from within the same overloaded method: writing return $this->foo inside of __get() will return null and raise an E_WARNING if there is no foo property defined, rather than calling __get() a second time.

<?php

    class Elephpant {
        private $values = ['a' => 1,
                           'b' => 2,
                           ];

        // Checks the dictionary, or return 0
        function __get($name) {
            if (isset($this->values[$name])) {
                return $this->values[$name];
            }
            
            return 0;
        }
    }

?>

Documentation

See Also

__halt_compiler()

__halt_compiler() halts the execution of the compiler. This is useful to embed data alongside code, like the installation files.

Byte position of the data start can be determined by the __COMPILER_HALT_OFFSET__ constant which is defined only if there is a __halt_compiler() presented in the file.

<?php

    // adapted from the manual
    
    // 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(); This part of the file is read by the script.

Documentation

See Also

__invoke() Method

The __invoke() magic method is called when the code calls an object as a function name. This type of class is also called a functor.

The method is able to take an arbitrary number of arguments, as usual.

When a class has the __invoke method, it is possible to call a method on its objects without mentioning a method’s name: the object itself is the method.

__invoke is also considered as the anonymous method: it is called without using its name.

<?php

    // extracted from the PHP manual
    class CallableClass
    {
        public function __invoke($trunk)
        {
            var_dump($trunk);
        }
    }

    $obj = new CallableClass;
    $obj(5);
    var_dump(is_callable($obj));

?>

Documentation

See Also

__isset() Method

__isset() is a magic method: it is called when the existence of a property has to be checked.

That way, it is possible to create dynamically properties, without hardcoding them.

The __isset() method is usually paired with the __get() and __set() methods.

The __isset() is called by isset() and empty(). They are also called by the coalesce operator ?? and ??=. It is not called on null-safe object operator ?->.

<?php

    class Elephpant {
        private $values = ['a' => 1,
                           'b' => 2,
                           ];

        function __isset($name) {
            return isset($this->values[$name]);
        }
    }

    $elephpant = new Elephpant;
    var_dump(isset($elephpant->a)); // true
    var_dump(empty($elephpant->c)); // false

?>

Documentation

See Also

__LINE__

__LINE__ holds the current line number in the current file.

The line numbers starts at 1. It is always available.

__LINE__ is often used with __FILE__, which holds the file name.

This constant is written in uppercase, by convention. It is case insensitive, and may be used with any combination of uppercase and lower case.

<?php

    function trumpet() {
        echo __FILE__.':'.__LINE__; // /tmp/test.php:4
    }

trumpet();

?>

Documentation

See Also

__METHOD__

__METHOD__ holds the current method or function name.

The method name includes the namespace and the class it was declared in, e.g. N\X::foo. It also uses the definition’s case.

When used inside a method, __METHOD__ is the name of the method it is used in. When used outside a function, this constant holds an empty string, and does not emit any warning.

__METHOD__ and __FUNCTION__ are almost identical.

This constant is written in uppercase, by convention. It is case insensitive, and may be used with any combination of uppercase and lower case.

<?php

    function trumpet() {
        echo __METHOD__; // trumpet
    }

    function STAMPEDE() {
        echo __method__; // STAMPEDE
    }

    class Elephpant {
        function trumpet() {
            echo __METHOD__; // trumpet
        }
    }

    trumpet();
    (new Elephpant)->trumpet();

?>

Documentation

See Also

__serialize() Method

The __serialize() method is called when a script tries to construct an associative array of key/value pairs that represent the serialized form of the object.

When no array is returned, a TypeError is thrown.

__serialize() is a magic method.

<?php

    class WebPage {
        private $html;
        private $url;

        public function __construct($url) {
            $this->url = $url;
        }

        public function __serialize() {
            return ['url' => $url];
        }

        public function __unserialize($arg) {
            $this->url = $arg['url'];
            $this->html = file_get_contents($this->url);
        }
    }

?>

Documentation

See Also

__set() Method

__set() is a magic method: it is called when writing data to inaccessible, either protected or private, or non-existing properties. It is used to give a value to the property.

That way, it is possible to create dynamically properties, without hardcoding them.

The __set() method is usually paired with the __get() method.

The method signature is public function __set(string $name, mixed $value): void. The $name argument is the name of the property being interacted with. The $value argument specifies the value the $name-ed property should be set to. The return value of __set() is ignored because of the way PHP processes the assignment operator.

The method must be declared as public, or it is implicit. Arguments cannot be passed by reference. Property overloading only works in object context and will not be triggered in static context.

<?php

    class Elephpant {
        private $values = ['a' => 1,
                           'b' => 2,
                           ];

        // Checks the dictionary, or return 0
        function __set($name, $value) {
            if (isset($this->values[$name])) {
                $this->values[$name] = $value;
            }
            
            //do not set new values
        }
    }

?>

Documentation

See Also

__set_state() Method

__set_state() is called when an object has been exported with var_export(), and has to be instantiated again.

__set_state() is tasked with recreating the object, assigning the previous values to it, and recreating any missing properties, such as database connections or resources.

The __set_state() method has no counterpart: var_export() does not use any magic method.

__set_state() is a static method, unlike the other magic methods. __set_state() is a magic method.

<?php

    class Elephpant {
        private $values = ['a' => 1,
                           'b' => 2,
                           ];
    
        // Checks the dictionary, or return 0
        public static function __set_state($array) {
            $object = new self();
    
            // This takes advantage of PHP object invasion
            $object->values['a'] = $array['a'] ?? '0';
            $object->values['b'] = $array['b'] ?? '0';
            
            return $object;
        }
    }

?>

Documentation

See Also

__sleep() Method

__sleep() is a magic method: it is called when an object is being serialized, so that the object may be cleaned.

In particular, some resources, such as database connections or files, cannot be serialized. They should be closed, stored as a path, and reopened later with __wakeup().

The __sleep() method is usually paired with the __wakeup() method.

__sleep() must return an array listing, as strings, the names of the properties that should be serialized. Any property left out of that array is discarded, and reset to its default value once the object is unserialized.

If __sleep() does not return an array, PHP emits a warning and null is serialized instead of the object’s properties.

__sleep() cannot return the names of private properties declared in a parent class: doing so raises a notice. __serialize() and __unserialize() should be used instead when finer control over the serialized data, or access to inherited private properties, is needed.

<?php

    class Elephpant {
        private $file;
        private $path;

        function __sleep() {
            fclose($this->file);
            return ['path'];
        }

        function __wakeup() {
            $this->file = fopen($this->path, 'r');
        }
    }

?>

Documentation

See Also

__toString() Method

__tostring() is a magic method: it is called when the object has to be converted into a string.

That way, it is possible to dynamically convert the object to a string and display it, or transmit it to another part of the application.

__toString() is called when strict_types is not active. Otherwise, passing an object to a string parameter yields an error: it requires an explicit type cast.

__toString() is always called in concatenation, and string interpolation.

There is no magic method to convert an object to another type.

__toString() must be declared public, take no arguments, and return a string: returning anything else triggers a fatal error, or a TypeError when a : string return type is declared.

Since PHP 8.0, any class that defines __toString() automatically implements the Stringable interface, without having to declare it explicitly.

Since PHP 7.4, exceptions may be thrown from within __toString(); in earlier versions, doing so resulted in a fatal error.

<?php

    class Elephpant {
        private $habitat = 'S';
        private $weight = 1;
        private $age = 2;

        // Checks the dictionary, or return 0
        function __toString() : string {

            // $this->habitat is used as is
            // $this->weight is formatted with quotes
            // $this->age is converted to other values
            return "$this->habitat '$this->weight' ".($this->age ? 'A' : 'B');
        }
    }

    echo new Elephpant;

    $trunk = (string) new Elephpant;

?>

Documentation

See Also

__TRAIT__

__TRAIT__ holds the current trait name: this is the trait of definition, not the called class. It is not the same as self::class, which may change depending on the calling context.

The trait name includes the namespace it was declared in, e.g. N\X. It does not include the leading \.

When used outside a trait, __TRAIT__ is empty.

This constant is written in uppercase, by convention. It is case insensitive, and may be used with any combination of uppercase and lower case.

<?php

    namespace N; 
    
    trait Trumpeting {
        function trumpet() {
            echo __TRAIT__;  // N\Trumpeting
            echo __CLASS__;  // N\Elephpant
        }
    }

    class Elephpant {
        use Trumpeting;
    }

?>

Documentation

See Also

__unserialize() Method

The __unserialize() magic method is called when a script tries to construct an object from an associative array of key/value pairs.

__unserialize() was introduced in version 7.4, as the modern replacement for the Serializable interface. It is called by unserialize() on a freshly created, uninitialized instance of the class, receiving as its only argument the array that was returned by __serialize() at the time the object was serialized. The method is responsible for reading that array and restoring every property to its former value.

Unlike the older Serializable::unserialize(), __unserialize() works with a plain PHP array instead of a raw string, so there is no need to handle a custom string format by hand. It is meant to be used together with __serialize(): if a class defines one of the two magic methods, it should define the other. When neither is present, PHP falls back to serializing the object’s properties directly, including private and protected ones, which is also what __wakeup() and __sleep() used to control before the magic methods were introduced.

Because unserialize() can be called on untrusted input, most notably user-supplied cookies, session data or request payloads, the code inside __unserialize() should validate the incoming array carefully. A crafted array which does not match the expected shape may otherwise be used to build objects in an unexpected state, which is the basis of PHP object injection and insecure deserialization attacks.

<?php

    class Elephpant {
        private $html;
        private $url;

        public function __construct($url) {
            $this->url = $url;
        }

        public function __serialize() {
            return ['url' => $url];
        }

        public function __unserialize($arg) {
            $this->url = $arg['url'];
            $this->html = file_get_contents($this->url);
        }

    }

?>

Documentation

See Also

__unset() Method

__unset() is called when the code unsets, or removes a magic property. That way, it is possible to remove dynamically properties. Hardcoded properties are reset to their default state, and do not call this magic method.

The __unset() method is usually paired with the __isset() and __set() methods.

__unset() is a magic method.

<?php

    class Elephpant {
        private $values = ['a' => 1,
                           'b' => 2,
                           ];
    
        function __unset($name) {
            unset($this->values[$name]);
        }
    
        function __isset($name) {
            return isset($this->values[$name]);
        }
    
        function __set($name, $value) {
            $this->values[$name] = $value;
        }
    }

?>

Documentation

See Also

__wakeup() Method

__wakeup() is a magic method: it is called when an object is being deserialized, so that the object may be restored to its working condition.

In particular, some resources, such as database connections or files cannot be serialized. They should be closed, stored as a path in __sleep(), and reopened later with __wakeup().

The __wakeup() method is usually paired with the __sleep() method.

<?php

    class Elephpant {
        private $file;
        private $path;

        function __sleep() {
            fclose($this->file);
            return ['path'];
        }

        function __wakeup() {
            $this->file = fopen($this->path, 'r');
        }
    }

?>

Documentation

See Also

abs()

abs() calculates the absolute value of a number. It is the value itself, when the number is positive or zero, and it is the opposite of the number when the number is negative.

Almost all integers have an absolute value: the only exception is PHP_INT_MIN. Its value is -9223372036854775808, and the actual absolute value would be 9223372036854775808, which is bigger than PHP_INT_MAX.

abs() takes float and int as types. Except for the exception above, giving a float to abs() produces a float, and giving it an integer, produces an integer. Other types are forbidden. Objects have to be turned explicitly into a number.

<?php

    $a = -2;
    print abs($a); // 2
    print abs(abs($a)); // 2

?>

Documentation

See Also

Absolute Name

An absolute name is a name that is independent from the current namespace. It is usually identified by the leading \ sign.

An absolute name does not require a use expression, and is faster to process, as there is no resolution involved. It may also be less readable, as it makes names longer.

The opposite of relative name is relative name.

Absolute names are similar to absolute path, in a file system, though applied to functions, constants and classes names.

<?php

    namespace Savanna {
        function trumpet() {}

        class Elephpant {}

    }

    namespace Waterhole {
        //absolute name to call a function
        \Savanna\trumpet();

        //absolute name to create an object
        new \Savanna\Elephpant();

        //absolute name from the global space: no need to import it
        strtolower(...) instanceof \Closure;
    }

?>

Documentation

See Also

Absolute Value

An absolute value is the positive value of a real number.

PHP offers the native function abs() to calculate this value.

The absolute value of PHP_INT_MIN is a float.

<?php

    $a = 10;
    echo abs($a); // 10
    
    $b = -12;
    echo abs($b); // 12

?>

Documentation

See Also

Absolute

An absolute value is independent from the context in which it operates.

The notion of absolute has several usages:

  • There are absolute names, also known as fully qualified name: \get_class(), new myClass()
  • There are absolute path, which are path that starts at the root of the file system: /tmp/path/to/file.txt
  • There are absolute values, supported by abs() math function
  • The absolute parameter, when processing a DateTimeInterface difference

The notion of absolute is the opposite of the notion of relative, which depends on a local context.

<?php

// global namespace
namespace {
    // first definition
    function trumpet() {
        echo 'in the global scope.';
    }
}

namespace Savanna{
    // second definition
    function trumpet() {
        echo 'in the savanna scope.';
    }

    trumpet(); // relative call: it goes to the second definition
    \trumpet(); // absolute call: it goes to the first definition
    \Savanna\trumpet(); // absolute call: it goes to the second definition
}

?>

Documentation

See Also

Abstract Class

An abstract class is a class that cannot be instantiated directly. It has the abstract option.

An abstract class serves as a blueprint for other classes that extends it, and is intended to be subclassed. It is still possible to access its constants, static properties and static methods.

An abstract class can contain both regular methods and abstract methods. Regular methods provide common functionality that can be inherited by subclasses, while abstract methods are declared without an implementation. Subclasses of an abstract class must provide an implementation for all the abstract methods defined in the abstract class.

<?php

    abstract class AbstractClass {
        abstract function trumpet(); // abstract method

        function forage() {
            return 1;
        } // concrete method
    }

    class ConcreteClass extends AbstractClass{

        function trumpet() {
            return 2;
        } // concrete method
    
        // No need to redefine the concrete methods.
        // Yet, it is still possible
    }

?>

Documentation

See Also

Abstract Factory

An Abstract Factory is a design pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes.

It is one level of abstraction above the simple factory pattern. While a simple factory creates one type of object, an abstract factory is used to create a set of related factories, each responsible for creating a family of products.

Documentation

See Also

Abstract Method

An abstract method is a method that has no code. It also uses the abstract option in the syntax.

An abstract method serves as a blueprint for other methods: its host class is intended to be subclassed.

Interfaces only have abstract methods.

Abstract constructors cannot use promoted properties.

<?php

abstract class AbstractClass {
    abstract function trumpet(); // abstract method

    function forage() {
        return 1;
    } // concrete method
}

class ConcreteClass extends AbstractClass{

    function trumpet() {
        return 2;
    } // concrete method

    // No need to redefine the concrete methods.
    // Yet, it is still possible
}

?>

Documentation

See Also

Abstract Keyword

PHP has abstract classes, properties and methods. Classes defined as abstract cannot be instantiated, and any class that contains at least one abstract method, or property hook, must also be abstract.

PHP does not support abstract constants, so a class constant must be defined with a value, although it may be overwritten in a child class.

Traits may have abstract methods, and they don’t have to be labelled abstract. On the other hand, any class that holds such a trait must either overwrite the abstract methods, or be itself declared abstract.

Interfaces act as implicit and systematic abstract classes: each of the methods in an interface is implicitly considered abstract.

An abstract method may be made concrete. It cannot be turned back into an abstract method later.

An abstract method cannot be private: being abstract means that the method must be defined in a child, while private means the method is not shared with child classes. Protected and public are both fine.

An abstract method cannot be final: being abstract means that the method must be defined in a child, while final means the method cannot be overwritten.

Static methods may be declared abstract.

abstract applies to the property, and is used by either or both of the get and set hooks. At least one of them has to be without a body, as should be any abstract method.

<?php

    abstract class AbstractClass
    {
    
        // the abstract keyword is on the property
        public abstract string $p {
            set;
            get => 'abc';  
        }

        // Force Extending class to define this method
        abstract protected function getValue();
        abstract protected function prefixValue($prefix);
    
        // abstract property
        abstract public $p { get; }
    
        // Common method
        public function printOut() {
            print $this->getValue() . "\n";
        }
    }

?>

Documentation

See Also

Abstraction Layer

An abstraction layer is a piece of software that offer the same API to access multiple similar components.

The underlying components may be of various shapes: PDO offers an abstraction layer to databases, streams offer an abstraction layer to files, etc.

PDO is a database abstraction layer, to access various RDBMS servers with one PHP API. league/flysystem offers also an abstraction layer to filesystem, lcobucci/clock offers an abstraction to clocks.

Documentation

See Also

Abstraction

An abstraction, or also an abstraction layer, is a way to hide the underlying complexity of some logic behind a simpler interface so that other parts of the program don’t need to worry about the details.

In that sense, it is related to the abstract keyword, which introduces a signature and leaves freedom of implementation.

Abstraction is also the name of the refactor to replace a piece of code by an easily changed piece of code.

<?php

    echo 1; // displays 1 
    
    // This depends on the execution environment
    const A = PHP_OS == 'win' ? 'Windows' : 'Others';
    
    echo A; // display the value of A

?>

Documentation

See Also

Acceptance Test

Acceptance tests, also called user acceptance tests or UAT, are tests that verify that the software meets the business requirements and satisfies the expectations of the end user, before it is accepted and released.

Acceptance tests are usually the final phase of testing, run after unit, integration, and functional tests have already passed. They are often written from user stories or business specifications, using tools such as Behat or Codeception, sometimes in a natural-language format like Gherkin, so that non-developers, such as product owners or clients, can read and validate them.

Acceptance tests focus on whether the software does what the business needs, not on how it is implemented internally; in that sense, they are a form of black box testing.

Documentation

See Also

Accessibility

Accessibility is the process to make the code accessible to everyone.

PHP code being text, its accessibility relies on the IDE. The main accessible feature is the usage of tabulations, instead of multiple spaces.

Accessibility is also called a11y, aka a, 11 letters and y. This is shorter to write.

Documentation

See Also

Accountability

Accountability isn’t a built-in language feature: it’s a development practice. It means writing code in a way that makes it clear who did what, what happened, and why, so actions can be traced and owned.

Accountability may take several shapes:

  • Logging actions
  • Audit trails
  • Reporting errors
  • Adding tests
  • Using VCS
  • Code reviews.

Documentation

See Also

ACID

ACID is an acronym for the four ACID properties that guarantee reliable database transactions. It stands for Atomicity, Consistency, Isolation, and Durability.

  • Atomicity: a transaction either completes entirely or not at all. If any step fails, all changes are rolled back, leaving the database as if the transaction never started.
  • Consistency: a transaction brings the database from one valid state to another, respecting all defined constraints, rules, and cascades. It cannot leave data in a logically invalid state.
  • Isolation: concurrent transactions execute as if they were serial. The intermediate state of a transaction is not visible to other transactions. The degree of isolation is configurable.
  • Durability: once a transaction is committed, it persists even in the event of a system crash. Achieved through write-ahead logging and durable storage.

ACID transactions are available through PDO via beginTransaction(), commit(), and rollBack(). Most relational databases, MySQL/InnoDB, PostgreSQL, SQLite, etc. provide full ACID compliance.

<?php

    $pdo = new PDO('mysql:host=localhost;dbname=shop', 'user', 'pass');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $pdo->beginTransaction(); // start atomic unit
    
    try {
        $pdo->exec('UPDATE accounts SET balance = balance - 100 WHERE id = 1');
        $pdo->exec('UPDATE accounts SET balance = balance + 100 WHERE id = 2');
        $pdo->commit(); // durable on success
    } catch (PDOException $e) {
        $pdo->rollBack(); // atomicity: undo both updates on failure
        throw $e;
    }

?>

Documentation

See Also

Access Control List (ACL)

An Access Control List, or ACL, is a set of rules that defines which users or system processes are granted access to specific resources, and what operations they are allowed to perform.

In web applications, an ACL is typically implemented as a matrix of subjects, like users, roles…, and objects, like routes, resources, actions…, where each cell defines the permissions granted. ACL provides fine-grained authorization control, complementing authentication.

ACL can be implemented as:

  • Entry-based: each resource holds a list of principals and their permissions
  • Role-based, RBAC: permissions are assigned to roles, and roles are assigned to users
  • Attribute-based, ABAC: access decisions are based on attributes of the user, resource, and environment.

Several frameworks provide ACL components out of the box, or via packages.

<?php

    // Simple ACL check
    $acl = [
        'admin' => ['read', 'write', 'delete'],
        'editor' => ['read', 'write'],
        'viewer' => ['read'],
    ];
    
    function can(string $role, string $action, array $acl): bool {
        return in_array($action, $acl[$role] ?? [], true);
    }
    
    var_dump(can('editor', 'delete', $acl)); // false
    var_dump(can('admin',  'delete', $acl)); // true

?>

Documentation

See Also

Active Record

Active Record is a design pattern commonly used in development. It provides an object-oriented approach to interact with a database table or view. In the Active Record pattern, each table or view in the database is represented by a corresponding class in the PHP code.

The main purpose of Active Record is to encapsulate the database access logic within the objects themselves. This means that an Active Record object not only represents a single row of data, but it also includes methods to perform CRUD, or Create, Read, Update, Delete, operations on that data.

With Active Record, developers can easily create, retrieve, update, and delete records from the database by invoking methods on the corresponding objects. The Active Record object abstracts away the SQL queries and provides a more intuitive and object-oriented way to work with the data.

Additionally, Active Record allows developers to add domain logic to the objects. This means that business rules and validations can be implemented directly within the Active Record classes. For example, it is possible to define methods to validate input, perform calculations, or enforce certain constraints on the data.

Active Record is often used in conjunction with other design patterns, such as the Data Mapper pattern. While Active Record focuses on the direct interaction between objects and the database, the Data Mapper pattern separates the database access logic into a separate layer, providing more flexibility and decoupling between the domain objects and the persistence layer.

Documentation

See Also

Actor Model

The Actor Model, introduced by Carl Hewitt in 1973, is a mathematical model of concurrent computation. Its fundamental unit is the actor: a lightweight, isolated entity with its own private state and a mailbox. Actors never share memory. All communication happens exclusively through asynchronous message passing.

When an actor receives a message it may:

  • Create new actors
  • Send messages to actors whose addresses it knows
  • Designate the behavior to use for the next message it receives

Because no memory is shared, race conditions and the need for explicit locks are eliminated by design.

PHP is single-threaded in its classic request/response model, so the Actor Model is not natively available in the language. However, several frameworks and extensions bring actor-like concurrency to PHP:

  • ReactPHP and AMPHP implement event loops with asynchronous message passing via promises and fibers.
  • Swoole / OpenSwoole provide coroutines and channels that enable actor-style communication.
  • The parallel extension gives true multi-threaded execution with channels for inter-thread messaging.
  • Libraries such as Phluxor implement explicit actor runtimes on top of these primitives.
<?php

   // Conceptual actor-style pattern using ReactPHP EventLoop
   // Each coroutine owns private state and communicates via channels (parallel ext)

   use parallel\{Runtime, Channel};

   $channel = new Channel();

   $actor = new Runtime();
   $actor->run(static function (Channel $inbox): void {
       while ($message = $inbox->recv()) {
           echo "Actor received: {$message}\n";
       }
   }, [$channel]);

   $channel->send('hello');
   $channel->send('world');
   $channel->close();

?>

Documentation

See Also

Adapters

Adapters are the link between the application and the rest of the universe. They take incoming data and shape them into an internal format, and vice-versa.

Adapters are heavily used in hexagonal architecture. They are also a classic design pattern.

Adapters are related to decoupling code. They bridge two pieces of code that evolve independently.

Documentation

See Also

Addition

PHP additions apply to two different types: numbers and arrays.

For numbers, int and float, this is the classic mathematical addition.

For arrays, this is a special version of array merge: the arrays are merged, and keys are kept once they are written. This features only exists for addition and arrays. Substraction is not available.

With boolean, addition first cast the boolean to an integer, 0 or 1, and then, operates as a math addition.

With string, addition first try to convert the string to a numeric value. If it succeed, it operates as a math addition. Otherwise, it emits a type error.

With objects or resources, a type error is emitted.

<?php

$a = 1 + 2.3; // 3.3

$a2 = 1 + -2.3; // -1.3

$b = [1] + [3, 4]; // [1, 4]

?>

Documentation

See Also

Architectural Decision Record (ADR)

An Architectural Decision Record, or ADR, is a concise document that captures an important architectural decision made during the development of a software project. The goal of an ADR is to provide context, rationale, and consequences of a decision, so that future team members, or even the same team, can understand why a particular choice was made, even years later.

Key Elements of an ADR

  • Title: a short, descriptive name for the decision.
  • Status: whether the decision is proposed, accepted, deprecated, or superseded.
  • Context: the background or problem that led to the decision.
  • Decision: the actual choice made.
  • Consequences: the expected outcomes, trade-offs, or impacts of the decision.

Documentation

See Also

Agile

Agile refers to a set of software development methodologies that emphasize iterative delivery, collaboration, and adaptability. It is not a PHP-specific language or technical notion, though it is used in the PHP ecosystem.

Agile is an umbrella term. The fine-grained methodologies include:

  • Scrum: framework with roles, such as scrum master, product owner, sprints, and ceremonies
  • Kanban: workflow visualization method using boards and WIP limits
  • Sprint: time-boxed iteration, usually 1–4 weeks
  • User Story: short description of a feature from an end-user perspective
  • Backlog: prioritized list of work
  • Burndown Chart: visual showing remaining work over time
  • Definition of Done, aka DoD: criteria that must be met for a task to be considered complete
  • Retrospective: meeting to reflect on the past iteration and improve
  • Daily Stand-up: short daily coordination meeting
  • Minimum Viable Product, MVP: smallest version that delivers value
  • Pair Programming: two developers working together on the same code
  • Continuous Integration, CI / Continuous Delivery, CD.

Documentation

See Also

Artificial Intelligence (AI)

A neural network is a software made of many simple processing units, called neurons, connected and organized in layers. By showing it many examples, it automatically learns patterns to look for.

Documentation

See Also

AJAX

AJAX, the Asynchronous JavaScript and XML feature, is a set of web development techniques that allow a web page to communicate with a server asynchronously, without requiring a full page reload. Despite the name, modern AJAX often uses JSON rather than XML for data exchange.

AJAX requests are handled like any other HTTP request by PHP. The PHP application receives the request, processes it, and returns a response, most often JSON, which the client-side JavaScript then uses to update the page dynamically.

AJAX is fundamental to single-page applications and dynamic web interfaces.

<?php

    // Server-side PHP endpoint handling an AJAX request
    header('Content-Type: application/json');
    
    $data = json_decode(file_get_contents('php://input'), true);
    $name = htmlspecialchars($data['name'] ?? 'World');
    
    echo json_encode(['message' => "Hello, $name!"]);

?>

Documentation

See Also

Algebraic Data Type

An algebraic data type is a composite type built by combining simpler types through two fundamental operations: product and sum.

A product type holds values of several types simultaneously, connected by AND. Every field is always present. A struct, record, or tuple is a product type: { name: string, age: int } means a name AND an age, always both.

A sum type holds a value of exactly one of several alternatives, connected by OR. Only one case is active at a time, and each case may carry different data. Circle(Float) | Rectangle(Float, Float) means either a circle, with a radius, or a rectangle, with two sides, never both at once.

Full ADT systems pair sum types with exhaustive pattern matching: the compiler enforces that every case is handled, turning incomplete switches into compile-time errors.

PHP supports product types natively through classes and arrays. Sum types are approximated by union types int|string and by enums, but neither carries associated data per variant, and match does not perform exhaustive structural decomposition over union type values.

PHP does not support true ADT.

Documentation

See Also

Algorithm

An algorithm is a step-by-step procedure or set of rules designed to perform a specific task or solve a particular problem. Algorithms are the foundation of computer science and programming, as they provide a clear, logical sequence of operations to achieve a desired outcome.

Documentation

See Also

Algorithmic Complexity

Algorithmic complexity, also called computational complexity, refers to the study of the resources required by an algorithm to solve a problem as a function of the input size. It helps us understand how efficient an algorithm is, especially as the input size grows.

Algorithmic complexity matters for scalability, resource optimisation, performance forecast and server dimensioning.

The resources may be time, processing power, memory, disk usage or other computational resources.

Algorithmic complexity may be measured by metrics.

Documentation

See Also

Alias Types

An alias type, or type alias, is a short name for several types at once. Under the hood, alias types are union types.

PHP offers several native alias types, such as iterable, which represents array | Traversable. Alias types are not available for customisation.

The same rules apply to alias types as other types: for example, array | iterable produces a ‘Duplicate type array is redundant’ error.

<?php

// iterable is an alias for array|Traversable: both are accepted here
function sumValues(iterable $numbers): int {
    $total = 0;

    foreach ($numbers as $number) {
        $total += $number;
    }

    return $total;
}

echo sumValues([1, 2, 3]); // 6: a plain array is iterable

function threeToFive(): Generator {
    yield 3;
    yield 4;
    yield 5;
}

echo sumValues(threeToFive()); // 12: a Generator is Traversable, also iterable

// function sumValues(array|iterable $numbers): int {} // Fatal error: Duplicate type array is redundant

?>

Documentation

See Also

Alias

An alias is a distinct name for an existing named structure. It is a classic way to cope with possible naming conflict, and improve readability.

For example, there are aliases in namespaces import, to disambiguate classes, traits, interfaces, enums, functions and constants from other namespaces. There is also the class_alias() function, which allows the application-wide creation of aliases.

There are also aliases for methods, when importing them from a trait.

References are also considered an alias, as they stand for a variable with another name.

<?php

    use stdClass as StandardClass;
    
    foreach($map as $key => $value) {
        print "$key => $value\n";
    }

?>

Documentation

See Also

Allow Dynamic Properties

This is a native PHP attribute, which tells the engine that a class can dynamically create properties without declaring them.

This attribute may be added to any class. It is not necessary with stdClass.

The attributes allow any dynamic property: there is no way to restrict this to a set of names or a number without other means.

<?php

class Elephpant {
    function trumpet() {
        // creation of a property, without prior definition
        // This yields an error
        $this->trunkLength  = 1;
    }
}

#[AllowDynamicProperty]
class Herd {
    function trumpet() {
        // creation of a property, without prior definition
        // This doesn't yields an error
        $this->trunkLength  = 1;
    }
}

class Waterhole extends Stdclass {
    function trumpet() {
        // creation of a property, without prior definition
        // This doesn't yields an error, yet no attribute
        $this->trunkLength  = 1;
    }
}

?>

Documentation

See Also

Application-Layer Protocol Negotiation (ALPN)

ALPN is a TLS extension that lets a client and server agree on which application protocol to use over an encrypted connection, as part of the TLS handshake itself, rather than after the connection is already open.

During the handshake, the client sends a list of protocols it supports, such as h3 for HTTP/3, h2 for HTTP/2, or http/1.1, and the server picks one and confirms it before the connection finishes negotiating. This avoids the extra round trip that protocol detection would otherwise cost, and is how browsers and servers agree to speak HTTP/2 or HTTP/3 without first trying and falling back.

ALPN negotiation is handled by the TLS layer, via OpenSSL, underneath stream contexts or a QUIC-capable extension; it is not something userland code negotiates directly, though stream context options can be used to restrict or inspect the negotiated protocol.

Documentation

See Also

Alternative Syntax

PHP offers an alternative syntax for some of its control structures; namely, if, while, for, foreach, and switch. In each case, the basic form of the alternate syntax is to change the opening brace to a colon : and the closing brace to endif;, endwhile;, endfor;, endforeach;, or endswitch;, respectively.

<?php if ($a == 5): ?>
A is equal to 5
<?php endif; ?>

Documentation

See Also

Asynchronous Markup Protocol (AMP)

AMP refers to the AMP PHP library, formerly Amp Project, an event-driven, non-blocking I/O framework for building asynchronous applications.

It provides primitives for working with asynchronous operations: Promises, Futures, and an event loop. Amp is the foundation behind popular projects like ReactPHP and PHP-PM, and is widely used for building high-concurrency network services, WebSocket servers, and HTTP clients.

In a broader web context, AMP also stands for Accelerated Mobile Pages, a Google-backed project for creating fast-loading mobile web pages.

<?php

    use Amp\Loop;
    use Amp\Promise;

    Loop::run(function () {
        $result = yield Amp\Promise\resolve('Hello from AMP!');
        echo $result;
    });

?>

Documentation

See Also

Analysis

Analysis in software development refers to the systematic examination of source code, runtime behaviour, or architecture to detect issues, measure quality, or derive understanding.

Static analysis examines code without executing it. Tools such as PHPStan, Psalm, Mago and Phan inspect PHP source files for type errors, undefined variables, dead code, and security vulnerabilities. Exakat is a static analyser specifically designed for PHP, able to audit large codebases and enforce rules across many categories.

Dynamic analysis examines code during execution. It covers profiling, fuzzing, mutation testing, and runtime error detection.

Architectural analysis focuses on the relationships between components, coupling, cohesion, and adherence to intended design patterns.

<?php

    // Running static analysis from PHP (e.g., as part of a CI pipeline)
    $output    = [];
    $exitCode  = 0;
    exec('vendor/bin/phpstan analyse src --level=8 --no-progress', $output, $exitCode);
    
    if ($exitCode !== 0) {
        echo implode(PHP_EOL, $output);
        exit($exitCode);
    }

?>

Documentation

See Also

Anchor

An anchor, or HTML anchor, is an HTML element <a> used to create hyperlinks, allowing navigation to other pages, resources, or sections within the same page. When the href attribute references a fragment identifier, e.g. #id, the link jumps to a specific section of the current document.

Anchors are frequently generated programmatically when building HTML output, navigation menus, or documentation pages. Developers must be careful to escape user-supplied content used in anchor href attributes to prevent XSS vulnerabilities.

<?php

    // Generating an anchor safely in PHP
    $url   = 'https://www.php.net/';
    $label = 'PHP Manual';
    
    // htmlspecialchars prevents XSS
    echo '<a href="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '">'
        . htmlspecialchars($label, ENT_QUOTES, 'UTF-8')
        . '</a>';
    
    // Fragment / in-page anchor
    echo '<a href="#section-2">Go to section 2</a>';

?>

Documentation

See Also

And Operator

and is the logical operator: it returns true only when both operands are true; otherwise, it returns false.

It is a synonym for the symbolic operator &&, though it has a different precedence level.

There is also a bitwise and operator: &

and is a PHP keyword.

<?php

$a = 1 && 2;

?>

Documentation

See Also

Anemic Domain Model

The anemic domain model is an anti-pattern identified by Martin Fowler where domain objects contain only data, getters, setters, and no business logic. All business logic is instead placed in service classes that operate on these passive data containers.

The result is a structural inversion: the domain layer becomes a schema mirror, while service classes accumulate all the behaviour. This defeats the purpose of object-oriented design, where objects encapsulate both state and the operations that depend on that state.

The symptoms are recognisable: entities have only getters/setters, service classes are large and growing, business rules are scattered across multiple services, and the same validation or computation is duplicated in several places.

The alternative is the rich domain model, where entities enforce their own invariants, expose meaningful behaviour, and reject invalid state. This is the model advocated by Domain-Driven Design.

Anemic models often emerge from ORM-first design, where Doctrine or Eloquent entities are modelled around the database schema rather than the domain.

<?php

// Anemic: Order is a data bag; all logic in OrderService
class Order {
    public int    $id;
    public string $status;
    public float  $total;
    public array  $items = [];
}

class OrderService {
    public function ship(Order $order): void {
        if ($order->status !== 'paid') {          // business rule in service
            throw new \LogicException('...');
        }
        $order->status = 'shipped';               // service mutates the entity
        $this->repository->save($order);
    }
}

// Rich: Order enforces its own invariants
class Order {
    private string $status = 'new';

    public function ship(): void {
        if ($this->status !== 'paid') {           // rule lives in the entity
            throw new \DomainException('Order must be paid before shipping.');
        }
        $this->status = 'shipped';
        $this->record(new OrderShipped($this->id));
    }
}

?>

Documentation

See Also

Annotations

PHP annotations are a system to provide meta data about code, in a way that is programmatically processable.

PHP annotations are based on PHPDoc comment’s syntax, and were later partially modernized by PHP attributes.

<?php

/**
 * <description of trumpet>
 * @param int $a : <description of the parameter>
 * @return int : <description of the returned value>
 */
function trumpet(int $a) {
    
    // This annotation cannot be turned into an attribute
    /**
     * @var int $b : <description of the variable>
     */
     $b = $a + 1;
     
     return $b;
}

?>

Documentation

See Also

Anonymize

To anonymize is to replace a precise identifier with an unrelated piece of data. For example, Mr Elephpant may be renamed Mr Smith or b0d7b3834d527db3b2ccd6e4b0f3e0e6.

Anonymization removes anything that can trace back to the original user. It must also keep relationships with other data, which must also be anonymized. Some values cannot be anonymized, such as booleans.

Anonymization is distinct from fake data, which creates valid-looking data out of nothing.

Documentation

See Also

Anonymous Catch

Traditionally, the catch statement requires specifying both an Exception class and an identifier variable to hold the caught exception.

PHP 8.0 introduced a new language construct that makes the identifier variable optional, allowing for a fully anonymous catch statement. This means there is no need to specify a variable to hold the caught exception.

The motivation behind this proposal is to simplify exception handling code, especially in cases where there is no need to use the caught exception object. It leads to cleaner and more concise code, especially when the specific details of the exception are not interesting and can be handled generically.

<?php

    try {
        $a / 0;
    } catch (DivisionByZero) {
    
    }

?>

Documentation

See Also

Anonymous Class

A class may be instantiated, without defining a class name. The class is identical to a named-class, except for the name attribute. This also means that it cannot be used for typing, though it may be typed itself, using its parent class or implemented interfaces.

Also, arguments may be passed at instantiation time, unlike with named-class definition, where those arguments are passed when calling new, not when defining the class.

<?php

    interface Pachyderm {}

    function trumpet(Pachyderm $a) {}

    $a = new class () implements Pachyderm {};

    trumpet($a);

?>

Documentation

See Also

Anonymous Constant

A constant may be anonymous. In that case, it is reduced to its value, and it is a literal.

There is no explicit code for an anonymous constant: it is the simple application of the concept to an existing structure.

<?php

    // a constant
    const A = 'abc';
    
    // an anonymous constant
    'def';

?>

Documentation

See Also

Anonymous Function

A function may be instantiated, without defining a function name. Such functions are called anonymous.

Anonymous functions are defined as closures or arrow functions. They may also be created based on existing methods and functions, with the ... operator.

Even without names, they are usable like functions, or as callable.

Methods cannot be anonymous, but it is possible to call a method without mentioning its name by using the __invoke magic method.

<?php

    $closure = function () {} ; 

    $arrowFunction = fn() => 1;
    
    $fcs = strlen(...);

?>

Documentation

See Also

Anonymous

An anonymous structure is a structure that usually has a name, but may also go without it. When the structure is anonymous, some features are not available, such as creating or calling a new instance by using its name. Such operations must now handled by creating the asset, and handing it across the code base.

There a several structures which have an anonymous version:

  • Functions: there are two types: closures and arrow functions
  • Method: the magic method __invoke()
  • Classes
  • Constants: basically, it is a literal value
  • Catch: in this case, the exception is caught, but it is not provided in a related variable

Some structures are always named: variables, properties, traits, interfaces, enums.

Anonymous structures should not be confused with dynamic structures: these structures are defined with a name which is stored in a variable, or a similar data container. In fact, dynamic structures often rely on a name to be usable. This is the case of variables, with $$variable.

<?php

    $closure = function () {} ; 

    $arrowFunction = fn() => 1;
    
    'literal value';
    
    // an object of an anonymous class
    new class() {}; 
    
    try {}
    catch(Exception ) {}

?>

Documentation

See Also

Anti-Pattern

An anti-pattern, sometimes spelled antipattern, is a common but counterproductive solution to a recurring problem. Unlike a mistake made once, an anti-pattern is a response that appears reasonable or even familiar, is applied repeatedly, and systematically produces negative consequences: increased complexity, fragility, poor performance, or security vulnerabilities.

The term was coined in 1995 by Andrew Koenig and popularised by the 1998 book Anti-Patterns by Brown, Malveau, McCormick, and Mowbray. It draws an explicit parallel with design patterns: where a design pattern documents a proven good solution, an anti-pattern documents a proven bad one, together with the root cause, the symptoms that reveal it, and the refactored solution that replaces it.

Anti-patterns appear at every level of software development:

  • Architectural anti-patterns: big ball of mud, god object, spaghetti code
  • Design anti-patterns: singleton overuse, service Locator, magic container
  • Coding anti-patterns: copy-paste programming, premature optimisation, magic numbers
  • PHP-specific anti-patterns: suppressing errors with @, using eval() for configuration, register_globals-era dynamic variable injection

Recognising anti-patterns is a key skill in code review and static analysis. Exakat detects a wide range of PHP anti-patterns through dedicated rules.

<?php

    // Anti-pattern: God Object: one class that knows and does everything
    class Application {
        public function connectDatabase() { /* ... */ }
        public function renderHtml() { /* ... */ }
        public function sendEmail() { /* ... */ }
        public function validateInput() { /* ... */ }
        public function logError() { /* ... */ }
        // ... dozens more methods
    }
    
    // Anti-pattern: error suppression hiding real problems
    $result = @file_get_contents('data.json'); // silences warnings instead of handling them
    
    // Anti-pattern: magic numbers with no explanation
    if ($status === 3) { // What does 3 mean?
        redirect();
    }

?>

Documentation

See Also

ANTLR4

ANTLR, ANother Tool for Language Recognition, currently at its 4th major version, is a parser generator: given a formal grammar describing a language’s syntax, it generates a lexer and a parser for that language, in a target language of choice, such as Java, C#, Python, Go or JavaScript. There is no first-class PHP target, though community-maintained backends exist.

ANTLR4 grammars are LL(*)-based and produce a parse tree, which can then be walked with a generated Listener or Visitor. It is widely used to build DSLs, configuration-file parsers, and new implementations of existing languages, including some PHP parsers used by third-party tooling.

Most PHP static analyzers do not rely on ANTLR: they use PHP’s own tokenizer, then build their own AST directly, tailored to the needs of static analysis, rather than going through a generic, grammar-driven parser.

Documentation

See Also

Ahead Of Time

Ahead-of-time compilation, AOT, is the process of compiling source code to machine code before execution, as opposed to at runtime. The compilation happens once during the build phase; the produced binary runs directly without a separate compilation step at startup.

AOT stands in contrast to Just-in-Time compilation, where compilation happens during execution, and to interpretation, where source is executed line by line. AOT trades compilation time for faster startup and more predictable runtime performance.

True PHP AOT to native machine code is not part of the standard runtime. However, several mechanisms approximate AOT behaviour:

  • OPcache preloading: preloads and compiles PHP files into shared memory at server start, so they are not parsed or compiled on each request.
  • NativePHP: compiles a PHP application into a standalone desktop binary, bundling the PHP runtime.
  • Static analysis tools perform AOT-style type checking without executing code.
  • Compiler extensions: compile PHP or PHP-like code to C extensions ahead of time.

The primary PHP performance story is OPcache + JIT, not strict AOT.

<?php

// OPcache preloading — the closest PHP has to AOT for web apps
// preload.php: loaded once at PHP-FPM start, shared across all workers

// Preload all framework and application classes
$files = glob(__DIR__ . '/src//*.php');
foreach ($files as $file) {
    opcache_compile_file($file); // compile to bytecode once, cache in shared memory
}

// php.ini / php-fpm.conf:
// opcache.enable=1
// opcache.preload=/var/www/preload.php
// opcache.preload_user=www-data

// At request time: preloaded files are served from opcache with zero parse/compile cost.

// JIT (PHP 8.0+) — runtime, not AOT, but often confused with it
// opcache.jit=tracing
// opcache.jit_buffer_size=100M

?>

Documentation

See Also

APCu

APCu, APC User Cache, is a PHP extension that provides a shared-memory, in-process key-value store for caching arbitrary data between requests, without needing an external service like Memcached or Redis.

APCu is the successor of APC, Alternative PHP Cache, once its opcode-caching part was superseded by OPcache; only the user-cache API survived under the name APCu.

Common functions include:

  • apcu_store() to write a value, with an optional TTL, time-to-live
  • apcu_fetch() to read a value back
  • apcu_delete() to remove an entry
  • apcu_exists() to check for a key without fetching its value
  • apcu_inc() / apcu_dec() for atomic counters
  • apcu_clear_cache() to flush the whole cache

Because the cache lives in shared memory local to the PHP process pool, it is fast, but it is not shared across servers; in a multi-server, load-balanced setup, a distributed cache such as Redis or Memcached is usually preferred.

<?php

    if (apcu_exists('user_count')) {
        $count = apcu_fetch('user_count');
    } else {
        $count = count_users_from_database();
        apcu_store('user_count', $count, 300); // cache for 5 minutes
    }

    apcu_inc('page_views');

?>

Documentation

See Also

API Gateway

An API gateway is a server that acts as the single entry point for all client requests to a backend system. It sits in front of a set of services and is responsible for routing requests to the appropriate service, as well as handling cross-cutting concerns that would otherwise be duplicated across services.

Typical API gateway responsibilities: request routing, which are path-based or host-based to microservices, authentication and authorisation, based on JWT validation or API key checking, rate limiting and throttling, SSL termination, request/response transformation, logging and metrics collection, and caching.

By centralising these concerns at the gateway, individual services are freed from implementing them independently. A client makes a single call to the gateway; the gateway fans out to one or more services internally.

Common API gateways: AWS API Gateway, Kong, Traefik, NGINX with Lua, and Caddy. In microservices deployments, the gateway typically sits in front of a Kubernetes ingress and routes traffic to PHP-FPM pods.

<?php

// PHP does not typically implement an API gateway itself —
// gateways are infrastructure components (Kong, Traefik, AWS API Gateway).
// PHP services sit behind the gateway and receive pre-authenticated, pre-validated requests.

// Kong plugin (Lua) enforcing JWT auth before the request reaches PHP:
// config:
//   plugins:
//     - name: jwt
//       config:
//         secret_is_base64: false

// In PHP: trust that the gateway has validated the token
// The user identity is forwarded via a header set by the gateway
$userId = (int) $_SERVER['HTTP_X_USER_ID']; // set by the gateway, not the client

// AWS API Gateway: Lambda proxy integration
// The gateway invokes a PHP Lambda function per route
// Route: GET /orders/{id} -> order-service Lambda

// BFF (Backend for Frontend): PHP as a gateway
// PHP aggregates calls to multiple microservices and returns a tailored response
$user    = $userClient->get('/users/' . $userId);
$orders  = $orderClient->get('/orders?user=' . $userId);
$returns = $returnClient->get('/returns?user=' . $userId);

return [
    'user'    => $user,
    'orders'  => $orders,
    'returns' => $returns,
];

?>

Documentation

See Also

Application Programming Interface (API)

An API is a set of functions and procedures allowing the creation of applications that access the features or data of another service.

There are several API protocols: REST, RPC, gRPC, GraphQL, SOAP, etc.

They are sometimes supported directly by PHP, with extensions, or via components. There is usually a client version, used to connect to a remote API, and a server version, to host a service based on this protocol.

<?php

// Consuming a REST API with cURL
$ch = curl_init('https://api.example.com/users/1');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer your-api-token',
    'Accept: application/json',
]);

$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($statusCode === 200) {
    $data = json_decode($response, true);
    echo $data['name'];
}

?>

Documentation

See Also

Application Performance Management (APM)

APM stands for Application Performance Management. An APM monitors various performance metrics, such as CPU, memory usage, and logs.

It helps find bottlenecks in the code.

Documentation

See Also

Application Server

An application server is a software environment that handles the execution of PHP scripts, serving dynamic content and managing interactions between the web server, the backend systems, like databases, and the client, browser or API consumer.

While PHP itself runs as an interpreted scripting language, the application server facilitates tasks like processing requests, managing resources, and sometimes handling session state or authentication.

Documentation

See Also

Appeasement Pattern

The appeasement pattern is a code smell where validation, error checking, or security controls are weakened or bypassed to satisfy code quality tools, a demanding caller or to silence errors, instead of fixing the underlying issue.

Common PHP manifestations include: using the @ error suppression operator to hide failures, loosening type checks to accept any input, adding special-case exceptions to a validator for a specific caller, or gradually degrading a strict check into a permissive one to avoid breakage.

The appeasement pattern also happens with static analysis: the tool may not support a particular syntax, lack helpful context or the code may simply be ambiguous. The appeasement pattern leads to more verbose or convoluted code, so as to allow extra configuration.

The appeasement pattern leads to fragile code where hidden failures accumulate silently, security assumptions erode, and bugs become much harder to diagnose. The correct approach is to fix the root cause rather than appease the symptom.

<?php

    // Appeasement: silencing an error instead of fixing it
    $result = @file_get_contents($untrustedPath); // failure is hidden
    
    // Appeasement: loosening a type check to stop a caller from failing
    function process(mixed $value): void {
        // was: if (!is_int($value)) { throw new \InvalidArgumentException(); }
        // now silently coerces because one caller passes strings
        $value = (int) $value;
    }
    
    // SCA Appeasement: 
    // $url has already been checked for being a valid URL so this will always works
    /** @var array{0: string, 1: string} $r */
    preg_match(#(http)s?://#, $url, $r);
    echo $r[0];

?>

Documentation

See Also

Array Append

Append, or array append, is an array operation, which adds an element at the end of the array. It is also called a push.

There are two operators for this feature ; the [] operator, which has to be placed after a variable or member. There is also the array_push() function, which is available as a callback, unlike the operator.

The opposite operation is a pop, with the function array_pop(). array_unshift() is the append at the beginning of the array.

<?php

    $array = [1, 2, 3];
    $array[] = 4;
    
    $array []= 5; // Same as above, with a notation similar to a short assignation
    
    array_push($array, 6);
    
    // $array === [1, 2, 3, 4, 5, 6];

?>

Documentation

See Also

Application

An application is a software program designed to perform specific tasks for end users. PHP applications can take many forms: web applications served over HTTP, command-line tools, background daemons, REST APIs, batch-processing scripts, etc.

PHP applications are typically structured around a framework or architecture pattern, like MVC, ADR, hexagonal architecture, etc. and a dependency-injection container. The entry point is usually a single index.php for web apps, or a CLI script invoked via the shell.

PHP applications excel at connecting to various sources of information, to collect, process and store data.

<?php

    declare(strict_types=1);
    
    // Bootstrap the application
    require __DIR__ . '/vendor/autoload.php';
    
    // Route incoming HTTP request
    $uri    = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
    $method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
    
    $router = new Router();
    $router->get('/',      [HomeController::class,  'index']);
    $router->get('/about', [AboutController::class, 'index']);
    
    $response = $router->dispatch($method, $uri);
    $response->send();

?>

Documentation

See Also

Arbitrary Number Of Argument

PHP allows any number of arguments to be passed to a function call. In the function definition, receiving those arguments means managing an arbitrary number of parameters.

This is achieved with the variadic operator, or with functions such as func_get_args().

They are also called variable argument lists.

When the arguments are dynamic, aka they are collected at execution time, the variadic operator or the function call_user_func_array() turns an array to arguments.

<?php

    function trumpet(...$args) {
        print "This function is called with ".count($args)." arguments\n";
        print "This function is called with ".func_get_count()." arguments\n";
        print "This function is called with ".count($func_get_args())." arguments\n";
    }

    $array = range(0, rand(5, 10)); // generates an array with 1 to 11 elements

    trumpet(...$array);
    call_user_func_array('trumpet', $array);

?>

Documentation

See Also

Arcane

Arcane refers to weird and obscure features, that are unknown, unused or forgotten. Sometimes, all at the same time. They have been with the language for a long time, and they eventually drop from the feature list.

  • It is possible to use ++ on a string containing variables. In that case, trailing letters are augmented by one.
  • strpos() used to accept an integer as second argument: it would convert it automatically to its ASCII equivalent
  • range() used to produce all the values between the interval boundaries, even when the boundaries where one string and one integer
  • Logical operators works on strings, and then, produce strings.
<?php

    $a = 'b';
    echo ++$a; // c
    
    // 98 is b
    print strpos('abc', 99); // 1
    // This was removed in PHP 8.0

    var_dump(a & 'A' );    // 'A'
    var_dump(a & 'B' );    // '@'

?>

Documentation

See Also

Architecture

Architecture refers to the global design of code, or its servers.

Architecture evolves into urbanisation: this happens when several applications have to be coordinated.

Documentation

Archive

An archive is a single document that stores a collection of files and directories.

There is PHAR, PHP Archives, which contains PHP code, and any other kind of file, and can be executed directly.

There are also other archive formats, such as TAR, for files or JAR, for Java applications, etc.

An archive is often an artefact of compression, using Zip, Rar or Tar.

Documentation

See Also

Argon2

Argon2 is a modern, secure, and highly efficient password hashing algorithm. It was the winner of the Password Hashing Competition, PHC, in 2015 and is designed to resist brute-force attacks, including GPU-based attacks. PHP has built-in support for Argon2 starting from version 7.2.

<?php
$password = "PHP is alive and kicking!";

// Hash the password with Argon2id
print password_hash($password, PASSWORD_ARGON2ID);

?>

Documentation

See Also

Argument

Arguments are values passed to a function or method, at execution time. The argument is the execution time value, and the recipient of that value is the parameter, which is located in the signature of the method. They may be a variable or an expression.

<?php

    function trumpet($parameter) {}

    $argument = 1;
    trumpet($argument + 2);

?>

Documentation

See Also

ArgumentCountError

ArgumentCountError is thrown when too few arguments are passed to a user-defined or PHP native function or method. This is an error, not an exception.

No exception is raised for extra parameters, as those may still be processed by the method itself.

<?php

    function trumpet($a) {}

    // No error is raised here
    trumpet(1,2);

    // ArgumentCountError is catchable
    try {
        trumpet();
    } catch (ArgumentCountError) {
        print 'No enough parameters passed.';
    }

?>

Documentation

See Also

ArithmeticError Error

ArithmeticError is thrown when an error occurs while performing mathematical operations. These errors include attempting to perform a bitshift by a negative amount, and any call to intdiv() that would result in a value outside the possible bounds of an integer.

Currently, a bitshift is the main source for arithmetic exceptions. The other is division by zero, which is a child class.

DivisionByZeroError is an ArithmeticError.

When ArithmeticError are not raised, PHP may return a NaN value, and INF value, or also 0.

<?php

// ArithmeticError is catchable
try {
    8 >> -1;
} catch (ArithmeticError) {
    print 'Cannot do a negative shift';
}

try {
    10 / 0;
} catch (DivisionByZeroError) { // or DivisionByZeroError
    print 'Cannot divide by 0';
}

print sqrt(-10); // NaN

print log(0); // -INF

?>

Documentation

See Also

Arity

Arity is the number of arguments, or operands, that a function, method, or operator accepts. A unary operator such as ! has arity 1, a binary operator such as + has arity 2, and a function’s arity is the count of its declared parameters. A function whose arity is fixed always expects exactly that many arguments; a function of variable arity, called variadic, accepts any number of arguments from a given point onward.

Arity matters for overload resolution in languages that dispatch on parameter count, for currying, where a function is considered fully applied only once it has received as many arguments as its arity, and for reflection, where a caller may need to discover how many arguments a callable expects before invoking it dynamically.

PHP supports both fixed and variable arity directly. A function’s fixed arity is simply its parameter list; variable arity is declared with the ... splat operator on the last parameter, and the actual number of arguments received by any call, fixed or variadic, can be inspected at runtime with func_num_args(), or discovered ahead of a call through ReflectionFunction::getNumberOfParameters().

<?php

    function sum(int ...$numbers): int {
        return array_sum($numbers);
    }
    
    sum(1, 2, 3); // called with arity 3, though sum() itself is variadic
    
    function greet(string $name) {
        echo func_num_args(); // 1: this call's actual arity
    }

?>

Documentation

See Also

Arm

An arm is a branch in a match() expression. There is the default arm, and the other arms. The arm includes the case, on the left, and the payload, on the right.

<?php

    // a match with 2 arm, including the default
    $a = match($b) {
        1 => 2,
        default => 3,
    };

?>

Documentation

See Also

Callable Arrays

An callable array is an array with index 0 and 1. The first index is a string, that represents a valid class, or an object. The second argument is a string, which is a method name.

With such a configuration, it is possible to use that array as a callback: either with a static method call, or a normal method call.

<?php

class Elephpant {
    static function stampede() { echo __METHOD__;}
           function trumpet() { echo __METHOD__;}
}

$callable1 = [new Elephpant, 'trumpet'];
$callable1(); // Elephpant::trumpet

$callable2 = ['Elephpant', 'stampede'];
$callable2(); // Elephpant::stampede

$callable3 = [Elephpant::class, 'stampede'];
$callable3(); // Elephpant::stampede

?>

Documentation

See Also

Array Callback

An array callback is an array of two elements, which may be used as a callback function.

The array must have only two elements: the first one is a class name or an object, and the second one is a method name. Then, the method on the class or object is called, when used with the class functioncall syntax.

The array should not use any string keys. It should only use index 1 and 0, although they may be in wrong order.

<?php

class Elephpant {
    function trumpet() { echo __METHOD__; }
    static function stampede() { echo __METHOD__; }
}

$method = [new Elephpant, 'trumpet'];
$method(); // Elephpant::trumpet

$method = [1 => 'trumpet', 0 => new Elephpant]; // 1 and 0 keys, but wrong order
$method(); // Elephpant::trumpet

$staticMethod = [Elephpant::class, 'stampede'];
$staticMethod(); // Elephpant::stampede

$staticMethod2 = ['\Elephpant', 'stampede'];
$staticMethod2(); // Elephpant::stampede

?>

Documentation

See Also

Array With Curly Braces

Curly braces used to be a feature, used to access specific index in an array or in a string. They acted like the square braces.

This features was deprecated in version 8.0.

<?php

    $array = ['a', 'b', 'c', 'd'];
    echo $array{2};    // c
    
    $string = 'abcd';
    echo $string{2};   // c

?>

Documentation

See Also

Array Dot Notation

Array dot notation is a convention for addressing a value nested inside a multi-dimensional array using a single string of keys separated by dots, such as 'a.b.c', instead of chaining several square-bracket accesses.

PHP has no native support for dot notation: writing $array['a.b.c'] only looks for a single key literally named a.b.c. To resolve the path and read or write the nested value, the string must be split on the dots and each segment used to walk down the array, either with a hand-written loop or with a helper function or package.

Dot notation is commonly used by frameworks and libraries to give a compact syntax for reading configuration values or deeply nested data, such as Laravel’s Arr::get($array, 'a.b.c') or Symfony’s property access component.

<?php

    function arrayGetDot(array $array, string $path, mixed $default = null): mixed {
        foreach (explode('.', $path) as $key) {
            if (!is_array($array) || !array_key_exists($key, $array)) {
                return $default;
            }
            $array = $array[$key];
        }

        return $array;
    }

    $config = ['db' => ['host' => 'localhost', 'port' => 5432]];
    echo arrayGetDot($config, 'db.host'); // localhost

?>

Documentation

See Also

Array Element

An array element is a piece of data, stored at an index in the array.

An array element may be of any type, and it may be also repeated, unlike the array index.

The array element is also called an item. It is often named $value, in a loop, as a blind variable.

When an array is a list, the elements are all of the same type. When an array is a hash, the elements may be of different types.

Array elements are not typed at the language level. They may be typed for static analysis tools, via the phpdoc syntax.

<?php

$array = ['a' => 1, 'b' => 3, 'c' => 5];
while(list($key, $value) = each($array)) {
    print $key . ' => ' . $value . PHP_EOL;
}

?>

Documentation

See Also

Array Shape

An array shape is a type annotation that describes an array by its exact set of keys and the type of the value stored under each one, instead of describing it only by the type of its elements in general. array{name: string, age: int} denotes an array that has a name key holding a string and an age key holding an int, as opposed to the coarser array<string, int|string>, which only says the array maps strings to a mix of integers and strings without tying any particular key to any particular type.

Array shapes are a PHPDoc annotation, written in a @param, @return, or @var docblock tag. They can mark optional keys with a trailing ?, allow additional unlisted keys with ..., and can be nested to describe arrays of arrays. They are the array analogue of row polymorphism / open record types found natively in languages such as TypeScript or OCaml.

PHP’s engine has no notion of array shape: an array type declaration accepts any array regardless of which keys it holds or what is stored under them, and nothing is checked at runtime about individual keys. Array shapes exist purely as a static-analysis annotation, verified by tools at analysis time; the PHP runtime performs no corresponding check, so a function documented with an array shape still receives whatever array is actually passed, keys missing or not.

<?php

    /**
     * @param array{name: string, age: int, email?: string} $user
     */
    function greet(array $user): string {
        // PHPStan/Psalm know $user['name'] is a string and $user['age'] an int;
        // the PHP engine enforces none of this at runtime.
        $greeting = 'Hello, ' . $user['name'];
    
        if (isset($user['email'])) {
            $greeting .= ' (' . $user['email'] . ')';
        }
    
        return $greeting;
    }
    
    // Nothing stops this call at runtime, even though the shape is violated.
    greet(['name' => 'Ada']);

?>

Documentation

See Also

Array Spread

Array spread is the ellipsis operator, applied to an array. Then, the array itself is replaced by each of its own elements, as if each element was spread from the array.

<?php

$a = [1,2,3];
$b = [...$a, 4,5];

// $b === [1,2,3,4,5];

?>

Documentation

See Also

Array Syntax

The array syntax, or array notation, is the usage of square brackets after a data container, such as variables or properties, or a literal, to access an element. It is generally known to be used with array structures, though it may also be used with strings and objects.

<?php

    $array = ['a', 'b', 'c'];
    echo $array[1]; // b
    
    $string = 'ABC';
    echo $string[2]; // C
    
    $object = new ArrayObject(['x', 'y', 'z']);
    print $object[0]; // x

?>

Documentation

See Also

Array Zip

Array zip is the operation of combining several arrays element-by-element and by position. The first zipped element groups together every array’s first item, the second zipped element groups together every array’s second item, and so on. It is also called a transpose, since it turns a list of parallel arrays into a list of rows, the way array_column() turns a list of rows into a single column.

PHP has no native zip() function, but array_map() performs exactly this operation when its callback is null: instead of applying a callback, array_map() groups the corresponding elements of the arrays it receives into an array of arrays.

Just like array_merge(), this pattern accepts an arbitrary number of arrays, which may be collected in one array and passed with the spread operator. If the arrays have different lengths, array_map() pads the shorter ones with null, so the result always has as many rows as the longest input array.

Array zip is not related to the zip archive, which compress data.

<?php

    $names = ['Alice', 'Bob', 'Carol'];
    $ages  = [30, 25, 35];

    $zipped = array_map(null, $names, $ages);
    // [['Alice', 30], ['Bob', 25], ['Carol', 35]]

    $arrays = [$names, $ages]; // may be more...
    array_map(null, ...$arrays);
    // [['Alice', 30], ['Bob', 25], ['Carol', 35]]

    // shorter arrays are padded with null
    array_map(null, [1, 2, 3], ['a', 'b']);
    // [[1, 'a'], [2, 'b'], [3, null]]

?>

Documentation

See Also

Array, []

array is the array structure.

It may be written as array() or with square brackets [], which is also called the array short syntax.

The keys that serve as index in the array may be string or integers.

An array assigns automatically an integer index to the values appended to it. An arbitrary index may be assigned with the => syntax, or when accessing an element in the array.

Mixed keys in an array refer to the practice of adding elements in the array with both the automatic indexing and the arbitrary assignment.

<?php

    $array = array(1, 2, 3); 
    
    $anotherArray = ['a' => 2, 'b' => 33];
    
    echo $anotherArray['b']; // 33

?>

Documentation

See Also

array_column

array_column() extracts the index or property of the second argument from a list of arrays or objects passed as first argument.

It may also assign a key in regards to that value, from a second index or property.

array_column() omits silently any missing index or property.

array_column() uses the whole array or object as value, when the second argument is null.

array_column() is more efficient than custom code to convert an array into a map.

<?php

    $list = [
        ['a' => 1, 'b' => 'x'],
        ['a' => 2, 'b' => 'y'],
        ['a' => 3, 'd' => 'z'],
    ];
    
    array_column($list, 'a'); // [1, 2, 3]
    
    array_column($list, 'b'); // [x, y]
    
    array_column($list, 'a', 'b'); // [x => 1, y => 2, 0 => 3]
    
    class Elephpant {
        function __construct(public int $a, public string $b, public string $c) {}
    }

    $list = [
        new Elephpant(a: 1, b: 'x'),
        new Elephpant(a: 2, b: 'y'),
        new Elephpant(a: 3, d: 'z'),
    ];
    
    array_column($list, 'a'); // [1, 2, 3]

?>

Documentation

See Also

array_combine()

array_combine() creates an array from an array of keys and an array of values.

Both arguments are treated as lists: their respective keys are discarded, and only their positions are used. The arrays are not sorted.

Both arguments must have the same number of elements.

array_combine() is the opposite of array_keys and array_values together.

<?php

    // adapted from the PHP manual example
    $a = ['green',  4 => 'red', 'c' => 'yellow'];
    $b = ['avocado', 'apple', 'banana'];
    $c = array_combine($a, $b);

    print_r($c);
    
    /**
       Array
    (
        [green] => avocado
        [red] => apple
        [yellow] => banana
    )
    */
    
    var_dump($a === array_combine(array_keys($a), array_values($a)));

?>

Documentation

See Also

array_diff()

array_diff() is a PHP native function that computes the difference between arrays, comparing values, using their string representation.

array_diff() takes an array $array, and one or several other arrays ...$arrays. It returns a new array made of the elements of $array whose value is not present in any of the other arrays, keeping the original keys of $array.

Values are compared as strings, so array_diff() may report false positives when comparing objects, arrays, or values with mixed types that share the same string representation.

There are several variants of this function: array_diff_key() compares the keys, instead of the values. array_diff_assoc() compares both keys and values. array_udiff() accepts a custom comparison callback for the values.

The complement function is array_intersect(), which returns the elements that are shared amongst the arrays.

<?php

    $array1 = ['a' => 'green', 'b' => 'brown', 'c' => 'blue', 'red'];
    $array2 = ['a' => 'green', 'yellow', 'red'];

    $result = array_diff($array1, $array2);
    print_r($result);
    // ['b' => 'brown', 'c' => 'blue']

?>

Documentation

See Also

array_diff_assoc()

array_diff_assoc() is a PHP native function that computes the difference between arrays, comparing both keys and values, using their string representation.

array_diff_assoc() takes an array $array, and one or several other arrays ...$arrays. It returns a new array made of the elements of $array whose key/value pair is not present, with the same key and the same value, in any of the other arrays.

An element is only excluded when both its key and its value match an entry in another array; the same value under a different key, or the same key with a different value, is kept in the result. Values are compared as strings, so the same false-positive risk as array_diff() applies when comparing objects, arrays, or mixed types sharing a string representation.

The complement function is array_intersect_assoc(), which returns the elements whose key/value pair is shared amongst the arrays. array_diff_key() compares keys only, and plain array_diff() compares values only.

<?php

    $array1 = ['a' => 'green', 'b' => 'brown', 'c' => 'blue', 'red'];
    $array2 = ['a' => 'green', 'yellow', 'red'];

    $result = array_diff_assoc($array1, $array2);
    print_r($result);
    // ['b' => 'brown', 'c' => 'blue', 0 => 'red']

?>

Documentation

See Also

array_diff_key()

array_diff_key() is a PHP native function that computes the difference between arrays, comparing keys instead of values.

array_diff_key() takes an array $array, and one or several other arrays ...$arrays. It returns a new array made of the elements of $array whose key is not present in any of the other arrays, keeping the original keys and values of $array.

Since only the keys are compared, and never cast to string, array_diff_key() is safe to use with arrays holding objects, arrays, or resources as values.

The complement function is array_intersect_key(), which returns the elements whose key is shared amongst the arrays. array_diff_assoc() compares both keys and values, while plain array_diff() compares values only.

<?php

    $array1 = ['a' => 'green', 'b' => 'brown', 'c' => 'blue', 'red'];
    $array2 = ['a' => 'yellow', 'b' => 'orange', 'green'];

    $result = array_diff_key($array1, $array2);
    print_r($result);
    // ['c' => 'blue']

?>

Documentation

See Also

array_fill()

array_fill() is a PHP native function which creates an array with $count times a specified $value, starting at integer offset $start_index.

Literal values are copied: references are dropped, and the value only is copied. On the other hand, objects are only copied by their reference: the same object occupies all the requested slots, they are not cloned or made distinct in any way.

array_fill() may easily lead to memory exhaustion, given $count is large enough.

<?php

    $array = [1, 1, 1];
    $array = array_fill(0, 3, 1); 
    
    $array = [-3 => 2, 2, 2];
    $array = array_fill(-3, 3, 2); 
    
    $elephpant = new stdClass();
    $elephpant->i = 1;

    $array = array_fill(0, 2, $elephpant);
    $array[1]->i = 3;
    echo $array[0]->i; // also 3 

?>

Documentation

See Also

array_filter()

array_filter() is a native PHP function that filters elements of an array using a callback.

It iterates over each value of the array, passing it to the callback function. If the callback returns a truthy value, the element is included in the result array.

When no callback is provided, all entries that evaluate to false are removed.

<?php

    $numbers = [1, 2, 3, 4, 5, 6];
    
    // Filter even numbers
    $evens = array_filter($numbers, fn($n) => $n % 2 === 0);
    // [2, 4, 6]
    
    // Remove falsy values
    $data = [0, 1, '', 'hello', null, true, false];
    $clean = array_filter($data);
    // [1, 'hello', true]

?>

Documentation

See Also

array_find()

array_find() is a PHP native function, introduced in version 8.4, that returns the first value of an array for which a callback returns a truthy value, or null if no element matches.

Unlike array_filter() followed by picking the first element, array_find() short-circuits as soon as a match is found, and never builds an intermediate array. It complements array_any() and array_all(), which only test for the existence of a match without returning the matching value, and array_find_key(), which returns the matching key instead of the value.

Since array_find() returns null when nothing matches, and null may also be a legitimate value already stored in the array, code that must tell the two situations apart should use array_find_key() and compare it to null with ===, rather than rely on the returned value alone.

<?php

    $numbers = [1, 3, 4, 7, 10];

    $firstEven = array_find($numbers, fn($n) => $n % 2 === 0);
    // 4

    $found = array_find($numbers, fn($n) => $n > 100);
    // null, no element matches

?>

Documentation

See Also

array_find_key()

array_find_key() is a PHP native function, introduced in version 8.4 alongside array_find(), that returns the key of the first element of an array for which a callback returns a truthy value, or null if no element matches.

It is the key-returning counterpart of array_find(): where array_find() gives back the matching value, array_find_key() gives back its key, which is useful when the position, or the original index, of the match matters more than the value itself, or when that exact element needs to be updated or removed afterwards.

Because 0 and the empty string are valid, yet falsy, array keys, the result of array_find_key() must be compared against null with the identical comparison operator ===, exactly like the classic strpos() syndrome, rather than merely tested for truthiness.

<?php

    $fruits = ['apple', 'banana', 'cherry'];

    $key = array_find_key($fruits, fn($f) => str_starts_with($f, 'b'));
    // 1

    $key = array_find_key($fruits, fn($f) => str_starts_with($f, 'z'));
    // null, no element matches

?>

Documentation

See Also

array_intersect()

array_intersect() is a PHP native function that computes the intersection of arrays, comparing values, using their string representation.

array_intersect() takes an array $array, and one or several other arrays ...$arrays. It returns a new array made of the elements of $array whose value is also present in every other array, keeping the original keys of $array.

Values are compared as strings, so array_intersect() may report false positives when comparing objects, arrays, or values with mixed types that share the same string representation.

There are several variants of this function: array_intersect_key() compares the keys, instead of the values. array_intersect_assoc() compares both keys and values. array_uintersect() accepts a custom comparison callback for the values.

The complement function is array_diff(), which returns the elements that are not shared amongst the arrays.

<?php

    $array1 = ['a' => 'green', 'b' => 'brown', 'c' => 'blue', 'red'];
    $array2 = ['a' => 'green', 'yellow', 'red'];

    $result = array_intersect($array1, $array2);
    print_r($result);
    // ['a' => 'green', 0 => 'red']

?>

Documentation

See Also

array_intersect_assoc()

array_intersect_assoc() is a PHP native function that computes the intersection of arrays, comparing both keys and values, using their string representation.

array_intersect_assoc() takes an array $array, and one or several other arrays ...$arrays. It returns a new array made of the elements of $array whose key/value pair is also present, with the same key and the same value, in every other array.

An element is only kept when both its key and its value match an entry in every other array; the same value under a different key, or the same key with a different value, is excluded from the result. Values are compared as strings, so the same false-positive risk as array_intersect() applies when comparing objects, arrays, or mixed types sharing a string representation.

The complement function is array_diff_assoc(), which returns the elements whose key/value pair is not shared amongst the arrays. array_intersect_key() compares keys only, and plain array_intersect() compares values only.

<?php

    $array1 = ['a' => 'green', 'b' => 'brown', 'c' => 'blue', 'red'];
    $array2 = ['a' => 'green', 'yellow', 'red'];

    $result = array_intersect_assoc($array1, $array2);
    print_r($result);
    // ['a' => 'green']

?>

Documentation

See Also

array_intersect_key()

array_intersect_key() is a PHP native function that computes the intersection of arrays, comparing keys instead of values.

array_intersect_key() takes an array $array, and one or several other arrays ...$arrays. It returns a new array made of the elements of $array whose key is also present in every other array, keeping both the original keys and values of $array.

Unlike array_intersect(), the values themselves are never compared or cast to string, so array_intersect_key() is safe to use with arrays holding objects, arrays, or resources as values.

The complement function is array_diff_key(), which returns the elements whose key is not shared amongst the arrays. array_intersect_assoc() compares both keys and values.

<?php

    $array1 = ['a' => 'green', 'b' => 'brown', 'c' => 'blue', 'red'];
    $array2 = ['a' => 'yellow', 'b' => 'orange', 'green'];

    $result = array_intersect_key($array1, $array2);
    print_r($result);
    // ['a' => 'green', 'b' => 'brown']

?>

Documentation

See Also

array_is_list()

array_is_list() is a native PHP function that checks if the given array is a list.

An array is considered a list if its keys are sequential integers starting from 0. Associative arrays or arrays with gaps, non-integer or out of sequence keys are not considered lists. This function was introduced in version 8.1 to help distinguish between sequential and associative arrays, which is useful when working with functions like json_encode() that treat lists as JSON arrays and associative arrays as JSON objects.

<?php

    $list = [1, 2, 3];
    var_dump(array_is_list($list)); // true
    
    $assoc = ['a' => 1, 'b' => 2];
    var_dump(array_is_list($assoc)); // false
    
    $empty = [];
    var_dump(array_is_list($empty)); // true
    
    $gapped = [0 => 'a', 2 => 'c'];
    var_dump(array_is_list($gapped)); // false

?>

Documentation

See Also

array_key_exists()

array_key_exists() reports if a key has been assigned any value in an array. It reports true if it is, and false otherwise.

array_key_exists() is often compared to isset(), although they have differences: array_key_exists() returns true as long as the index exists, while isset() also checks the corresponding value for not being null.

Unlike its name, array_key_exists() works on array as well as objects. This is a deprecated feature, since PHP 8.0.

<?php

    $array = ['a' => 1, 2, 3 => 3, 4 => null];
    var_dump(array_key_exists('a'  , $array));    // true
    var_dump(array_key_exists(1    , $array));    // false (0 => 2)
    var_dump(array_key_exists('3'  , $array));    // true
    var_dump(array_key_exists(4    , $array));    // true
    var_dump(array_key_exists('abc', $array));    // false

?>

Documentation

See Also

array_key_first()

array_key_first() is a native PHP function that returns the first key of an array, or null if the array is empty.

This function does not modify the internal pointer of the array, unlike using reset() and key().

<?php

    $array = ['a' => 1, 'b' => 2, 'c' => 3];
    
    $key = array_key_first($array);
    // 'a'

?>

Documentation

See Also

array_keys()

array_keys() returns all keys, both integer and string, as a new numerically indexed array.

array_keys() has a second parameter, which filters the keys by their corresponding value. Only the keys with the provided value are reported.

array_keys() has a third parameter, which activates the identity comparison for the second argument, rather than the type-juggling default one.

array_keys() always returns a new array with numeric keys starting from 0. It preserves the order of appearance of the matching keys.

array_keys() returns an empty array, when provided with an empty array. It also works with multi-dimensional arrays, but only scans the first level.

array_keys() does not work on objects. It may work, with caveats, by casting the object to array with (array).

array_keys() is a complement to array_values, which returns only the values. It is the partial contrary to array_combine().

<?php

    $array = [
        'name'  => 'Alice',
        10      => 'ten',
        'age'   => 25,
        'active'=> true
    ];

    $keys = array_keys($array);
    // Result: ['name', 10, 'age', 'active']

?>

Documentation

See Also

array_map()

array_map() is a PHP native function that applies a closure to every element of an array.

array_map() uses the first argument as the callback, and the following subsequent arguments as one argument of that closure each. Any missing value in an array is assigned as null, while a missing argument is a fatal error.

array_map() only provides the value in the array, and not the related key: this should be done with array_walk().

<?php

    function square($number) { return $number * $number; }

    $array = [1,2,3];
    $squared = array_map(square(...), $array);
    // [1, 4, 9];

    function squareSum($first, $second) { return $first ** 2 + $second ** 2; }

    $squareSums = array_map(squareSum(...), [1, 2, 3], [4, 5]); // array_map uses the longest array

?>

Documentation

See Also

array_merge()

array_merge() combines all the arrays passed as arguments into one array.

array_merge() accepts an arbitrary list of arrays: in terms of performances, it is better to call it with all the arrays once, rather than merge arrays one after the other.

<?php

    $array1 = [1, 2, 3];
    $array2 = [4, 5, 6];
    
    array_merge($array1, $array2);
    // [1, 2, 3, 4, 5, 6];
    
    $arrays = [$array1, $array2]; // may be more... 
    array_merge(...$arrays); 
    // [1, 2, 3, 4, 5, 6];

?>

Documentation

See Also

array_pad()

array_pad() is a PHP native function which completes an array up to $length elements with a specified $value. When $length is positive, the padding is to the right, and when $length is negative, it is a padding to the left.

Literal values are copied, while objects are only copied at the reference level: the same object occupies all the requested slots; they are not cloned or made distinct in any way.

array_fill() may easily lead to memory exhaustion, given $count is large enough.

<?php

    $array = [1];
    $array = array_pad($array, 3, 2); 
    $array === [1, 2, 2];
    
    $array = [1];
    $array = array_pad($array, -3, 4); 
    $array === [4, 4, 1];
    
    $elephpant = new stdClass();
    $elephpant->i = 1;

    $array = array_pad([], 2, $elephpant);
    $array[1]->i = 3;
    echo $array[0]->i; // also 3 

?>

Documentation

See Also

array_pop()

array_pop() removes the last inserted element in an array, and returns it. The original array is reduced by one element.

array_pop() removes the last element and the last key of the array. The operation is quick, O(1) of big O complexity.

array_pop() is the opposite operation of array_push() and the [] append operator. With these functions, it is possible to build FIFO stacks.

array_pop() returns the poped value, and modifies the source array in place.

<?php

    $array = [1, 2, 3, 4, 5];
    echo array_pop($array); // 5
    // $array == [1, 2, 3, 4];

    $array = [1, 2, 3, 4];
    $array[] = -2;
    echo array_pop($array); // -2
    
?>

Documentation

See Also

array_push()

array_push() adds the second argument, and all the next, to the end of the array, passed as first argument. A new index is created for each new entry, in order.

array_push() adds the new elements and creates the new keys. It is not possible to specify a key with this function: one should use the $array['key'] = $value syntax.

array_pop() is the equivalent operation of the [] append operator. It is the opposite of array_push(). With these functions, it is possible to build FIFO stack.

<?php

    $array = [0, 1, 2];
    print array_push($array, 3, 4); // 5, the number of elements
    // $array == [0, 1, 2, 3, 4];

    $array = [0, 1, 2];
    $array[] = 3; 
    // $array == [0, 1, 2, 3];

    $array = [0, 1, 2];
    $array[33] = 3; 
    // $array == [0, 1, 2, 33 => 3];
    
?>

Documentation

See Also

array_search

array_search() is a native PHP function that searches an array for a value and returns the corresponding key if found, or false if not found.

It is often used to check if a value exists in an array. When the presence of the value is the main goal of the check, it is advantageously replaced by in_array(). Otherwise, this function is prone to the same trap as strpos(): the returned key may be 0, the first element, which is confused with false in a loose comparison.

array_search() performs a loose comparison by default. Pass true as the third argument to enable strict comparison.

<?php

    $colors = ['red', 'green', 'blue'];

    if(array_search('red', $colors)) {
        print "Found red.";
    }

    // Error! 'red' is at key 0, which is confused with false
    if(array_search('red', $colors)) {
        print "Found red.";
    }

    // This is OK
    if(array_search('red', $colors) !== false) {
        print "Found red.";
    }

?>

Documentation

See Also

array_shift()

array_shift() is a PHP native function that removes and returns the first element of an array. All numeric keys are re-indexed starting from zero; string keys are unaffected.

The operation is O(n) because all remaining numeric keys must be renumbered after the removal. This makes it slower than array_pop(), which removes the last element in O(1).

Together with array_push() or the [] append operator, array_shift() enables a FIFO queue pattern.

<?php

    $array = [1, 2, 3, 4, 5];
    echo array_shift($array); // 1
    // $array == [2, 3, 4, 5];

    $array = ['a' => 'x', 0 => 'y', 1 => 'z'];
    echo array_shift($array); // x
    // $array == [0 => 'y', 1 => 'z'];

?>

Documentation

See Also

array_slice()

array_slice() is a PHP native function that extracts a portion of an array.

array_slice() takes the array $array, starts at the offset $offset and collects $length elements. Then it returns the array.

$offset is the position of the index in the array, not the key itself. As usual, it starts at 0. String keys, arbitrary keys, or arbitrary order of the inserted values are ignored: consider that array_slice() works on the result of array_values(). Use sorting beforehand to ensure the key order is taken into account, when needed.

array_slice() also offers a parameter $preserve_keys, which keeps the original keys: only string keys are preserved, integer keys are reindexed, starting at 0. It is disabled by default.

The complement function is array_splice(), which extracts an array from another, and keeps the external portions.

<?php

    // simple example
    $array = [1, 2, 3, 4,];
    print_r(array_slice($array, 1, 2));
    // [2, 3]

    // use null to reach the end of the array
    print_r(array_slice($array, 2, null));
    // [3, 4]
    
    // with keys
    $array = ['a' => 1, 3 => 2, 3, -1 => 4,];
    print_r(array_slice($array, 1, 2));
    // [2, 3]
    
    // with preserve_keys
    $array = ['a' => 1, 'd' => 2, 5 => 3, -1 => 4,];
    print_r(array_slice($array, 1, 2, true));
    // ['d' => 2, 0 => 3]

?>

Documentation

See Also

array_splice()

array_splice() is a PHP native function that removes a portion of an array.

array_splice() takes the array $array, starts at the offset $offset and collects $length elements. Then it returns the extracted array, and update the incoming $array.

$offset is the position of the index in the array, not the key itself. As usual, it starts at 0. String keys, or arbitrary keys or arbitrary order of the inserted values are ignored: consider that array_splice() works on the result of array_values(). Use sorting beforehand to ensure the key order is taken into account, when needed.

array_splice() also offers a parameter $replacement, which inserts another array in the place of the cut section of the array. By default, it inserts nothing.

The complement function is array_slice(), which extracts an array from another.

<?php

    // simple example
    $array = [1, 2, 3, 4,];
    array_splice($array, 1, 2);
    print_r($array);
    // [1, 4]
    
    // with keys
    $array = ['a' => 1, 3 => 2, 3, -1 => 4,];
    array_splice($array, 1, 2);
    print_r($array);
    // [1, 4]
    
    // with replacement
    $array = [1, 2, 3, 4,];
    array_splice($array, 1, 2, [6]);
    print_r($array);
    // [1, 6, 4]

?>

Documentation

See Also

array_unique()

The array_unique() PHP native function removes duplicate values from an array. It is important to note that it treats values as strings for comparison by default, unless a specific sort flag is provided.

The second parameter, flags, can be used to modify the comparison behavior:

  • SORT_STRING: compare items as strings, by default.
  • SORT_REGULAR: compare items normally. This is equivalent to === comparison, and works with enumerations.
  • SORT_NUMERIC: compare items numerically.
  • SORT_LOCALE_STRING: compare items as strings, based on the current locale.
<?php

    $array = [1, '1', 2, 2];
    
    // Default behavior (SORT_STRING): returns [1, 2]
    var_dump(array_unique($array)); 
    
    // SORT_REGULAR: treats 1 and '1' as different if they are of different types
    // Note: with SORT_REGULAR, it still might return only one value if types are loosely equal
    var_dump(array_unique($array, SORT_REGULAR));
    
    // Preserve keys: array_unique preserves keys by default
    $arrayWithKeys = ['a' => 'red', 'b' => 'green', 'c' => 'red'];
    var_dump(array_unique($arrayWithKeys)); // returns ['a' => 'red', 'b' => 'green']

?>

Documentation

See Also

array_unshift()

array_unshift() prepends one or more elements to the beginning of an array. All numeric keys are reset starting from zero, while string keys remain unchanged. The function returns the new number of elements in the array.

array_unshift() is the opposite of array_shift(), which removes and returns the first element. Together with array_push() and array_pop(), these four functions are used to implement queue, FIFO, or stack, LIFO, data structures.

Note that array_unshift() is an O(n) operation because all integer keys must be renumbered.

<?php

    $array = [1, 2, 3];
    $count = array_unshift($array, 0);
    // $array == [0, 1, 2, 3], $count == 4

    // Prepend multiple elements
    array_unshift($array, -2, -1);
    // $array == [-2, -1, 0, 1, 2, 3]

    // String keys are preserved; integer keys are reset
    $assoc = ['b' => 2, 'c' => 3];
    array_unshift($assoc, 1);
    // $assoc == [0 => 1, 'b' => 2, 'c' => 3]

?>

Documentation

See Also

array_values()

The array_values() PHP native function returns the values in an array, with automatically generated indexes. It indexes anew the values as if they all were appended in the array, one after the other.

The values are in the same order as in the original array.

array_values() provides a way to reach the value by position or offset, in an array, when the keys have been set arbitrarily. For the first value, there is the function array_first().

<?php

    $array = ['a' => 1, 'b' => 2, ];

    // displays [1, 2]
    var_dump(array_values($array)); 

    $array = [-2 => 'a', 3 => 'b', 'c'];
    // displays ['a', 'b', 'c']; 
    // equivalent to [0 => 'a', 1 => 'b', 2 => 'c']; 
    var_dump(array_values($array)); 

    print array_values($array)[0]; // prints the first value, a
    print array_first($array);     // prints the first value, a
    print array_values($array)[1]; // prints the second value, b

?>

Documentation

See Also

array_walk()

array_walk() is a PHP native function that applies a closure to every element of an array.

array_walk() uses the first argument as the array or object with the elements, the second argument as the callback, and the following subsequent arguments as one argument of that closure each. Any missing value in an array is assigned as null, while a missing argument is a fatal error.

The callback may take two arguments. This way, it may apply modifications that take the key into account. This is unlike array_map().

If the walk has to be reflected in the source array, the first argument of the callback must be a reference, and it should be updated.

Although both methods are very similar, array_walk() and array_map() do not have the same argument order, return value nor behavior.

<?php

    function square(&$x, $c) { $x = $x * $x + $c; }
    
    $array = [1,2,3];
    array_walk($array, square(...));
    print_r($array);
    // [1, 5, 11];

?>

Documentation

See Also

ArrayAccess

ArrayAccess is an interface that allows objects to be accessed like arrays using square brackets, similar to accessing elements in a regular array. When a class implements the ArrayAccess interface, it must provide methods to define how the object behaves when accessed like an array.

  • offsetExists($offset): this method is called to check if a specific offset exists in the object. It should return a boolean value: true if the offset exists, false otherwise.
  • offsetGet($offset): this method is called to try to retrieve the value associated with a specific offset. It should return the value at that offset.
  • offsetSet($offset, $value): this method is called to try to set a value for a specific offset. It takes two parameters: the offset and the value to be set.
  • offsetUnset($offset): this method is called to unset or remove a value associated with a specific offset.

Implementing ArrayAccess can be useful to create custom data structures or objects that mimic array behavior, providing a convenient and consistent way to work with data.

ArrayAccess is often complemented with Countable, to make the object yet even more like an array.

<?php

class LimitedArray implements ArrayAccess {
    public $a = 1;
    public $b = 1;
    public $c = 1;

    public function offsetSet($offset, $value): void {
        if (in_array($offset, ['a', 'b', 'c'])) {
            $this->$offset = $value;
        }
        // else ignore
    }

    public function offsetExists($offset): bool {
        return in_array($offset, ['a', 'b', 'c']);
    }

    public function offsetUnset($offset): void {
        // do nothing
    }

    public function offsetGet($offset): mixed {
        if (in_array($offset, ['a', 'b', 'c'])) {
            return $this->$offset;
        }
    }
}

$limitedArray = new LimitedArray();

$limitedArray['a'] = 3;
$limitedArray['d'] = 13;

echo $limitedArray['a']; // 3
echo $limitedArray['d']; // null

?>

Documentation

See Also

ArrayObject

ArrayObject is a native class that provides the functionality of an array with the added features of an object. It extends the base ArrayObject class and implements the ArrayAccess, Countable, IteratorAggregate, and Serializable interfaces.

With ArrayObject, it is possible to create objects that have the behavior of arrays, meaning it is possible to access array elements as properties and use object-oriented methods to manipulate the array.

Operators such as append [], or foreach() loops, are then available with those objects.

On the other hand, ArrayObject fails any array type, and many array functions do not work with the objects: array_key_exists(), array_map(), etc.

Converting an ArrayObject to an array is done with a cast (array) or a call to iterator_to_array().

<?php

    class myObject extends ArrayObject{ }
    
    $variable = new ArrObj([0, 1]);
    
    $variable[] = 2;
    foreach($variable as $k => $v) {
        echo $k . ' => ' . $v . PHP_EOL; 
    }

?>

Documentation

See Also

Arrow Functions

Arrow functions, introduced with the fn keyword, are a type of closure with a specific syntax. They only accept one expression, and automatically import all the variables from the local context of definition.

Arrow functions may also be marked as static, to prevent this import.

<?php

    class Elephpant {
        private int $p = 2;

        function trumpet() {
           $b = 10;
           $fn = fn($a) => $a + $b + 2;
           
           $fn = static fn($a) => $a + $b + $this->p;

           // $this is not allowed in static arrow function
           $fn = static fn($a) => $a + $b + $this->p;
        }
    }

?>

Documentation

See Also

Artifact

An artifact refers to any intermediate or final output that is produced during the development process. This could include compiled code, cache content, libraries, executable files, documentation, diagrams, configuration files, and more. Artifacts are the tangible results of the development process and are often used for testing, deployment, and maintenance of software applications.

Documentation

See Also

As

The as operator has several usages:

  • It is an optional keyword with the foreach() control structure, to access the key of the looped array
  • It is an optional keyword with the use expression, in trait import
  • It is an optional keyword with the use expression, in namespace import

The as operator often works to give a distinct name to an existing structure.

<?php

    use stdClass as StandardClass;

    foreach($map as $key => $value) {
        print "$key => $value\n";
    }

?>

Documentation

See Also

American Standard Code for Information Interchange (ASCII)

ASCII is a character encoding standard used to represent text in computers and electronic devices. It assigns a unique number, or code, to each character, allowing text to be stored and processed digitally.

PHP handles ASCII characters with the functions ord() and chr().

<?php

$string = 'abdc';

echo ord($string[1]); // b = 98

echo chr(100); // d

?>

Documentation

See Also

Aspect-Oriented

Aspect-oriented design structures code so that cross-cutting concerns: behaviors that affect multiple classes or layers without belonging to any single one, are isolated into dedicated units called aspects.

In applications, common cross-cutting concerns include logging, caching, authorization, validation, and transaction management. They are typically implemented through decorators, middleware chains, event listeners, or AOP frameworks.

The key principle is that business logic classes should remain unaware of these concerns: they are woven in by the surrounding infrastructure rather than being called explicitly. This improves cohesion, reduces duplication, and makes each concern independently testable and replaceable.

<?php

// Cross-cutting concern isolated as a decorator
final class LoggingRepository implements UserRepositoryInterface {
    public function __construct(
        private readonly UserRepositoryInterface $inner,
        private readonly LoggerInterface         $logger,
    ) {}

    public function find(int $id): User {
        $this->logger->info('find', ['id' => $id]);
        return $this->inner->find($id);
    }
}

?>

Documentation

See Also

Aspect Oriented Programming

Aspect programming is a programming paradigm that separates business logic from cross-cutting concerns: things that affect many parts of the program but would pollute the happy path of the business logic. For example, validation, formatting, logging or error handling.

Documentation

See Also

Assertions

Assertions are checks that take effect in development and testing environments, but are optimised away to have zero cost in production.

Assertions are disabled in production, by using the zend.assertions directive. Then, they are said zero-cost: they are completely omitted in the code, and not executed.

Assertions are a development tool, and should not be used in production. Be aware that the removal of the assertion may leave the system running with unchecked data.

There are packages providing assertions features and more.

<?php

    $a = foo();
    assert($a !== null, 'Sorry, we got a NULL from foo()!');

?>

Documentation

See Also

AssertionError

AssertionError is thrown when an assertion made with assert() fails.

Unlike most engine errors, AssertionError is raised by user-controlled code: it only fires when the zend.assertions directive enables assertion execution, and the assert.exception directive is left at its default of 1, so that a failed assertion is turned into a thrown error instead of a silent or warning-based failure.

AssertionError extends Error, not Exception, which places it alongside engine-level failures such as TypeError and ArithmeticError rather than the SPL exception hierarchy. Since assertions are meant to be a zero-cost development aid, AssertionError should generally not be relied upon in production flow control: when zend.assertions is set to -1 the assertion code is not even compiled, and no error is thrown at all.

<?php

    $age = -5;
    
    try {
        assert($age >= 0, 'Age cannot be negative');
    } catch (AssertionError $e) {
        print 'Assertion failed: ' . $e->getMessage();
    }

?>

Documentation

See Also

Asset

Web assets, or also assets, is an encompassing term, that designates all essential elements necessary for the successful execution of a web-based project. Specifically, in the context of web design and development, these ‘assets’ pertain to diverse components, such as CSS, JavaScript libraries, textual content, graphics, photographs, videos, and audio files.

Assets are often reduced to their URL, which might be hard coded or dynamically generated.

Documentation

See Also

Assignation

Assignation, sometimes misspelled assignement, refers to the process of assigning a value to a variable. It is a fundamental concept in programming that allows storing and manipulating data.

The main operator of assignation is =. There are secondary operators, such as +=, *=, ??=, … which are called short assignation: they apply a specific operation while assigning.

Finally, there are some inherent assignations: foreach() loops, method calls and list() operator perform assignations without an explicit operator.

<?php

    $a = 'b';
    
    // $c is assigned by 
    foreach([1, 2, 3] as $c) {}
    echo $c; // $c is 3
    
    // list call that assigns values
    [$a, $b, $c] = ['a', 'b', 'C'];

?>

Documentation

See Also

Associative Array

An associative array, also called a hash array, is an array whose keys are strings; there may also be integer index, mixed with the string ones.

In the evolution of PHP, associative arrays evolved into objects, where the index in the array turned into property names.

It is possible to use types others than integer and string with an array syntax: this requires building an object for that. This is the case of Iterator and Weakmap.

<?php

    $associative = ['a' => 1, 'b' => 4, 3 => 5, 6 ];

    echo $associative['a'];

?>

Documentation

See Also

Assumption

An assumption is a piece of code that makes use of knowledge that is not visible in the source.

Assumptions are often related to arrays: after checking that a variable is of type array, some specific indexes are used, while there is no guarantee that they are available.

Assumptions may apply to any type of data.

Assumptions are characterized by a lack of checks, before or after. They are based on code discipline, actual or expected, and hard rules that are thought to never be violated: this never happens.

Assumptions lead to faster code, and faster coding. They also yield errors later, when the assumptions rules are violated.

Assumptions may be upgraded to assertions, by adding an explicit check on the situation.

<?php

    function trumpet($elephpant) {
        if ($elephpant instanceof Elephpant) {
            print $elephpant->getName();
        } else {
            // if $elephpant is not an object of type Elephpant, then it is an array. Where does this come from?
            print $elephpant['name'];

            // if $elephpant is an array, is 'name' always available?

        }
    }

?>

Documentation

See Also

Abstract Syntactic Tree (AST)

An abstract syntax tree, also called an AST, is a tree representation of the abstract syntactic structure of PHP source code.

It is a representation of the code, that focuses on the syntactic elements that are later executed.

Documentation

See Also

Asymmetric Cryptography

Asymmetric cryptography, also called public-key cryptography, is a method of encrypting and authenticating data using two mathematically linked keys, a public key and a private key.

The method is build on three elements:

  • The public key can be shared freely with anyone.
  • The private key is kept secret by its owner.
  • What one key encrypts, only the other can decrypt

RSA, ECC or Elliptic Curve, Diffie-Hellman and DSA are all asymmetric cryptography.

Documentation

See Also

Asymmetric Property

An asymmetric property is a property that specifies the asymmetric visibility. This means that the property has a different visibility for read and for write. By default, visibility is symmetric: identical to write and read.

<?php

    class Elephpant {
        public private(set) int $property;
    }

?>

Documentation

See Also

Asymmetric Visibility

Asymmetric visibility, also called set visibility, is a feature of PHP class properties. They refer to the situation where different scopes may read, or get or write, or set.

Traditionally, the visibility options, private, protected and public, constrain the access to the property, both in reading and writing. With asymmetric visibility, there may be contexts that have different rights of access.

<?php

class Elephpant {
    public private(set) string $weight = 'abc';

    function setWeight($weight) {
        $this->weight = $weight;
    }
}

$elephpant = new Elephpant();
echo $elephpant->weight; // abc
$elephpant->setWeight('def');
echo $elephpant->weight; // def

//
$elephpant->weight = 'ghi';

?>

Documentation

See Also

Async

The async keyword is used in programming, and especially in languages like JavaScript, Python, and C#, to define a function that runs asynchronously. It means that it can perform operations without blocking the rest of the program.

PHP does not support a notion of async. The closest feature is called fiber or parallel processing, yet it is quite different from asynchronous. Generators also provide a pseudo-asynchronous processing.

<?php

    // Starting another process for parallel processing
    shell_exec('php other.php &');

?>

Documentation

See Also

Asynchronous

Asynchronous PHP, often abbreviated as async PHP, refers to the capability of executing PHP code asynchronously, meaning that tasks can run concurrently without waiting for each other to complete. Traditional PHP scripts execute code synchronously, where each task must finish before the next one starts. Asynchronous PHP allows tasks to start and run independently, improving efficiency and performance, especially for tasks like handling multiple HTTP requests, database operations, or file I/O.

There are various libraries and frameworks available for implementing asynchronous PHP, such as Fiber, ReactPHP, Amp, and Swoole.

<?php

    function async_task($data) {
        // Simulate some asynchronous task, like fetching data from an API
        usleep(1000000); // Sleep for 1 second to mimic a time-consuming task
        return "Processed data: $data";
    }
    
    $fiber = new Fiber(function () {
        $data = "Some data to process";
        $result = async_task($data);
        Fiber::suspend($result); // Suspend the fiber and yield the result
    });
    
    // Start the fiber
    $fiber->start();
    
    // Main program can continue execution while the fiber runs asynchronously
    echo "Main program continues...\n";
    
    // Resume the fiber and get the result
    $result = $fiber->resume();
    echo "Fiber result: $result\n";

?>

Documentation

See Also

Atomic Operation

An atomic operation is an operation that is indivisible: it either completes fully or not at all, with no intermediate state visible to other threads or processes. Atomicity is one of the ACID properties of database transactions, and it is also a core concept in concurrent programming.

PHP is typically single-threaded per request, so atomicity concerns arise mainly in:

  • Database transactions: a set of SQL statements executed as a single atomic unit.
  • File operations: using locks to prevent partial writes.
  • Shared memory or caches: using atomic increment/decrement to avoid race conditions.

Without atomicity guarantees, concurrent access can lead to race conditions and data corruption.

<?php

    // Atomic database transaction
    $pdo = new PDO('sqlite::memory:');
    $pdo->beginTransaction();
    
    try {
        $pdo->exec('UPDATE accounts SET balance = balance - 100 WHERE id = 1');
        $pdo->exec('UPDATE accounts SET balance = balance + 100 WHERE id = 2');
        $pdo->commit();
    } catch (PDOException $e) {
        $pdo->rollBack();
    }
    
    // Atomic increment in APCu (shared memory)
    apcu_inc('page_views', 1, $success);

?>

Documentation

See Also

Attack Surface

The attack surface of an application is the sum of all the different points where an attacker could try to enter data, extract data, or trigger unintended behavior. The larger the attack surface, the more opportunities exist for exploitation.

In applications, the attack surface spans several layers:

  • Application code: input handling, query construction, file operations, serialization and deserialization.
  • Infrastructure endpoints: PHP-FPM status pages, API diagnostic routes, health-check URLs: operational tooling that is often less hardened than the main application.
  • Dependencies: every third-party package added to a project extends the attack surface with its own code, its own vulnerabilities, and its own transitive dependencies.
  • PHP extensions and shared libraries: native extensions wrap C libraries whose vulnerabilities directly affect the PHP process.

A key principle is that every new feature or integration expands the attack surface. Modernizing a stack can improve security in many dimensions while simultaneously opening new areas that must be understood and managed.

Reducing attack surface is itself a security strategy: disabling unused extensions, hiding diagnostic endpoints behind authentication, limiting the PHP functions available via disable_functions, and keeping dependencies minimal all shrink the area an attacker can target.

<?php

// FPM status endpoint operational tooling that increases attack surface
// if exposed without access controls
// nginx config: location /status { fastcgi_pass php-fpm; }

// Restricting attack surface via disable_functions in php.ini:
// disable_functions = exec, shell_exec, system, passthru, popen

?>

Documentation

See Also

Attack

An attack on a server is any deliberate attempt to exploit, disrupt, or gain unauthorized access to a server, its data, or its services. These attacks can target vulnerabilities in software, hardware, or human behavior, and are typically carried out by malicious actors for various motives, such as stealing data, causing downtime, or using the server as a launchpad for further attacks.

An attack relies on existing vulnerabilities. It may also exploit published or unpublished 0-day vulnerabilities, or target a specific weakness.

An attack may be automated in various manners, from a brute-force campaign targeting the same vulnerability on a large number of servers, to a tailored attack on a single server.

An attack may be blocked by appropriate counter measures, such as access blocking, bug fixing, configuration application, server moving, etc.

Documentation

See Also

Attribute Class

This is a native PHP attribute, which tells the engine that a class is a PHP attribute.

This attribute is not necessary to make a class a valid attribute. Yet, it is recommended to use it and make the classes explicitly attributes.

<?php

    #[Attribute]
    class ElephpantAttribute { }

    #[ElephpantAttribute]
    class Elephpant { }

?>

Documentation

See Also

Attribute

Attributes are machine readable options that may be added to PHP code. Since PHP 8.0, they are accessible from PHP.

Attributes provide extra and customisable options for the PHP engine, static analysis tools and coders alike.

Attributes are a modern version of the phpdoc comment blocks.

Attributes are backward compatible: they can be used in any PHP version, and are ignored when not supported.

Attributes may or may not have a supporting class: attributes may be used for their semantic value, or with related code.

<?php

    #[Attribute]
    class Elephpant {} // this class is an Attributes

    #[Elephpant]  // This attribute may be instanciated, and executed
    #[Tusk]  // This attribute serves only as a flag. No class is available.
    class Herd {} // this class is an Attributes

?>

Documentation

See Also

Audit Trail

An audit trail, or audit log, is a chronological record of events, actions, or changes that provides documentary evidence of who did what, when, and why in a system, process, or organization. It is a critical tool for accountability, security, compliance, and troubleshooting.

Documentation

See Also

Audit

An audit is a systematic, independent, and documented process for obtaining evidence and evaluating it objectively to determine whether predefined criteria, policies, or standards are being met.

Audits are conducted to verify compliance, accuracy, reliability, and integrity in various contexts, including finance, security, quality management, and software development.

Documentation

See Also

Authentication

Authentication is the proof that a user is indeed who he claims to be. In a couple username/password, the password is the authentication, as only the user is supposed to know it. Identification is the other aspect of the problem.

Documentation

See Also

Authorize

To authorize means to give permission or approval for someone to do something, or to officially empower them to take a certain action.

To authorize relies on a system of permission and privilege, that represents what action or resource is impacted; it also relies on an identification system, to know who is requesting the permission.

The authorizations may be local to the current application, or it may be remote, such as an SSO.

<?php

    if ($user->isAuthorized()) {
        doSomething();
    }

?>

Documentation

See Also

Auto-Increment

An auto-increment column is a numeric column whose value is generated by the database engine on insert, typically by adding one to the previous highest value. It is the most common way to build a surrogate primary key, since the application never has to compute or coordinate the value itself.

MySQL uses the AUTO_INCREMENT column option, PostgreSQL uses SERIAL or an IDENTITY column, and SQLite uses AUTOINCREMENT. Laravel’s migration id() and increments() helpers, and Doctrine’s autoincrement column option, both generate this kind of column.

Because the values are sequential and predictable, auto-increment identifiers exposed in a URL or an API response let an attacker enumerate every record of a resource by walking the integer range, a form of insecure direct object reference. They also leak the approximate row count and growth rate of a table to anyone who can read two consecutive IDs. This is one of the reasons applications obfuscate the value or use a UUID or ULID as the public-facing identifier instead, while keeping the auto-increment integer as the internal primary key for indexing efficiency.

Auto-increment values are not guaranteed to be gap-free: a rolled-back transaction or a deleted row still consumes a value, so the sequence should never be relied upon to reflect an exact count.

<?php

    // Laravel migration
    Schema::create('projects', function (Blueprint $table) {
        $table->id(); // BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY
    });

?>

Documentation

See Also

Preappend File Directive

The auto_prepend_file PHP directive adds a require call before the main file. The file is then automatically executed, and all its definitions are added. They are then available later in the execution.

Only one file is prepended: if several files need to be, they should be included in a centralized file.

Documentation

See Also

Autocompletion

Autocompletion, or autocomplete, also called code completion, is an IDE or editor feature that suggests or completes code while the developer is typing. It speeds up development, reduces typos, and surfaces available APIs without requiring constant documentation lookups.

PHP autocompletion relies on static analysis: type declarations in the source, PHPDoc annotations, and type inference, where a type is not explicitly specified, may be guessed with a high level of confidence. Autocompletion relies on an LSP server: Language Server Protocol.

Autocompletion also applies to IDE plugins, framework-specific stubs, and tools like stub files to enable completion for external components.

<?php

    // Full type information enables accurate autocompletion
    function getUser(int $id): User {
        return new User($id);
    }

    $user = getUser(1);
    $user->  // IDE suggests: getName(), getEmail(), getId() …

?>

Documentation

See Also

Class Autoloading

Autoloading provides a hook to allow the loading of a class, the first time PHP requires it. This is a more flexible way to handle the class definitions than the traditional inclusions, which requires good planning.

Autoloading requires each class, trait, interface or enumeration to be stored in a distinct file. This is the most popular way, yet autoloading allows any other strategy of storage, as long as the class may be loaded based only on its name.

Autoloading relies on the spl_autoload_register() function. Prior to PHP 8.0, it was possible to define the __autoload() method, and this function has been deprecated since PHP 7.2.

Autoloading does not work for global constants and functions. Those still require a specific inclusion mechanism.

In modern PHP, not using class autoloading is considered a bad practice.

<?php

    spl_autoload_register(function ($class_name) {
        include $class_name . '.php';
    });
    
    $obj  = new MyClass1();
    $obj2 = new MyClass2(); 

?>

Documentation

See Also

Automagic

Automagic is a porte-manteau, merging automatic and magic. Some PHP operations are automagic, meaning that a lot more is processed than what it appears.

Such operations usually yield surprise and confusion, or are a cherished feature.

Automagic is mostly used as an adverb, automagically.

<?php

    var_dump(10 === '1e1');  // true
    // PHP automagically converts the string into a number, and 1e1 yields 10. 

    $array = [null => 1, '33' => 2];
    echo $array[0]; // 1
    // PHP converts the NULL into 0
    echo $array[33]; // 2
    // PHP converts numeric strings to strings

?>

Documentation

See Also

Automatic Index

Automatic index is the index that PHP assigns to a value, when it is added to an array, without specifying the index.

By default, the indices start at 0, and are incremented one by one, each time it is needed. It is not incremented when it is not needed.

The automatic index is needed at the definition of the array, or when using the array append operator [].

PHP uses the largest integer index that was used in the array, and increments it. That way, no overwrite of the index appears.

<?php

    $array = ['a', 'b', 'c'];
    // [0 => 'a', 1 => 'b', 2 => 'c']
    
    $array[] = 'd';
    // [0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd']
    
    $array['e'] = 'f';
    // [0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd', 'e' => 'f']
    
    $array[] = 'g';
    // [0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd', 'e' => 'f', 4 => 'g']
    
    $array[11] = 'h';
    // [0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd', 'e' => 'f', 4 => 'g', 11 => 'h']
    
    $array[] = 'i';
    // [0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd', 'e' => 'f', 4 => 'g']
    // [0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd', 'e' => 'f', 4 => 'g', 11 => 'h', 12 => 'i']

?>

Documentation

See Also

Autovivification

Autovivification is the automatic creation of an array when a value is dereferenced.

Autovivification from scalars, including true, is deprecated since PHP 7.4 and removed in version 8.0.

Autovivification from false is deprecated since PHP 8.1.

Autovivification from null is valid.

<?php

    $a = false;
    $a[1] = 2;
    
    $b = null;
    $b[3] = 4;

?>

Documentation

See Also

Autowiring

Autowiring, or auto-wiring, is the ability of the framework to inject dependencies, based on the constructor signature.

Autowiring is based on types, in the signature of the controller.

Autowiring is commonly used in dependency injection, DI containers.

Autowiring reduces boilerplate code, enhances type usage and makes refactoring easier.

<?php

    class Renderer {
        private View $view;
    
        function __construct(View $view) {
            $this->view = $view;
        }
    }

?>

Documentation

See Also

Availability

Availability is the proportion of time a system or service is operational and accessible to users. It is typically expressed as a percentage, such as 99.9% three nines or 99.99% four nines, calculated over a given period.

High availability is achieved through redundancy, fail-over mechanisms, health checks, and careful deployment strategies that minimize unplanned downtime.

Documentation

See Also

Backslash \

\ is a character, also called anti-slash, used in various situations:

  • Start of an escape sequence, in a string
  • Escape character, in various languages
  • Directory separator in path, on Windows systems. It is accepted by PHP, but not recommended.
  • Name separator in a namespace.
<?php

    namespace A\B\C;

    echo \\\\n\\n;  // displays a \n followed by a new line

?>

Documentation

Backed Enum

Backed enums are enumeration which a string or integer equivalent for each of its cases. Each equivalent, like the cases names, must be distinct. They also must be of the type of the backed enumeration: not type juggling on numeric strings or integers happens.

Non backed enumerations are called unbacked enumerations.

<?php

enum Suits: string {
    case HEART = 'heart';
    case CLUB = 'club';
    case DIAMOND = 'diamond';
    case SPADE = 'spade';
}

enum Prime_digits: int {
    case TWO = 2;
    case THREE = 3;
    case FIVE = 5;
    case SEVEN = 7;
}

?>

Documentation

See Also

Backed Property

A backed property is a property with a hook, that actually uses the eponymous property to store the value.

The opposite of a backed property is a virtual property.

<?php

class Elephpant {
    public $trunkLength { get => $this->trunkLength; }
}

?>

Documentation

See Also

Backed

A backed structure has several meanings:

  • Backed enumeration: an enumeration that has an integer or string value
  • Backed property: a property with a hook, that actually stores the value in the property.
<?php

    enum Habitat : int {
        case Savanna = 1;
    }

    class Elephpant {
        private $trunkLength { get => $this->trunkLength;}
    }
    
?>

Documentation

See Also

BackedEnum

The BackedENum interface identifies an enumeration with a string or int value. It works only on backed-enumerations.

This interface is only available for type checks, and cannot be implemented by another class.

This interface ensures the enum::tryFrom() and enum::from() methods and the enum::$value property are available, to convert from and to scalars.

<?php

enum E { case A;} 
enum F: int { case B = 1;} 

var_dump(E::A instanceof BackedEnum); // false
var_dump(F::B instanceof BackedEnum); // true

?>

Documentation

See Also

Backend

Backend refers to the software that runs on the server, and not on the client machine. PHP is a typical backend language.

The complement to backend is the front end.

Documentation

See Also

Backoff

Backoff is a strategy that increases the delay between successive retries of a failed operation, instead of retrying immediately or at a fixed interval.

The most common form is exponential backoff, where the delay grows exponentially with each failed attempt, for example doubling after every failure: 1 second, 2 seconds, 4 seconds, 8 seconds, and so on, usually capped at a maximum delay so the wait does not grow unbounded. The rationale is that a failure is often caused by a temporarily overloaded or unavailable service, and hammering it with immediate retries only makes the problem worse, while a growing delay gives the service time to recover before the next attempt.

Backoff is almost always combined with jitter, a small random variation added to the computed delay. Without jitter, many clients that failed at the same time, for instance after a service restart, would all retry in lockstep at exactly the same moments, producing repeated bursts of load known as the thundering herd problem. Adding randomness spreads those retries out over time instead. Backoff is also typically paired with a maximum number of attempts, or a deadline, after which the operation is abandoned and reported as failed, rather than retried forever.

Backoff logic is commonly implemented by hand around HTTP client calls, or provided by libraries built on top of Guzzle middleware, message queue workers, or job retry mechanisms in frameworks such as Laravel, where a job’s backoff() method or attribute controls the delay before each re-attempt.

<?php

    function withBackoff(callable $operation, int $maxAttempts = 5): mixed {
        $attempt = 0;
        while (true) {
            try {
                return $operation();
            } catch (\Throwable $e) {
                $attempt++;
                if ($attempt >= $maxAttempts) {
                    throw $e;
                }
                $delay = (2 ** $attempt) + random_int(0, 1000) / 1000;
                usleep((int) ($delay * 1_000_000));
            }
        }
    }

?>

Documentation

See Also

Back-tick

Back-ticks are only used to execute a command with the underlying operating system. They are the equivalent of shell_exec().

Since PHP 8.5, they are deprecated, and should be replaced with a call to shell_exec() or exec().

<?php

$dir = `ls`;

?>

Documentation

See Also

Backtrace

A backtrace is a snapshot of the callstack at a specific point in the program’s execution. This is typically needed when an error or exception occurs.

<?php

    function migrate() {
        trumpet();
    }

    function trumpet() {
        debug_print_backtrace();
    }

    migrate();

    /**
    #0 /in/a4eQc(3): trumpet()
    #1 /in/a4eQc(10): migrate()
    */

?>

Documentation

See Also

Backward Compatible

A feature is backward compatible when it can be handled by a previous version than its version of publication. It is automatically ignored by the previous versions, either by design or by luck.

For example, the attributes #[Attribute] are backward compatible: they were introduced in version 8.0, and their syntax, starting as a comment with a #, is backward compatible: it is processed as a comment in previous PHP versions.

Note that this example is partially backward compatible: it may work or not.

The contrary of a backward compatible feature is backward incompatible.

<?php

    #[Attribute] // This is backward compatible
    class Elephpant {
        function trumpet(#[AttributeForParameter] $trunk) { // This is not backward compatible

        }
    }

?>

Documentation

See Also

Backward Incompatible

A feature is backward incompatible when it cannot work with a previous version, and requires a specific version, or more recent.

For example, the function str_contains is backward incompatible, as it was introduced in version 8.0, and is not available in previous versions.

The keyword throw can be used within expressions since PHP 8.0. In older versions, throw was available, but needed to be an instruction on its own.

The contrary of a backward incompatible feature is forward compatible.

<?php

    check() or throw new Exception('Check failed!');

?>

Documentation

See Also

BadFunctioncallException

The BadFunctioncallException exception is thrown if the callback refers to an undefined function or if some arguments are missing.

BadFunctioncallException is defined by the SPL extension. It is not natively used.

<?php

    function trumpet(string $sound) {
        if (empty($sound)) {
           throw new \UnexpectedValueException('trumpet() expects a non-empty string');
        }
    }

?>

Documentation

See Also

Balanced

A pair of tokens is balanced when the opening token has a corresponding and unique closing token.

Tokens that needs balancing:

  • Parenthesis, with ( and )
  • Curly bracket, with { and }
  • Variable delimiters with curly bracket, with ${ and }
  • Square bracket, with [ and ]
  • Single quotes, with '
  • Double quotes, with "
  • Oblic quotes, with \`

Quotes are the same for opening and closing tokens.

The listed tokens must be nested: after an opening token, any new opening token must be closed before the first one can be closed.

Inside quotes, the brackets and parenthesis may be unbalanced, as the accountability is turned off. This is not the case for curly brackets,

Closing tokens are assigned to the last opening token: in case of mismatch, it produces a syntax error.

<?php

    // This is a syntax error.
    // $trunk = ([;

    $herd = '])(['; // this is OK inside quotes
    // the curly brackets must be balanced when they enclose a variable or valid PHP expression.
    // $herd = "{$trunk";

?>

Documentation

See Also

Bang !

!, also called the exclamation mark, is a character, used in various situations.

  • Not operator: var_dump(!1) is false
  • As a wildcard in regex
  • As a wildcard with fnmatch().
<?php

    var_dump(!1);

?>

Documentation

See Also

Base Class

A base class, also called a superclass or a parent class, is a class that serves as the root of an inheritance hierarchy. Other classes extend it to inherit its properties and methods.

A base class may be concrete, meaning it can be instantiated directly, or it may be abstract, preventing direct instantiation and forcing subclasses to implement its abstract methods.

A PHP class may only extend one base class, but it may implement multiple interfaces.

There are native base classes, like Exception and Error, from which all exceptions and errors inherit.

<?php

    class Animal {
        public function breathe(): string {
            return 'inhale/exhale';
        }
    }
    
    class Dog extends Animal {
        public function speak(): string {
            return 'woof';
        }
    }
    
    $dog = new Dog();
    echo $dog->breathe(); // inherited from base class

?>

Documentation

See Also

Base

The term base has two common meanings:

  • Base class: a parent class from which other classes inherit. A base class defines common attributes and behavior shared by all subclasses. A base class is declared with class and extended with extends. Abstract base classes use the abstract keyword to enforce method implementation in subclasses
  • Numeric base: the number of unique digits in a positional numeral system. PHP natively supports base 2, binary, base 8, octal, base 10, decimal, and base 16, hexadecimal integer literals. The base_convert(), bindec(), octdec(), decoct(), hexdec(), and dechex() functions convert between bases
  • Base 64 encoding: an encoding method a binary-to-text encoding scheme that represents binary data in an ASCII string format.
<?php

    // Base class (parent class)
    abstract class Shape {
        abstract public function area(): float;
    }
    
    class Circle extends Shape {
        public function __construct(private float $radius) {}
        public function area(): float { return M_PI * $this->radius ** 2; }
    }
    
    // Numeric base conversions
    echo base_convert('ff', 16, 10); // 255  (hex -> decimal)
    echo base_convert('255', 10, 2); // 11111111  (decimal -> binary)
    
    echo 0b11111111; // 255  (binary literal)
    echo 0xFF;       // 255  (hex literal)
    echo 0377;       // 255  (octal literal)

?>

Documentation

See Also

Base 64 Encoding

Base64 is a binary-to-text encoding scheme that represents binary data in an ASCII string format. It is often used to encode data so it can be safely transmitted over text-based systems such as email, URLs, or JSON, which may not handle binary data well.

Base64 is used to prevent degradation of the message during the transmission: the data is not corrupted by the journey on Internet.

Base64 is not encryption. It does not secure the data: there is no protection against reading by a third party, unless they are not aware of Base64 itself.

Base64 is not related to the notion of mathematical base, such as base 10, binary, octal or hexadecimal.

<?php

    $phpString = 'Well, I can say: 你好!' ;
    
    $encoded = base64_encode($phpString);
    print $encoded.PHP_EOL;
    
    $decoded = base64_decode($encoded);
    print $decoded.PHP_EOL;

?>

Documentation

See Also

basename()

Basename is a PHP native function that returns the name of a file, extracted from a full path.

When passed a second parameter, basename uses it as the file extension and removes it. The file extension is then a string, and includes the dot. It is not possible to provide multiple file extensions.

basename() is locale aware, so it has to match the locale of the filesystem to find and remove the extension in multiple bytes encoding.

<?php

    $path = '/var/www/index.php';
    
    print basename($path); // index.php
    print basename($path, '.php'); // index 
    print basename($path, '.PHP'); // index.php
    print basename($path, 'php'); // index.

?>

Documentation

See Also

Batch

Batch processing refers to the treatment of several items at the same time, instead of one at a time.

Batch may mean all at the same time, or it may refers to processing the elements in several small groups.

Processing in batch is efficient when the overhead of an operation is high per unit, such as storing one row at a time in a database, or when processing everything at once requires too much resources.

Processing in intermediate size batch may also be more efficient than processing everything by unit, or as a whole. It is related to the problem of the elephpant and the bananas.

<?php

    // Processing the array one by one
    foreach($array as $a) {
        $database->store($a);
    }
    
    // Processing the array in one time
    $database->store($array);
    
    // Processing the array by batch of 10
    $chunks = array_chunk($array, 10);
    foreach($chunks as $chunk) {
        $database->store($chunk);
    }

?>

Documentation

See Also

Bcmath

For arbitrary precision mathematics, PHP offers BCMath, which supports numbers of any size and precision up to 2147483647, or 0x7FFFFFFF decimal digits, if there is sufficient memory, represented as strings.

<?php

    echo bcpow(3, 40);  // 12157665459056928801
    echo 2 ** 40;       // 1.2157665459057E+19 (a float)

?>

Documentation

See Also

Behavior

Behavior, is the external, observable appearance or action of a system. It is what a piece of code actually does when it runs, as opposed to what its source merely reads.

The PHP Language Specification distinguishes three degrees of predictability for behavior that is not fully pinned down by the language rules: implementation-defined behavior, where the engine must pick one option and document it; unspecified behavior, where the engine may pick any valid option, with no obligation to document or stay consistent; and undefined behavior, where no result is guaranteed at all, usually because the code violates a language constraint.

Documentation

See Also

Benchmarking

Benchmarking is a process of measuring performances. In the computer science, it usually means the speed of execution of a piece of code, or its usage of memory.

Benchmarks are set up at the code level, to compare various syntaxes and algorithms; per PHP versions, to compare the evolution of features; at application level, where a high level feature is run on a full installation.

Benchmarks are usually a good indicator of performance, and should be reviewed with the environment in mind: the hardware, operating system, versions, configurations, feature description … all have impacts on the final results, or the actual representation of real world situations.

Documentation

See Also

Best Practices

Best practices, or also called good practices, are rules and guidelines that are known to produce a desirable outcome.

For example, ‘comment the code’, ‘use meaningful names’ and ‘optimisation is the root of all evil’ are such rules.

Best practices are often grouped in a ruleset, such as SOLID, DRY or Calisthenics.

It takes some effort to understand the value of the rules, without running into the errors they protect against.

Some best practices focus on syntax level elements, such as forbidding usage of @ operator, or always using strict_types.

Best practices may be at odds one with another one. They may also be rejected by some developers while adored by others. There is no common list of best practices, and it evolves with time.

Documentation

See Also

Big-o-notation

Big O notation is a way to describe how fast an algorithm’s runtime or memory usage grows as the input size gets very large. It answers the question: ‘What happens when I give this algorithm 1000 items instead of 10?’

It describes the shape of the curve on a graph, not the exact speed.

Documentation

See Also

Binary Integer

Integers can be specified in binary, or base 2, notation. Binary integer syntax starts with the prefix 0b and only contains 0 and 1.

Binary integers may be specified as positive or negative. Their size may become very long, and yet, eventually, produce an integer. They may have leading 0, after the prefix 0b.

Binary format exists only at compilation time: at execution time, the integer is in decimal form and has no hint that it was input as a binary number.

Binary numbers are integers until PHP_INT_MAX. Beyond that, they are cast into a decimal number, float, and eventually, are returned as INF.

It is possible to use decbin() and sprintf(), related functions to produce a string representation in the binary format.

<?php

    // 12
    $binary = 0b1100;
    
    // On a 32bit machine (double the size for 64bits one)
    $binary = 0b1111111111111111111111111111111;

?>

Documentation

See Also

Binary Not Operator

The tilde ~ operator returns the opposite value, bit by bit. The value is first converted to an integer, then, negated. This operator returns an integer.

~ is often confused with !, as some usages quite overlap.

<?php

    $a = 3;     // 3 
    $b = ~$a;   // -4
    $c = !$a;   // false

?>

Documentation

See Also

Binary Operator

A binary operator is an operator that operates on a two operands. It performs an operation based on the value of both operand. PHP supports several binary operators, including the following:

  • Assignation operator =
  • Equality operator ==
  • Difference operator !- and <>
  • Identity operator ===
  • Non-identity operator !==
  • Math operators, such as addition +, substraction -, multiplication *, division /, power **, modulo %
  • Comparison operators, such as greater than >, greater or equal than >=, lesser than <, lesser or equal than <=
  • Concatenation, with the dot operator .
  • Spaceship operator, <=>
  • All the short operators, that combines a binary operation with an assignation: for example, add and assign +=

And many others.

<?php

    $a = 1;
    $a +=2;
    var_dump($a === 3); // true

?>

Documentation

See Also

Binary

Binary has several distinct usages:

  • Binary integers: a way to represent numbers with 0 and 1
  • Binary operators: operators that use 2 arguments
  • Binary search: a search technique over a sorted array
  • Binary executable: the compiled version of PHP, not as source code

Generally, binary refers to the binary integers.

<?php

    // 12 in binary 
    $binary = 0b1100;
    
    // > is a binary operator: it takes 2 arguments
    var_dump($binary > 13);

?>

Documentation

See Also

Bind

A closure, when build on a method, is bound to an object. When the closure is executed, it will be with that object. Unless the closure is rebound with another object: in that case, the new object will be used as context for the closure execution.

<?php

class Elephpant {
        public function __construct(private int $age) {    }

    public function trumpet() {  echo $this->age;  }
}

$fn = Closure::fromCallable([new Elephpant(10), 'trumpet']);
$fn();

$fn2 = $fn->bindTo(new Elephpant(99), Elephpant::class);
$fn2();

// $fn is called with another object
$fn->call(new Elephpant (100));

?>

Documentation

See Also

Bitfield

A bitfield is a data structure that packs multiple related boolean flags or small integers into a single integer or sequence of bits, where each bit or group of bits represents a distinct value or state.

Bitfields are stored as integers. They may be specified with the binary integer notation, which makes the individual bits visible.

<?php

    $bitfield = 0b111; // 7

?>

Documentation

See Also

Bitmask

A bitmask is a single integer, or sequence of bits, used to set, clear, or check the state of specific bits in another integer, usually via bitwise operations.

<?php

    $bitfield = 0b111; // 7
    $bitmask  = 0b100; // 4

    $result  = $bitfield | $bitmask; // 0b011 == 3

?>

Documentation

See Also

Bitshift Operators

Bitshift operators << and >> move bits within an integer. The bits are shifted by an number of position, to the right or to the left. They are equivalent to multiplying or dividing by a power of 2.

<?php

$a = 3;       // binary : 11
echo $a >> 1; // binary : 1 (the last 1 is lost)
echo $a << 2; // binary : 1100 

?>

Documentation

See Also

Bitwise Operators

Bitwise operators evaluate specific bits within an integer.

Bitwise operators are convenient to handle bit fields.

  • &, &=: ampersand operator, and
  • |, |=: pipe operator, or
  • ^, ^=: caret operator, xor

All these operators have a short assignation version, as shown above.

These operators differ from logical operators, which convert the value to boolean before manipulation.

<?php

    $a = 3;  // binary : 11
    $b = 7;  // binary : 111
    
    print $a & $b; // 3; binary : 11

?>

Documentation

See Also

Black Box Testing

Black box testing is a testing approach where the tester examines the behavior of a system without any knowledge of its internal code, structure, or implementation.

Only inputs and outputs are considered: the tester provides inputs, either through a UI, an API, or a running application, and checks whether the outputs match the expected behavior. This approach mimics how an actual end-user or an external attacker would interact with the system.

Black box testing is commonly used for functional testing, acceptance testing, and penetration testing, where testers probe an application from the outside, the same way a real attacker would.

Documentation

See Also

Blade

Blade is the templating engine bundled with the Laravel framework. Like Twig, it separates presentation from business logic, but Blade templates compile down to plain PHP and are cached, rather than being interpreted by a separate engine.

Blade’s output syntax matters for security: {{ $value }} automatically passes the value through htmlspecialchars() before printing it, which is the safe default for most output. The unescaped syntax {!! $value !!} prints the raw value with no encoding at all, and is only safe when the value is fully trusted, for instance HTML generated by the application itself, never raw user input. A third form, Js::from($value), is used to safely embed PHP data inside a <script> block: it encodes the value as JSON and escapes characters that would otherwise break out of the script context, which plain {{ }} does not do correctly.

Blade also provides control structures such as @if, @foreach, and @include, as well as reusable layouts through @extends and @section.

<?php
    // resources/views/comment.blade.php

    {{-- Safe: escaped through htmlspecialchars() --}}
    <p>{{ $comment->body }}</p>

    {{-- Dangerous with untrusted data: no escaping at all --}}
    <p>{!! $comment->body !!}</p>

    {{-- Safe way to pass PHP data into a <script> block --}}
    <script>
        const comment = {!! \Illuminate\Support\Js::from($comment->body) !!};
    </script>

?>

Documentation

See Also

Blast Radius

Blast radius, borrowed from the vocabulary of explosives, is the extent of the damage caused when something goes wrong: how many users, services, servers, or how much data are affected by a single failure, bad deployment, or security incident, as opposed to how severe that failure is in isolation.

In deployment and reliability, blast radius is what a canary release, feature flag, or gradual rollout deliberately keeps small: instead of shipping a change to every server or every user at once, it is shipped to a small slice first, so that a regression only affects that slice while it is caught and rolled back. Fault isolation techniques, such as the circuit breaker, the bulkhead, or splitting a monolith into independently deployable services, reduce blast radius by containing a failure to the component where it originates rather than letting it cascade to unrelated parts of the system.

In security, blast radius describes how much an attacker can reach once a single credential, API key, or account is compromised. A database user with full admin rights, or an API token with unrestricted scope, has a large blast radius; the principle of least privilege exists specifically to shrink it, so that a leaked key only exposes the narrow set of resources it was actually issued for.

Reducing blast radius does not reduce the probability of a failure occurring; it reduces the cost when one does, which is why it is a central concern of chaos engineering drills, incident postmortems, and access control design alike.

Documentation

See Also

Blind Variable

A blind variable is a variable that is needed in an expression, but doesn’t carry much semantic value. This is the case in loops, where the local variable is needed for the processing of each element, but is often a generic name.

Blind variables are defined in the host structure.

Blind variables are expected to be used only within their structure, although they do exist beyond.

<?php

    // $key and $value are blind variables
    foreach(source() as $key => $value) {
        doSomething($key, $value);
    }
    
    
    // standard loop syntax
    for($i = 0; $i < 10; ++$i) {
        doSomething($i);
    }

?>

Documentation

See Also

Block

Blocks are zero, one or more instructions, grouped together with or without curly brackets.

A number of commands require blocks of instructions: namespace, use, function, class, trait, interface, enum, closure, switch, match, for, foreach, while, do..while, if-then.

Blocks may require brackets, like for class, switch(), function bodies; they may be optional, like with case, arrow-functions, namespace or loops.

A block may live on its own: it has no impact on the code, although it might be used to arbitrarily group instructions.

<?php

function trumpet($trunk) {
    if ($trunk) {
        $tusk = 1;
    } else
        $tusk = 2;

    return $tusk;
}
?>

Documentation

See Also

Blocking Wait

A blocking wait, or blocking call, also called a synchronous wait, is an operation that suspends the execution of the current process or thread until the operation completes. During a blocking wait, no other work can be done by that execution unit.

Most PHP I/O operations like file reads, database queries, HTTP requests via curl… are blocking by default. The PHP process simply waits until the operation returns a result.

The alternative is non-blocking or asynchronous I/O, where execution continues and a callback or coroutine is invoked when the result is ready. Frameworks such as ReactPHP and Amp provide non-blocking event loops for PHP.

Blocking waits can become a bottleneck in high-concurrency scenarios, as each blocking call ties up a worker process.

<?php

    // Blocking: execution stops here until the HTTP response arrives
    $response = file_get_contents('https://api.example.com/data');
    
    // Blocking: waits for the sleep to complete
    sleep(2);
    
    // Non-blocking alternative using ReactPHP
    $loop = React\EventLoop\Factory::create();
    $browser = new React\Http\Browser($loop);
    $browser->get('https://api.example.com/data')->then(function ($response) {
        echo $response->getBody();
    });
    $loop->run();

?>

Documentation

See Also

Bloom Filter

A Bloom filter is a space-efficient probabilistic data structure used to test whether an element is a member of a set. It can return false positives, indicating an element might be in the set when it’s not, but never false negatives, if it says the element is not in the set, it’s definitely not.

Documentation

See Also

Body

The body, of a function or a command, is the related block that is commanded by the command. It is often enclosed in curly brackets { }, as for function or switch, but sometimes optional, as for foreach or ifthen.

The body is omitted in a method, when the method is abstract. As an abstract method is only its signature, the body is replaced by a semi colon ;.

<?php

    abstract class Elephpant {
        function trumpet() {
            // This block is the body
        }

        // No body for an abstract method
        abstract function forage();
    }

?>

Documentation

See Also

Boilerplate

Boilerplate refers to sections of code, documentation, or configuration that are repeated in multiple places with little or no variation. Boilerplate code is often necessary but can be tedious to write and maintain because it is standardized and reused frequently.

Code generation and libraries reduce boilerplate code, by automating the generation of code.

<?php

// Example: Manual database connection and query: boilerplate is connexion, query, execution, fetch.
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$id]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);

?>

Documentation

See Also

Broken Object Level Authorization (BOLA)

Object Level Authorization is a mechanism that checks if a user has the right to access or execute an action on a specific object. For example, a user may have the permission to update his profile, but not anyone else’s profile.

Such mechanisms are often overlooked, as they are set deep in the application, and the user has been channeled there with all needed information.

BOLA is often detected by manipulating the ids of the objects.

Documentation

See Also

Boolean

A boolean is a value that is either true or false.

PHP’s booleans are constants. They may be prefixed by \, and are case-insensitive. They can’t be redefined in any namespace.

There are operators to convert any data to a boolean, and operators to combine boolean together. There are also bit operators, which process integers as a field of boolean.

Booleans have a related scalar type: bool. There is also a special false type.

<?php

    $a = True;
    $b = \FALSE;

?>

Documentation

See Also

Bootstrap

The bootstrap concept generally means starting something using minimal initial resources and building it up by using the results of earlier steps. It’s the idea of pulling yourself up by your own bootstraps.

Use a small, simple starting point to create a more complex or capable system.

Bootstrapping include the following steps

  • Load composer autoload
  • Define base path
  • Load environment variables
  • Load configuration
  • Create the application object
  • Set up dependency injection container
  • Set up service providers
  • Establish connections to database, logging system, cache
  • Register routes
  • Attach listeners
  • Build the request object
  • Run the controller

These list is a general panorama. The steps may not be in order, not exhaustive not applicable to specific frameworks.

Documentation

See Also

Ownership

Ownership, and Borrow Checking, is a compile-time memory model, central to Rust, in which every value has exactly one owning variable at a time. Moving a value transfers ownership and invalidates the previous owner; borrowing lets code use a value temporarily through a reference, either one mutable borrow or any number of read-only borrows at once, but never both simultaneously. The borrow checker enforces these rules at compile time, which is how Rust prevents data races and use-after-free bugs without a garbage collector.

Because the rules are purely static, a program that violates them is simply rejected by the compiler before it ever runs; there is no runtime cost and no runtime check.

PHP has no ownership model and no borrow checker. Objects are reference-counted and garbage-collected: a value can be referenced from as many variables as needed, simultaneously and without restriction, and the engine tracks lifetime automatically rather than the type system enforcing exclusive access. This removes an entire class of bugs the borrow checker targets, at the cost of PHP being unable to statically guarantee the absence of concurrent, conflicting mutation of the same object from unrelated parts of a program.

Documentation

See Also

Bottleneck

A bottleneck is a place in a piece of software which cannot keep up with the rest of the application. It is the slowest part, and also, the limiting portion of the software. It builds on the image of a bottle, where the neck is smaller to reduce spilling in case of a fall, but reduces output too.

Documentation

See Also

Bracket

Bracket is a generic class of characters.

They include

  • Parenthesis, (), or round brackets
  • Curly {}, or accolades
  • Square [], or brackets

Brackets are a element of the PHP syntax.

<?php

    // curly brackes for block
    {
        // square brackets for array syntax
        $array[1] = 2;
    }

?>

Documentation

See Also

Bracketless

Bracketless refers to situations where a block of code has optional enclosing curly brackets {}.

Bracketless blocks lead to only one expression as a block, which is error prone. Most of the time, the brackets are always required by convention, unless the block is explicitly delimited, as in a do-while().

This is the case with single expressions for(), foreach(), while(). It is the case with do-while and with cases, in switch().

It is also the default usage with the alternative syntax, which does not use brackets for block enclosing.

switch() and match() must have parenthesis around the block of cases: these can’t be bracketless.

Bracketless only applies to curly brackets {}. Parenthesis are mostly used for operator precedence, and, when not, are actually useless. Square brackets are never optional.

<?php

    // bracketless foreach()
    foreach([1,2,3] as $number) 
        print $number . PHP_EOL;
        $a = 1; // This is not part of the loop, even if it looks like so
    
    // bracketless do-while()
    $number = 1;
    do 
        print $number . PHP_EOL;
        ++$number;
    while ($number < 4);

?>

Documentation

See Also

Branch

A branch is one of the two alternative in a if then expression. There is the then branch, and the else branch. There are usually two meanings associated with PHP code:

  • Control-flow branch: the path taken by execution when a condition is evaluated, as in if/else, match() arms, or switch cases
  • VCS branch: a parallel, independent line of development in a version control system such as git, created to work on a feature or fix without disturbing the main line, and later reintegrated through a pull request or a merge commit.
<?php

    // a match with 2 arm, including the default
    if ($a) {
        $branch = 'then';
    } else {
        $branch = 'else';
    }

?>

Documentation

See Also

Breach

A breach is the actual usage of a vulnerability to gain unwanted access to resources on a server.

A breach may:

  • Steal sensitive information, such as, and not limited to, user credentials, financial data, source code
  • Deface the website
  • Install backdoors or malware
  • Use of the server for further attacks, e.g., DDoS, phishing, crypto-mining

After a breach, there is a phase of remediation.

Documentation

See Also

Breadth-First Search

Breadth-first search, or BFS, is an algorithm for traversing or searching a tree or graph that explores all neighbors of a node before moving on to the next level of neighbors. Starting from a root node, it visits every node at distance 1, then every node at distance 2, and so on, expanding outward one full layer at a time.

BFS is typically implemented with a queue: the starting node is pushed in, and then, repeatedly, a node is popped from the front, its unvisited neighbors are marked visited and pushed to the back, until the queue is empty. This first-in-first-out order is what produces the level-by-level traversal, in contrast with depth-first search, which uses a stack, or recursion, and dives down one branch before backtracking.

Because it explores the graph one layer at a time, BFS is the natural choice for finding the shortest path between two nodes in an unweighted graph, since the first time the target node is reached is guaranteed to be via the fewest possible edges. It is used for tasks such as finding the shortest chain of relations in a social graph, crawling a website level by level, or checking whether a graph is connected.

<?php

    function bfs(array $graph, string $start): array {
        $visited = [$start => true];
        $order = [];
        $queue = new SplQueue();
        $queue->enqueue($start);

        while (!$queue->isEmpty()) {
            $node = $queue->dequeue();
            $order[] = $node;

            foreach ($graph[$node] ?? [] as $neighbor) {
                if (!isset($visited[$neighbor])) {
                    $visited[$neighbor] = true;
                    $queue->enqueue($neighbor);
                }
            }
        }

        return $order;
    }

    $graph = [
        'A' => ['B', 'C'],
        'B' => ['A', 'D'],
        'C' => ['A', 'D'],
        'D' => ['B', 'C'],
    ];

    print_r(bfs($graph, 'A')); // ['A', 'B', 'C', 'D']

?>

Documentation

See Also

Break

break is a control structure, which ends execution of the current for, foreach, while, do-while or switch structure.

break accepts an optional argument, which tells how many enclosing structures are to be broken out of.

break should not be confused with continue: continue doesn’t work in a switch, like break does.

<?php

foreach([1,2,3] as $b) {
    // break upon the first even number
    if ($b % 2 == 0) {
        break;
    }
    
    echo $b;
}

foreach([1,2,3] as $b1) {
    foreach([1,2,3] as $b2) {
        // break upon the first even number
        if (($b1 + $b2) % 2 == 0) {
            break 2; // exit both loops
        }
    }
    
    echo $b1 + $b2;
}

?>

Documentation

See Also

Broken Access Control

Broken access control is a category of vulnerability where an application fails to properly enforce what an authenticated, or even anonymous, user is allowed to do. Authentication answers who is this user?, while access control answers what is this user allowed to do?; broken access control happens when the second question is not asked, or answered incorrectly.

Typical instances include bypassing the principle of least privilege by allowing an action that should be denied by default, viewing or editing another user’s record by tampering with an identifier, an API missing checks on some of its endpoints, or a low-privilege user reaching admin-only features by elevation of privilege.

Broken access control is a category, rather than a single flaw: IDOR and BOLA are common, specific instances of it.

<?php

    // Broken access control: the check for admin-only is missing
    function deleteUser(int $id) {
        $db->query("DELETE FROM users WHERE id = $id");
    }

    // Fixed: enforce the role before performing the action
    function deleteUser(int $id, User $currentUser) {
        if (!$currentUser->isAdmin()) {
            throw new UnauthorizedException();
        }
        $db->query("DELETE FROM users WHERE id = $id");
    }

?>

Documentation

See Also

Brownfield

A brownfield project is a software development effort that takes place within or alongside an existing codebase, legacy system, or inherited infrastructure. The term is borrowed from civil engineering, where building on previously developed land, a brown field, requires accounting for existing structures, contamination, or constraints that new construction on a green field would not face.

Brownfield development is the norm in most professional PHP work. The majority of PHP projects in production were not started recently, and carry decisions made years ago, under different requirements, by teams that may no longer be present.

Characteristics of brownfield PHP projects:

  • Legacy constraints: older PHP versions may be the baseline, and introducing modern syntax such as named arguments, readonly properties, or fibers requires either a PHP upgrade or a split codebase.
  • Accumulated technical debt: inconsistent coding standards, mixed paradigms, missing tests, and undocumented assumptions are common. Any new feature must navigate this existing complexity.
  • Migration risk: every change to a shared module, database schema, or API contract risks breaking existing behaviour. Regression testing becomes critical.
  • Incremental improvement: refactoring must be done in stages. The strangler fig pattern, replacing parts of the system piece by piece while keeping the rest running, is a common strategy.
  • Third-party integration: brownfield systems often depend on vendors, external APIs, or legacy libraries that constrain upgrade paths.

The opposite of brownfield is greenfield development: starting a new project from scratch with full freedom over architecture and tooling.

Strategies for managing brownfield PHP code:

  • Introduce static analysis tools, incrementally using a baseline file to suppress existing errors while preventing new ones
  • Add a test harness around untested modules before refactoring them
  • Use PHP-CS-Fixer or Rector to automate style and upgrade migrations without manual churn
  • Enforce declare(strict_types=1) file by file as modules are touched.
<?php

    // Brownfield: adding strict types to an existing file during a refactor,
    // without changing behaviour, as part of incremental improvement.

    declare(strict_types=1);

    // Rector rule example (in rector.php): automatically upgrade syntax in legacy files.
    // $rectorConfig->ruleWithConfiguration(
    //     \Rector\TypeDeclaration\Rector\FunctionLike\AddReturnTypeDeclarationRector::class,
    //     [...]
    // );

    // Characterisation test: lock current (possibly wrong) behaviour before refactoring.
    // $this->assertSame(legacyFunction($input), legacyFunction($input));

?>

Documentation

See Also

browscap

Browscap is a browser capabilities project that provides a database and API for determining the capabilities of a web browser. The term Browscap is often used to refer to the browser capabilities project as well as the configuration file browscap.ini that contains information about various web browsers.

The primary purpose of Browscap is to help web developers tailor their web applications or websites based on the capabilities of the user’s browser. It provides details about the browser type, version, and various other characteristics. This information can be used to adapt the presentation or behavior of a website to ensure compatibility with different browsers.

The Browscap project originally started as a part of the PHP project, and PHP developers can use the information from Browscap to improve the accuracy of functions like get_browser(), which is a PHP function used to get information about the capabilities of a user’s browser.

<?php

    print_r(get_browser($_SERVER['HTTP_USER_AGENT']));

?>

Documentation

See Also

Browser

A browser, short for web browser and also called a navigator, is a software application designed to access, retrieve, and display content from the World Wide Web. It allows users to view and interact with websites, web applications, and online services.

PHP features get_browser() native function, which lists some of the requesting browser capabilities.

PHP acts as a http client rather than a browser, when using the http:// wrappers, the curl extension or the components like guzzle, amphp, reactphp, etc.

Documentation

See Also

Bucket

The term bucket is not commonly associated with a specific concept. In a more general sense, the term bucket is often used in the context of data structures and algorithms to refer to a container or a storage space for holding several elements together.

For example, in the context of hashing or hash tables, a bucket may be used to describe the individual storage locations where key-value pairs are stored. When a hash collision occurs, that is when two keys hash to the same location, the elements with the same hash value are often placed in a bucket, which is a data structure that allows multiple elements to be stored at the same location.

Documentation

See Also

Bug

A bug is a discrepancy between the expected result of a program and its actual result.

Bugs have many different varieties:

  • Code does not compile
  • Program stops before completing, with a ‘Fatal error’
  • Program outputs a wrong result
  • Program outputs a result different from expected
  • Program is vulnerable to security attack
  • Poor performance.
<?php

// a case of syntax error
// echo hello world; 

echo -3 ** 2; // known bug

?>

Documentation

See Also

Build

A build is the automated process of transforming source code into a deployable artifact, performed by a build tool. Build steps typically include: installing dependencies, running static analysis, executing tests, generating assets, and packaging the application.

Build processes are commonly driven by tools such as Make, Phing, Composer scripts, or shell scripts, and are integrated into a Continuous Integration pipeline.

A reproducible build produces the same artifact from the same source code, which is essential for reliable deployments.

<?php

    // composer.json scripts section acts as a simple build runner
    // { "scripts": { "build": ["@lint", "@test", "@analyse"] } }
    
    // Phing build.xml target example:
    // <target name="build" depends="lint,test,package"/>

?>

Documentation

See Also

Bulkhead

The bulkhead pattern isolates the resources used to call different dependencies, so that a slowdown or failure in one dependency cannot exhaust the resources needed to keep serving requests to healthy ones. The name is a nautical metaphor: a ship’s hull is divided into watertight compartments, so a breach in one compartment floods only that section instead of sinking the whole ship.

In practice, a bulkhead caps how many concurrent calls, connections, or workers may be in flight for a given dependency, using a semaphore, a dedicated connection pool, or a separate queue/worker group per dependency. When the cap is reached, further calls are rejected immediately, or shed to a fallback, rather than queued indefinitely behind an already-struggling dependency; this keeps one slow API or database from starving the resources that other, unrelated calls also depend on.

Bulkheads are often deployed alongside circuit breakers: the circuit breaker stops calling a dependency once it is clearly failing, while the bulkhead limits how much damage that dependency can do to the rest of the application while it is still being called.

PHP’s traditional one-request-per-process model already gives some bulkhead-like isolation between requests, but within a long-running process, such as a queue worker, a Swoole/RoadRunner server, or a script fanning out to several APIs, resources must be bounded explicitly: a semaphore-like construct such as a Swoole\Coroutine\Channel with a fixed capacity, a Redis counter with a TTL acting as a distributed semaphore, or a dedicated HTTP client with its own connection pool per dependency.

<?php

    // Bulkhead via a Swoole coroutine channel used as a counting semaphore
    $semaphore = new \Swoole\Coroutine\Channel(20); // capacity: 20 concurrent calls
    for ($i = 0; $i < 20; $i++) {
        $semaphore->push(true);
    }

    $semaphore->pop(); // acquire a slot (blocks if the pool is saturated)
    try {
        $response = callDependency();
    } finally {
        $semaphore->push(true); // release the slot
    }

?>

Documentation

See Also

Business Logic

Business logic, also called domain logic, is the part of the application that encodes the real-world rules, workflows, and decisions that the software is built to fulfill. It is the ultimate goal of the software: the reason it exists.

Business logic answers questions like: how is an invoice calculated? What are the conditions for a user to be eligible for a discount? When is an order considered fulfilled? These rules come from the business domain, not from the technology.

Everything else in the application, like HTTP routing, database persistence, authentication, caching, logging, is infrastructure. Infrastructure exists to serve the business logic, not the other way around. A common design mistake is to scatter business rules across controllers, SQL queries, or framework callbacks, making them hard to find, test, and change.

Well-structured applications isolate business logic from infrastructure. Domain-Driven Design, Hexagonal Architecture, and Clean Architecture all promote this separation. The domain layer, which holds the business logic, should have no dependencies on frameworks, databases, or external services. This makes it independently testable and resilient to technology changes.

Business logic often leaks into controllers, the infamous fat controllers, Eloquent models, the fat models, or stored procedures, which are anti-patterns that couple the domain to infrastructure concerns.

Documentation

See Also

Passing By Reference

When calling a method, or returning from it, data may be passed by value or by reference.

By reference, a reference to the data is passed: any modification on that value inside the method will be reflected in the original value.

This is the alternative way of passing data to methods: the default way is to use by value, which copies the data.

Passing by reference is the default behavior with object. Otherwise, it needs to be declared with the & operator, in the function signature.

Returned values are passed back to the calling context with the same rule as for parameters.

<?php

    $trunk = 0;
    trumpet($trunk);  // displays 1
    print $trunk; // displays 1
    
    function trumpet(&$trunk) {
        ++$trunk;
        echo $trunk;
    }

?>

Documentation

See Also

Passing By Value

When calling a method, or returning from it, data may be passed by value or by reference.

By value, a copy of the data is passed: any modification on that value inside the method will not be reflected in the original value.

This is the default way of passing data to methods: the alternative way is to use by reference.

Passing by value may be memory-intensive when passing a large array. This is not the case for objects, which are always passed by reference.

Returned values are passed back to the calling context with the same rule as for parameters.

<?php

    $trunk = 0;
    trumpet($trunk);  // displays 1
    print $trunk; // displays 0
    
    function trumpet($trunk) {
        ++$trunk;
        echo $trunk;
    }

?>

Documentation

See Also

Byte

A byte is a unit of digital information storage that typically consists of 8 bits. It is the fundamental building block for representing data in computers. A byte can store values ranging from 0 to 255, in an unsigned 8-bit representation.

PHP uses bytes when manipulating strings. Bytes are characters, as long as the string uses ASCII representation, which is by default. Characters might be larger than a byte, and they become multi-bytes.

<?php

    $string = abcd;

    echo strlen($string); // 4

?>

Documentation

See Also

bzip2 Extension

The bzip2 extension handles the bzip2 compression format: read, write and access arbitrary part of files. It also provides a compression format for the output of PHP.

<?php

    // open file for reading
    $bz = bzopen($filename, r);
    
    // output until end of the file
    echo bzread($bz);
    
    bzclose($bz);

?>

Documentation

See Also

C10K

The C10K problem is the challenge of handling 10,000 concurrent network connections on a single server. The term was coined by Dan Kegel in 1999 and became a landmark milestone in server design.

Traditional thread-per-connection or process-per-connection models collapse under this load: spawning 10,000 threads consumes gigabytes of stack memory and floods the OS scheduler. The solution is event-driven I/O, using epoll, kqueue, or WSAPoll to watch thousands of file descriptors simultaneously in a single thread, only waking when a descriptor is actually ready.

C10K-scale concurrency historically required external tools: nginx as a front-end proxy, FrankenPHP workers, or userland event loops from ReactPHP, AMPHP, or Revolt. PHP 8.6 addresses this with the native Io\Poll API, which exposes epoll/kqueue directly without leaving PHP.

The successor challenge, C10M or 10 million connections, requires kernel bypass techniques, that are out of scope for userland PHP.

<?php

    // Without C10K-aware design: one process per connection
    // Fails at high concurrency: each fork() is expensive
    $server = stream_socket_server('tcp://0.0.0.0:8080');
    while ($client = stream_socket_accept($server)) {
        if (pcntl_fork() === 0) { // child per connection: does not scale to 10K
            handle($client);
            exit;
        }
    }
    
    // C10K-aware: single process, event-driven, PHP 8.6 Io\Poll
    use Io\Poll\Context;
    use Io\Poll\Event;
    
    $context = new Context();
    $server  = stream_socket_server('tcp://0.0.0.0:8080');
    stream_set_blocking($server, false);
    
    $context->add($server, Event::Read, function ($handle) use ($context) {
        $client = stream_socket_accept($handle->stream, 0);
        if ($client === false) { return; }
        stream_set_blocking($client, false);
        $context->add($client, Event::Read | Event::OneShot, function ($ch) {
            echo fread($ch->stream, 8192);
            fclose($ch->stream);
        });
    });
    
    $context->run(); // handles thousands of connections in one thread

?>

Documentation

See Also

C2 Framework

A C2 framework is a library of tools to use with a vulnerability, to discover and escalate services on a target website. C2 Framework is also known as a C&C framework, or command-and-control framework.

Among the possible tasks, there are running command system, creating, editing and removing files, starting reverse shells, etc.

C2-framework shall be used once a backdoor has been installed, to widen the control over the target server. The installation of the backdoor is not included in the C2 framework.

<?php

    // example of a simple backdoor, based on the GET method 
    echo @eval($_GET['command']); 

?>

Documentation

See Also

Cache Stampede

A cache stampede, also known as thundering herd or dog-piling, is a failure mode that occurs when many concurrent requests simultaneously discover that a cached value has expired or is missing. All requests then attempt to regenerate the cache at the same time, flooding the backend with redundant work. This is especially destructive under high traffic because the backend, already under load, receives a sudden spike just when it is needed most.

Common mitigation strategies include: locking, where only one process regenerates the cache while others wait or serve stale data, probabilistic early expiration, where the cache refreshes slightly before it expires, based on a probability, and background revalidation, which returns stale data immediately while refreshing asynchronously.

<?php

    // Naive approach: prone to cache stampede
    $value = $cache->get('key');
    if ($value === null) {
        // All concurrent requests reach here simultaneously on expiry
        $value = expensiveComputation();
        $cache->set('key', $value, ttl: 60);
    }
    
    // Lock-based mitigation
    $value = $cache->get('key');
    if ($value === null) {
        $lock = $cache->lock('key:lock', ttl: 5);
        if ($lock->get()) {
            try {
                $value = expensiveComputation();
                $cache->set('key', $value, ttl: 60);
            } finally {
                $lock->release();
            }
        } else {
            // Wait for the lock holder to populate the cache
            $lock->block(4);
            $value = $cache->get('key');
        }
    }

?>

Documentation

See Also

Cache Warming

Cache warming, or warming up, is the practice of proactively populating a cache before real traffic depends on it, instead of letting the first users pay the cost of a cold-cache. It applies to both data and code.

For data, a warm-up script runs the same queries or computations that production traffic would trigger, storing the results in Redis, APCu, or another cache backend, so that by the time a deployment goes live, the hot-cache already holds the most requested entries. This is common after a deployment, a cache flush, or when bringing up a new server behind a load balancer.

For code, PHP has its own form of warming: opcache compiles PHP source into opcodes on first execution and caches them in shared memory; a freshly started worker or a newly deployed server is cold until each file has been compiled at least once. OPcache preloading, see opcache-preloading, warms the code cache ahead of time by compiling an entire set of files at PHP-FPM startup, so the very first request already runs on precompiled opcodes.

Cache warming trades a slower, predictable startup, such as a deployment step or a health-check delay, for a faster and more predictable steady state, avoiding the thundering-herd effect of many cold requests competing to warm the same cache at once, see cache-stampede.

<?php

// Data warm-up: run after every deployment, before the server accepts traffic
function warmUpCache(CacheInterface $cache, ProductRepository $products): void
{
    foreach ($products->findMostPopular(limit: 100) as $product) {
        // Populate the cache proactively: the first real visitor gets a hit,
        // not a cold miss that falls through to the database.
        $cache->get("product:{$product->id}", fn () => $product, ttl: 3600);
    }
}

// Code warm-up: compile the framework's core files into shared memory
// at PHP-FPM startup, referenced from opcache.preload in php.ini
function warmUpOpcache(iterable $files): void
{
    foreach ($files as $file) {
        opcache_compile_file($file); // precompiled: no parsing cost on first request
    }
}

?>

Documentation

See Also

Cache

Cache, or caching, is a technique used to store and reuse the results of expensive operations to improve performance.

There are different types of caches, depending on where they are applied: opcode cache, data cache, query cache, etc.

<?php

    $count = count($array);
    // $count is a cache for the number of elements in the array
    // it saves a call to count() for every loop

    for($i = 0; $i < $count; ++$i) {
        doSomething($i);
    }

?>

Documentation

See Also

Calendar

The calendar extension provides functions to convert dates between different calendars, such as Gregorian, Julian Day Count, Unix Timestamp, French Revolutionary, Jewish, and others.

<?php

    $julian_date = gregoriantojd($m, $d, $y);
    $french = jdtofrench($julian_date);
    
    echo $french;
    
?>

Documentation

See Also

Object Calisthenics

Object Calisthenics is a set of nine coding constraints, introduced by Jeff Bay, meant to be practiced as an exercise to force better object-oriented design habits, rather than followed strictly in production code at all times.

The nine rules are:

  • Only one level of indentation per method.
  • Don’t use the else keyword.
  • Wrap primitive types and strings in dedicated classes.
  • Use only one dot per line, limiting method chaining.
  • Don’t abbreviate names.
  • Keep entities, classes and packages, small.
  • Limit instance variables to two per class.
  • Use first-class collections, wrapping any collection in a dedicated class.
  • Don’t use getters and setters.

Applying every rule everywhere, all the time, tends to produce over-engineered code; the value is in practicing them deliberately to notice where a design leans on primitives, deep nesting, or exposed state more than it should.

Documentation

See Also

Call Graph

In programming languages, a call graph is a representation of the relationships between functions and methods in the codebase. It shows which functions call which other functions, and how data flows through the code.

The representation may be visual, or simply figurative, for further processing and analysis.

In the callgraph, the nodes represent functions or methods, edges represent calls from one function to another and the direction is usually an arrow from function A to function B means A calls B.

Documentation

See Also

Call

A call is the usage action of a definition or declaration.

A call may be a function call, a method call, a static method call or a closure call.

For example, a function is declared, then called. Calling an undefined structure is a fatal error.

A definition must happen before a call. The autoload process allows for last minute loading of a class definition.

A call is usually done on a callable type of data.

<?php

    function trumpet() {}

    // calling a function
    trumpet();

    // calling an undefined function
    forage();
    //Fatal error: Uncaught Error: Call to undefined function forage()

?>

Documentation

See Also

Callables

A callable is an object that can pass the callable type.

A callable may be a callback function or method, represented as a string, a closure or an arrow function.

Objects may also be callable, when their class implement the magic method __invoke().

<?php

function trumpet() { echo __METHOD__; }

call_user_func('trumpet');

?>

Documentation

See Also

Callbacks

Callbacks are functions or methods which are used as parameters for other functions. Such functions are used to customize the calling function. For example, array_map(), which applies a callback to every element of an array, or usort(), which sorts an array using a function.

Callback is akin to a functioncall: it is actually hidden inside the caller function.

Callback may be build with on closures, arrow-functions, native PHP functions, methods and static methods. They also use string, such as strtolower, and array, such as [X::class, 'methodName'], or [$object, 'methodName'], syntax. In fact, anything that is_callable() may be used.

<?php

    $array = ['Damien', 'Dan', 'Daniel', 'Davey', 'David', 'Dennis', 'Derick', 'Dmitry', 'Dustin',];
    $array = array_map('strtolower', $array);

    //['damien', 'dan', 'daniel', 'davey', 'david', 'dennis', 'derick', 'dmitry', 'dustin',];

?>

Documentation

See Also

Callstack

Every time a function, or method, is called, PHP enters a new context. When the function call is finished, PHP exits that context. To keep track of the previous contexts, PHP stores them in a stack: that way, it pops the last context, and goes on.

The callstack is usually not visible explicitly. It may be accessed with the function debug_print_backtrace(), for debugging purposes.

The callstack is an important element of the execution path of PHP. In particular, the callstack should not be too deep. There are also means to limit the depth of the callstack, to avoid running into infinite recursions.

<?php

function migrate() {
    trumpet();
}

function trumpet() {
    forage();
}

function forage() {
    debug_print_backtrace();
}

migrate();

// Displays
// #0 /in/lkZjr(8): forage()
// #1 /in/lkZjr(4): trumpet()
// #2 /in/lkZjr(15): migrate()
?>

Documentation

See Also

Camel Case

Camel case, also written camelCase is a way of writing names without spaces, where:

  • The first word starts with a lowercase letter
  • Each following word starts with an uppercase letter

The capital letters create humps like a camel’s back: this is the origin of the name.

Camel case is often used for method and variable names. Class names, on the other hand, use Pascal case.

<?php

    function calculatePrice(int $price): int {
        return $price * SALE_TAX_RATE;
    }

?>

Documentation

See Also

Canary

Canary, borrowed from the miner’s canary once used to detect dangerous gas underground, has two distinct meanings in software engineering.

  • A canary release, or canary deployment, is a rollout strategy where a new version is deployed to a small subset of servers or users first. Its behavior and metrics are monitored before the rollout is extended to everyone, which limits the blast radius of a regression. It is a close relative of the feature flag and of blue-green deployment.
  • A stack canary, or stack cookie, is a known value placed on the call stack, right before a function’s return address. If a buffer overflow overwrites the return address, it also overwrites the canary first, so the corruption is detected before the corrupted address is ever used. It is a memory-safety technique specific to compiled, memory-unsafe languages such as C and C++.

PHP scripts do not manage the stack directly, so stack canaries are not a PHP-level concern; the Zend Engine that executes PHP, however, is itself written in C, and may benefit from stack canaries at the compiler level. Canary releases, on the other hand, are a common practice for deploying PHP applications.

<?php

    // a simple canary release, gated by a user's id
    if ($user->id % 100 < 5) { // only 5% of users see the new checkout flow
        return new CheckoutFlowV2();
    }

    return new CheckoutFlowV1();

?>

Documentation

See Also

Cancellation

Cancellation is the ability to abort an ongoing asynchronous operation before it completes. In asynchronous and concurrent programming, long-running tasks such as HTTP requests, database queries, or timers may need to be stopped early to conserve resources or respond to user actions.

Cancellation is typically implemented through cancellation tokens: an object passed to an asynchronous operation that signals cancellation on demand. The operation periodically checks the token and stops if cancellation has been requested.

PHP async libraries such as Amp provide CancelledException and cancellation token support for fibers and promises.

Documentation

See Also

Canonical

Canonical PHP are the PHP recommended operators and functions. This adjective is often used in its non-canonical, to highlight that the feature exists, but is not recommended.

There are non-canonical functions, such as sizeof() versus count(), cast operators, such as boolean versus bool, property options, such as var versus public, constants, such as true versus 'on', etc.

Non-canonical operators are often a simple duplicate name for the same feature: they do not had any significant performance loss. In the end, they may be a question of taste or habits.

Canonical URL are HTML <link> tags that help prevent duplicate content issues by specifying the preferred or canonical version of a web page. This is crucial for SEO, because search engines penalize sites with duplicate content.

<?php

    $array = [1, 2, 3];
    echo sizeof($array); // 3

?>

Documentation

See Also

CAP Theorem

The CAP theorem, also known as Brewer’s theorem, states that a distributed data store can provide at most two of the following three guarantees simultaneously:

  • Consistency: every read receives the most recent write or an error. All nodes see the same data at the same time.
  • Availability: every request receives a non-error response, though it may not reflect the most recent write.
  • Partition tolerance: the system continues to operate even if network messages are dropped or delayed between nodes.

Since network partitions are unavoidable in real distributed systems, the practical choice is between CP, that is consistent and partition-tolerant, e.g., HBase, ZooKeeper, and AP, that is available and partition-tolerant, e.g., Cassandra, CouchDB.

PHP applications interact with distributed stores from the client side, selecting a backend that matches their consistency or availability requirements.

<?php

    // CP: Redis with WAIT ensures synchronous replication before returning
    $redis = new Redis();
    $redis->connect('redis-primary', 6379);
    $redis->set('balance', 100);
    $redis->wait(1, 100); // wait for 1 replica, 100 ms timeout
    
    // AP: reading from a replica may return stale data
    $replica = new Redis();
    $replica->connect('redis-replica', 6379);
    $balance = $replica->get('balance'); // possibly a past value

?>

Documentation

See Also

CAPTCHA

A CAPTCHA is a security test used on websites to tell whether the user is a human or a computer program, aka bot. The acronym CAPTCHA stands for Completely Automated Public Turing test to tell Computers and Humans Apart.

CAPTCHA comes in various shapes: they may be a difficult to read picture, a somewhat noisy sound, or various challenges where shapes have to be spotted inside a picture, or place above profiles.

Documentation

See Also

Carriage Return

A carriage return is a whitespace character, that historically represents moving the cursor to the beginning of the line, without changing line. It is often combined to the line feed: on a typewriter, that combination is needed to move the carriage to the beginning of the next line. This does not apply anymore on computers.

A carriage return is represented by the escape sequence \r, in double quote strings. It is also the ASCII code 13.

Carriage return are important when formatting code, as they are at the end of a line.

<?php

    echo "\r";
    echo chr(13); // ASCII code 13

?>

Documentation

See Also

Cascading Failure

A cascading failure is a failure that starts in one component and propagates to dependent components, each overload or error triggering the next, until a localized problem becomes a system-wide outage. A single slow downstream service, for example, can exhaust the connection pool of every caller waiting on it, taking down services that had nothing wrong with them.

Cascading failures are common in tightly coupled, or distributed, systems: a database that slows down backs up application servers, which back up the load balancer, which starts timing out healthy requests too. The same pattern shows up in data pipelines: a single bad record, or an unhandled locale code, can silently drop, or corrupt, every dependent row downstream, so a small conversion bug is amplified into the majority of a migration failing without a loud error.

Cascading failures are mitigated with the same patterns as fault isolation: circuit breakers, that stop calling a failing dependency; timeouts, that prevent one slow call from blocking a thread pool indefinitely; bulkheads, that isolate resource pools between consumers; and retries with backoff, so a recovering service is not immediately overwhelmed again.

Documentation

See Also

Cascading

Cascading is the general pattern where an action, or a change, applied to one element automatically triggers the same, or a related, action on the elements that depend on it, propagating outward from the original point.

Cascading is a neutral, structural concept: it appears as a deliberate feature, such as ON DELETE CASCADE in a database, cascading style sheets, where a rule applies down through nested selectors, or cascading configuration, where a setting inherits from a parent scope unless overridden. It also appears as an unwanted side effect, as in a cascading failure, where a single fault propagates through dependent components until the whole system is affected.

Whether cascading is desirable depends entirely on whether the propagation is intended and bounded. A cascading delete that removes orphaned child rows is convenient; an unbounded cascade that silently deletes far more than expected is a bug. The same duality applies to type propagation, event propagation, and configuration inheritance, which are all instances of cascading.

Documentation

See Also

Case Sensitivity

Case sensitivity refers to the way PHP retrieves names when it looks for a definition: is it in a case-sensitive way, or case insensitive.

The case insensitive named structures are:

  • Classes
  • Enumerations
  • Functions
  • Interfaces
  • Magic methods
  • Magic constants
  • Named parameters
  • Methods
  • Namespaces
  • PHP keywords
  • Traits

The case sensitive named structures are:

  • Class constants
  • Global constants, since PHP 8.0
  • Array index
  • Properties
  • Variables

Case sensitivity has the potential to speed up PHP execution: the gain is a micro-optimisation, that requires millions of calls before yielding significant speed up.

The different case sensitivities in the language is balanced by the common practice to use the original case when using a structure.

<?php

    // two distinct variables
    $x = 1;
    $X = 2;
    
    // two identical calls
    trumpet();
    TRUMPET();
    
    // Calling a class with its definition case
    $db = new SQLite3(); 
    // This is valid, and often reported by tools and conventions
    $db = new SQLite3(); 

?>

Documentation

See Also

Case

case is a PHP keyword, which may be used in three distinct situations:

  • With switch() expression
  • With match() expression
  • With enumeration

case is often complemented with default.

<?php

    enum Suit
    {
        case Hearts;
        case Diamonds;
        case Clubs;
        case Spades;
    }
    
    switch ($i) {
        case 0:
            echo "i equals 0";
            break;
        case 1:
            echo "i equals 1";
            break;
        case 2:
            echo "i equals 2";
            break;
    }

?>

Documentation

See Also

Cast Operator

Cast operators change the type of the variable to the desired type. Conversion between the current format and the target format may happen.

The available casts are:

  • (int), (integer): cast to integer
  • (bool), (boolean): cast to boolean
  • (float), (double): cast to float
  • (string): cast to string
  • (array): cast to array
  • (object): cast to object, of type stdClass. There is no operator to convert to a specific class type.
  • (void): complement operator to the NoDiscard attribute. It is not really a cast operator.
  • (unset): cast to NULL, deprecated since PHP 7.2
  • (real): cast to float.
<?php

    $foo = 10;               // $foo is an integer
    $bar = (boolean) $foo;   // $bar is a boolean

?>

Documentation

See Also

Catch

catch is the complement clause of try. It defines which exception is caught. Optionally, it defines which variable holds the exception when it happens, since PHP 8.0.

Multiple catches may be used. They are applied in the order of writing, and the first clause which succeed is the last.

It is possible to catch multiple exceptions at the same time: in that case, the second exception is chained.

<?php

    try {
        callSomeMethod();
    } catch (\SomeException $e) {
        display("Warning");
    } catch (\SomeSeriousException $e) {
        display("Alert");
    } catch (\Exception) {
        // process the error here
    }

?>

Documentation

See Also

Catchable Fatal Error

A catchable fatal error is a fatal error that PHP allows user code to intercept before the script terminates, instead of stopping execution unconditionally.

Since PHP 7, most fatal errors are represented as Error objects, which implement Throwable and can be intercepted with a try/catch block, making them catchable by nature. Before PHP 7, a narrower category existed as its own error level, E_RECOVERABLE_ERROR, notably raised when an object without a __toString() method was used in a string context; it could only be intercepted through a custom error handler set with set_error_handler(), not with catch.

If a catchable fatal error is not actually caught, it behaves exactly like an ordinary fatal error: execution stops.

<?php

    class NoConversion {}
    
    try {
        $s = (string) new NoConversion(); // fatal error, but catchable
    } catch (\Error $e) {
        echo 'Caught: ' . $e->getMessage();
    }

?>

Documentation

See Also

Continuous Delivery (CD)

Continuous delivery refers to the software development practice where the code changes are automatically built, tested, and prepared for release, so that the software can be deployed to production at any time with minimal manual effort.

Documentation

See Also

Content Delivery Network (CDN)

A Content Delivery Network, or CDN, is a geographically distributed network of proxy servers that delivers content to end-users from the node closest to them, reducing latency and offloading traffic from the origin server.

CDNs cache static assets, images, CSS, JavaScript, fonts, etc. and serve them with appropriate HTTP headers. They can also handle dynamic content acceleration, DDoS mitigation, TLS termination, and edge-side logic.

PHP contributes by setting correct HTTP caching headers so the CDN knows what to cache, for how long, and when to revalidate.

<?php

    // Tell the CDN it may cache this response for 1 day; browsers for 1 hour
    header('Cache-Control: public, max-age=3600, s-maxage=86400');
    header('Vary: Accept-Encoding');
    
    // Provide an ETag so the CDN can validate without a full download
    $etag = md5_file(__DIR__ . '/asset.js');
    header('ETag: "' . $etag . '"');
    
    if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] === '"' . $etag . '"') {
        http_response_code(304);
        exit;
    }

?>

Documentation

See Also

Centralization

Centralization is the concept to bring all identical elements at the same place.

For example, if a literal value is used throughout the code, it may be turned into a global constant, defined in one place, and used everywhere else.

Constants are a tool of centralization for values; functions and classes are a tool of centralization for commands.

Centralization helps the code, as changing one definition propagates the change to different and unrelated parts of the code.

Centralization is sometimes planned, and sometimes discovered with the tide. Then, it has to be extracted from the current code, as some minor local adaption may make it difficult to adapt.

Centralization is a necessary first step to standardisation.

It is also called federation.

Documentation

See Also

Common Gateway Interface (CGI)

CGI stands for Common Gateway Interface. It is a protocol, whose specification enables web server to execute programs. CGI is platform independent, and can be used with any programming language.

PHP may be build as a CGI, but also as a webserver module or a CGI server.

CGI was widely used in the early days of the web, more modern web development approaches, such as server-side scripting have largely replaced CGI in contemporary web development due to performance and security considerations.

Documentation

See Also

Chaining Assignation

Chaining assignation, also called chained assignment or assignment chaining, is the ability to assign the same value to several variables in a single expression, using successive = operators.

The assignment is evaluated from right to left: the rightmost value is assigned first, then the result propagates leftward. Each = operator returns the assigned value, which becomes the operand of the next assignment.

Note that magic methods such as __set() and __get() are never called during chaining assignments. Writing $a = $obj->b = 8; will not trigger __set() on $obj.

<?php

    // Basic chaining assignation
    $trunk = $herd = $tusk = 0;
    // $trunk, $herd, $tusk are all 0

    // Right-to-left evaluation
    $ivory = ($calf = 5) + 3;
    // $calf is 5, $ivory is 8
    
    // Chaining with a function call
    $arr = $count = count([1, 2, 3]);
    // both $arr and $count are 3

?>

Documentation

See Also

Chaining New Without Parenthesis

Since PHP 8.4, it is possible to call a method, access a property or call the __invoke() method immediately upon instantiation, without parenthesis around the instantiation.

With this syntax, there must be parenthesis, albeit empty ones, after the new.

This should not be confused with calling new without parenthesis for the constructor.

<?php

class Elephpant {
    public $property = 1;

    public function trumpet() { echo __METHOD__; }

    public function __invoke() { echo __METHOD__; }
}

new elephpant()->property;  // 1
new elephpant()->trumpet();     // Elephpant::trumpet
new elephpant()();          // Elephpant::__invoke

?>

Documentation

See Also

Chaining

The word chaining appears in several distinct PHP concepts:

  • Chaining assignation: assigning the same value to several variables in a single expression, using successive = operators, e.g. $a = $b = $c = 0;. Evaluated right to left. Magic methods are not triggered
  • Method chaining: calling methods successively on the return value of the previous call, e.g. $object->m1()->m2()->m3(). The result of each method call is used to call the next one
  • Fluent interface: an object-oriented API design pattern that relies extensively on method chaining to create readable, expressive code. Not related to the interface keyword
  • Chaining exceptions: re-throwing a caught exception wrapped inside a new exception, preserving the original error context via Exception::getPrevious()
  • Chaining new without parentheses: since PHP 8.4, calling a method, accessing a property, or invoking __invoke() directly on a new expression without wrapping it in parentheses, e.g. new X()->foo().

Documentation

See Also

Change Data Capture

Change Data Capture, or CDC, is a pattern that tracks and records row-level changes in a database, such as inserts, updates, and deletes, and makes them available to other systems in near real-time.

Instead of periodically polling the database for differences, CDC taps into the database’s transaction log, such as the Write-Ahead Log in PostgreSQL or the binary log in MySQL, to detect changes as they are committed. This makes it both efficient and low-latency.

CDC is commonly used to feed downstream consumers such as search indexes, caches, analytics pipelines, or microservices that need to react to data changes without being tightly coupled to the originating system.

It is a natural complement to event-driven architectures: each database change becomes an event that can be published to a message broker like Kafka, allowing consumers to process it independently and asynchronously.

CDC also supports data replication and synchronization across heterogeneous systems, making it a key building block in ETL pipelines, data warehousing, and zero-downtime migrations.

Documentation

See Also

Channel

A channel is a typed, synchronized queue used to pass values between concurrent tasks, popularized by Go’s chan and modeled on Communicating Sequential Processes, CSP. Rather than sharing mutable memory protected by locks, tasks communicate by sending values through a channel, and the channel itself provides the necessary synchronization. A send can block until a receiver is ready, and a receive can block until a value is sent, depending on whether the channel is buffered.

CSP-style concurrency treats the channel, not the lock, as the primary coordination primitive, and languages built around it, in Go, in Clojure’s core.async, with Erlang-style message passing, encourage structuring concurrent programs as independent tasks connected by channels rather than as threads sharing state.

PHP has no native channel type. Concurrency primitives such as Fiber provide cooperative multitasking within a single thread, but communication between fibers or between processes must be built from lower-level tools: a SplQueue, a message queue extension, shared memory, or a userland library; none of these are integrated into the language as a first-class, typed, blocking channel the way Go’s chan is.

Documentation

See Also

Chaos Engineering

Chaos engineering, or chaos testing, is the practice of deliberately injecting failures, such as added latency, dropped packets, error responses, or killed processes, into a system in a controlled setting, in order to verify that it degrades the way its design intends rather than the way its authors merely hoped. Rather than reasoning about resilience only on paper, chaos engineering exercises the actual failure paths: does a circuit breaker really trip when a dependency starts erroring, do jittered retries really avoid a retry storm, does the error rate really stay inside the error budget.

A chaos drill typically starts in a staging environment and, once the team trusts the results, is cautiously extended to a small slice of production traffic. Common injected faults include artificial extra latency on a dependency, a percentage of 5xx responses, dropped or delayed network packets, and forced restarts of a process or a container. Each drill is run against a stated hypothesis, for example ‘if the payment API is 30% slower, checkouts still succeed within the SLO’, and is considered successful once it becomes boring, that is, once it stops surprising the team, rather than once it stops finding bugs.

PHP applications, because most of their resilience patterns, timeouts, retries, circuit breakers, bulkheads, are implemented by hand or through HTTP client middleware rather than a platform-level service mesh, particularly benefit from chaos drills to confirm that these patterns are actually wired up correctly end-to-end, and not merely present in the code.

Documentation

See Also

Character

A character is a unit of information, that represents represents letters, punctuation signs, ideogram, etc.

Characters may be represented as a byte, on 8 bits, but also on longer sequences, with UTF-8 or UTF-16. By default, PHP uses 8 bits, and there are several extensions to manipulate the encodings.

There is no dedicated type for characters: a string of one element is used for that purpose. There are some special constraints related to manipulating characters inside a string: it is possible to access individual character in a string, with the array syntax, both to read or modify them.

<?php

    $string = 'abc';
    
    echo $string[1]; // display b
    
    var_dump($string[1]);
    //string(1) b

?>

Documentation

See Also

Cheat Sheet

A cheat sheet is a concise, condensed reference document that summarizes the essential syntax, commands, or rules of a language, tool, or process on a single page or a short list, meant to be scanned quickly rather than read start to finish like a manual. Unlike full documentation, which aims to be complete and explain the reasoning behind each feature, a cheat sheet deliberately leaves out context and edge cases to keep only what a reader is most likely to need to look up in the moment, often organized as tables, short code snippets, or bullet lists grouped by topic. In the PHP and web security world, the OWASP Cheat Sheet Series is a widely cited example, offering focused, actionable guidance on specific vulnerability classes, such as cross-site scripting, injection, or insecure direct object references, and it is referenced throughout this dictionary as further reading for exactly that reason. Cheat sheets are useful both for newcomers getting oriented in an unfamiliar language or tool and for experienced developers who need a fast reminder of syntax or a checklist they do not use often enough to memorize.

Documentation

See Also

Checksum

A checksum is a small, fixed-size value derived from a longer piece of data, used to detect errors or verify integrity. It is akin to a fingerprint or a signature.

There are several algorithms to create a checksum: crc32, md5, sha1, sha256.

Checksums are extensively used to check file downloads and network transmissions; to verify stored data, identify revisions in VCS and validate components versions with package managers.

<?php

    echo md5('PHP rocks!');
    
    echo md5_file('/tmp/text.txt');

?>

Documentation

See Also

Child Class

A child class is a class that extends another class. There is no specific keyword related to child classes: unlike parent which is unique and defined, any class that extends a class is its child. A class may have several children.

A child class may be the direct child of a class, or any of the own child.

<?php

// parent class
class Elephpant { }

// child class
class AfricanElephpant extends Elephpant {}

// child class of Elephpant
// child class of AfricanElephpant
class Calf extends AfricanElephpant {}

?>

Documentation

See Also

Continuous Integration (CI)

Continuous integration refers to the automation of the build and test phase of development.

Every revision that is committed triggers an automated build and test. With continuous delivery, code changes are automatically tested, reviewed, and built for a release to production.

Since a lot of these operations a executed one after the other, they are called a pipeline.

Continuous integration is a building block for continuous delivery. This extended notion also include the automated release in production of the code.

Documentation

See Also

Circuit Breaker

A circuit breaker is a general software engineering design pattern used to improve the resilience and stability of distributed systems. It prevents cascading failures by monitoring the calls to external services, like APIs, databases, or microservices. When a service fails repeatedly, the circuit breaker triggers and stops further calls to that service for a predefined period, allowing the target system to recover, and the local service to report the unavailability without producing incorrect values.

After the timeout, it may allow a limited number of test calls to see if the service has recovered.

Documentation

See Also

Circular Reference

A circular reference is a situation where an object has a reference to another object, and vice versa. The circle of reference may have two or more objects.

Circular references create limitations with the garbage collector, which requires more refined checks before removing elements from memory. Usually, the garbage collector removes objects which are not referenced by another object. And, in the case of circular references, the whole circle seems to be in use. This leads to memory leaks.

<?php

$elephpant = new Elephpant();
$herd = new Herd($elephpant);
$elephpant->setHerd($herd);

class Elephpant {
    private Herd $herd;

    function setHerd(Herd $herd) {
        $this->herd = $herd;
    }
}

class Herd {
    private Elephpant $elephpant;

    function __construct(Elephpant $elephpant) {
        $this->elephpant = $elephpant;
    }
}

?>

Documentation

See Also

Class Interface Trait Enumeration (CITE)

CITE stands for Class Interface Trait Enumeration. It represents all four types of PHP structures, also called classlike structures, when they interact together.

In particular, all four of them share the same namespaces, which may create naming conflicts. This is unlike functions and constants, which both have their own namespaces.

<?php

    class Elephpant {}

    interface Migratory {}

    trait Foraging {}

    enum Habitat {}

    const Elephpant = 1;
    function Elephpant() {}

?>

Documentation

See Also

Class Aliases

It is possible to make an alias of a class and call it with this new name. It either relies on the use expression, preferable at the beginning of the namespace, or the class_alias() function, for dynamic and application-wide aliases.

use expressions are valid only in one file, while class_alias() impacts the whole application, once it is called. class_alias() may also be used with dynamic elements, such as variables.

<?php

    use a as b;
    
    class_alias('a', 'c');
    
    class a {
        function __construct() {
            print __CLASS__;
        }
    }
    
    new a;
    new b;
    new c;

?>

Documentation

See Also

Class Constant Syntax

The class constant syntax is the full name of a class constant, formalized in a string. It is namespace\class-name::constant-name.

That representation requires the name of the class to include the full namespace path, with or without the leading \.

The class constant syntax does not work with local use expressions.

The class constant syntax works with the constant() and defined() functions.

<?php

    namespace Zoo\Habitat;

    use Elephpant as Trunk;

    class Elephpant {
        const HABITAT = 'Savanna';
    }

    echo constant('\Zoo\Habitat\Elephpant::HABITAT');
    echo constant('Zoo\Habitat\Elephpant::HABITAT');
    echo constant('Trunk::HABITAT'); // error, no such class as Trunk

?>

Documentation

See Also

Class Constants Visibility

Class constant may have a visibility option. This limits their accessibility to the current class, its class hierarchy or any other class. Visibilities for class constants are: private, protected and public.

<?php

class x {
    // This class can only be used in x
    private const C1 = 1;

    // This class can only be used in x and y
    protected const C2 = 1;

    // This class can be used in x, y and z
    private const C3 = 1;
}

class y extends x {
    // doSomething()
}

class z {
    // doSomething()
}

?>

Documentation

See Also

Static Constant

Static constants are constants that are defined inside a class, an interface, a trait since PHP 8.2, or an enumeration; depending on the containing structure, they are also called an interface constant, a trait constant, or an enum constant.

Static constants have a visibility. Visibility may be public, protected, or private. By default, and for backward compatibility, a constant without a visibility is public.

Static constants may also be overwritten by child classes. They can also use the final keyword, to avoid such behavior.

Static constants are defined at coding time, and cannot be changed later, nor dynamically created.

Static constant syntax is the same as for enumeration cases.

<?php

    class Elephpant {
        public  const HABITAT = 1;
        private const WEIGHT = 2;
        private const string TYPE = 'valid';
    }

?>

Documentation

See Also

Class Entities

An entity represents a single object, with a unique identifier and a set of properties. The entity is usually stored in a database for long times. The type of the entity is called its model.

Documentation

See Also

Class Hierarchy

The class hierarchy is a list of classes, which are extending one from another. The extended classes are parents, and the extending classes are children. Classes extending the same class are also called siblings.

The depth of the class hierarchy is a measure of the complexity.

<?php

    class Elephpant {}

    class AfricanElephpant extends Elephpant {}

    class Calf extends AfricanElephpant {}

    class PlayfulCalf extends Calf {}
    class ShyCalf extends Calf {}

?>

Documentation

See Also

Class Hoisting

Class hoisting is a compilation mode where the declarations of functions, classes… are moved before their actual usage.

This allows the usage of functions that are declared later in the code.

PHP doesn’t do class hoisting: it does two passes on the code, and later, triggers the autoload if a class is missing.

<?php

// displays trumpet
trumpet();

function trumpet() { echo __FUNCTION__; }

?>

Documentation

See Also

Class Invasion

Objects of the same type have access to each others private and protected features, like properties, constants and methods, even though they are not the same instances.

This means that the host object of a class A can call any method and property on a different object of the same class.

It also works between siblings class. When the called method is defined in the parent class, protected methods are also accessible that way.

Class invasion works on private and protected methods, properties and constants.

Class invasion doesn’t work when running an external closure inside the class.

<?php

// Example of Host class accessing local object (direct class invasion)
class Elephpant {
    private $p = 'abc';
    private const HABITAT = 'def';

    private function privateMethod() { echo __METHOD__; }

    function sniff(Elephpant $other) {
        echo $other->p;
        echo $other::HABITAT; // also works on constant, though less useful
    }

    function set($s) {
        $this->p = $s;
    }

    function mirrorTest() {
        // The current object ($this) calls the local object's private method
        $elephpant = new Elephpant;
        $elephpant->privateMethod();
    }
}

$matriarch = new Elephpant;
$matriarch->set('xyz');

$calf = new Elephpant;
$calf->sniff($matriarch);
// display xyzdef

// class invasion between sibling classes
class theParent {
    // Necessary. Could be abstract too.
    protected function execute() { echo __METHOD__; }
}

class sister extends theParent {
    // cannot be called outside of a sibling class instance
    protected function execute() { echo __METHOD__; }
}

class brother extends theParent {
    // calling a sister's class method
    function greetSibling($sibling) { $sibling->execute(); }
}

(new brother)->greetSibling(new sister);

?>

Documentation

See Also

Class Operator

Class operator is the ::class, added to a class, interface, trait or enumeration identifier. It returns the fully qualified name of the class, according to the current code.

::class is affected by use expressions, but not by class_alias() function.

<?php

// class operator in action
// This is an unknown class, so it displays A\B
echo A\B::class;

// This is an 'use' class, so it displays A\B
use A\B as D;
echo D::class;

// class_alias creates a new class, so it is different. 
class E{}
class_alias('E', 'F');
echo F::class;

?>

Documentation

See Also

Class

Basic class definitions, plural classes, begin with the keyword class, followed by a class name, followed by a pair of curly braces which enclose the definitions of the properties and methods belonging to the class.

A class name may be validated with the following regex: ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$; and by avoiding a list of PHP keywords, such as namespace, class, interface, etc.

<?php

class Elephpant {
    const HABITAT = 1;

    private $weight = 2;

    function method() {
        /// and more
    }

}

?>

Documentation

See Also

class_alias()

The class_alias() function creates an alias for a class, interface, enum or trait. Then, the alias may be used in place of the original name anywhere in the application, including in use expressions.

Since version 8.3, class_alias() supports the creation of aliases with native PHP classes.

class_alias() is also usable on interfaces, enumerations and traits.

Once created, the objects are of the original class. The alias name doesn’t stick to the objects, and it is not possible to know if the object was created as an alias or the original class. The alias may be used with types.

There is no equivalent to class_alias() for functions, or constants.

<?php

class_alias(stdClass::class, StandardClass::class);

$object = new StandardClass();

// stdClass
print gettype($object);

?>

Documentation

See Also

class_implements()

class_implements() returns an array of all interfaces implemented by a given class, including interfaces implemented by its parent classes. The keys and values of the returned array are both the interface names.

An optional second parameter, by default true, controls whether the autoloader should be invoked if the class does not yet exist. Pass false to suppress autoloading.

class_implements() returns false if the class does not exist and autoloading is disabled.

Related functions are class_parents(), which returns parent classes, and class_uses(), which returns traits used by the class.

<?php

interface Countable {}
interface Stringable {}

class MyCollection implements Countable, Stringable {
    public function count(): int { return 0; }
    public function __toString(): string { return ''; }
}

$interfaces = class_implements(MyCollection::class);
// ['Countable' => 'Countable', 'Stringable' => 'Stringable']

// Also works with a string class name
$interfaces = class_implements('MyCollection');

// Works on instances too
$obj = new MyCollection();
$interfaces = class_implements($obj);

var_dump(isset($interfaces['Countable'])); // true

?>

Documentation

See Also

Clean Architecture

Clean Architecture is a programming paradigm, where code is distributed in four layers: framework, interface adapters, application business rules, enterprise business rules. The layers are linked by the Dependency rule.

Documentation

See Also

Clean Code

Clean code refers to code that is well-organized, easy to read, and easy to maintain. It follows best practices and principles that contribute to the overall quality of the codebase. Clean code is not only about functionality but also about readability, simplicity, and maintainability. It is a concept introduced by Robert C. Martin in his book Clean Code: A Handbook of Agile Software Craftsmanship.

Documentation

See Also

Command Line Interface (CLI)

PHP provides support for a Command Line Interface mode, also called CLI, which allows developers to execute PHP scripts directly from the terminal or command prompt without needing a web server. In this mode, commands are passed as a file or lines of text, and the PHP interpreter processes them sequentially. This feature is particularly useful for automation tasks, cron jobs, scripting, testing, or running PHP-based tools. Additionally, the CLI mode offers access to command-line arguments, making it possible to write interactive scripts or utilities that can process user input or parameters at runtime.

Documentation

See Also

Client

A client is a piece of software that connects to a server to send it queries, and receive responses.

The client-server paradigm is a base for internet communications.

Documentation

See Also

Clock

A clock abstraction encapsulates the current time behind an interface, making code that depends on the current time testable with a controlled, deterministic value instead of the real system clock.

PSR-20 standardizes this with ClockInterface, which exposes a single method: function now(): DateTimeImmutable. Rather than calling new DateTimeImmutable() or time() directly, a ClockInterface is injected as a dependency, giving tests full control over the perceived time.

PHP 8.3 introduced the native DateTimeImmutable::createFromTimestamp() method for testing purposes.

<?php

    use Psr\Clock\ClockInterface;
    
    final class Scheduler {
        public function __construct(private readonly ClockInterface $clock) {}
    
        public function isExpired(DateTimeImmutable $expiresAt): bool {
            return $this->clock->now() > $expiresAt;
        }
    }

?>

Documentation

See Also

Clone

Clone creates a duplicate of an object.

By default, PHP creates a shallow clone: it only makes a copy of the scalar properties, and it keeps the references and any objects untouched. This means that object properties are shared between an object and its clone.

To perform a deep clone, aka to clone an object and its referenced properties, there is the magic method __clone().

Until PHP 8.5, clone was only an operator. Ever since, it is also a native PHP function, which accepts a second argument to update the public properties. That argument prevents using the magic method __clone, although both may happen at the same time. When __clone and clone() update the same property, the clone() is applied last, and stays.

Cloning had a conflict with the readonly properties, until updating readonly during the cloning operation was allowed, in version 8.5.

<?php

    class Elephpant {
        protected $weight = 1;

        function __clone() {
            $this->weight = 2;
        }
    }

    // instantiation
    $original = new Elephpant;

    // cloning
    $twin = clone $original;

    $secondTwin = clone($original);  // parenthesis are now useful
    echo $secondTwin->weight;  // 2
    $customTwin = clone($original, ['weight' => 3]);
    echo $customTwin->weight;

?>

Documentation

See Also

Close Naming

Close naming is the creation of names that have little differences between them, and which leads human to easily confusing them more often.

The confusion may originate from different sources:

  • Names with only one or two letters of difference: get/set; max/map; type/typo;
  • Swaps of parts of the name: xmlDiff/diffXml;
  • Names with hard to read letters: x0/xO/xQ
  • Names with possible opposite means: host, client,

Close naming does not always yield error, but requires extra attention to ensure it is not confused with another structure.

Close naming may happen with any named structure: variables, methods, classes, constants, etc. It is part of healthy coding conventions.

Documentation

See Also

Close Tag

PHP commands are placed between the PHP tags, <?php and ?>. The second tag is called the closing tag.

Closing tag allow to finish a PHP tag, and switch back to non-interpreted code. The text following the closing tag is then display raw, until the next PHP tag.

When a file online contains PHP code, the closing tag is not necessary. Its absence even prevents the accidental adding of white space, which create output errors.

<?php
    // here, PHP code
    
    // the closing tag
    ?>Here, raw text, always displayed
    <?php
    // more PHP code
    
    // No final closing tag

Documentation

See Also

Closed Source

Closed source, also called proprietary software, means that the source code is not publicly available. Only the creator or owning company can view, modify, or distribute the code.

Documentation

See Also

ClosedGeneratorException

A ClosedGeneratorException is an exception that occurs when the code tries to perform an operation on a generator that has already been closed. Generators iterates over a set of values without needing to create an array to hold all the values in memory at once.

Once a generator is closed, it cannot be used for further iteration. Any attempt to use methods like next(), send(), or throw() on a closed generator throws a ClosedGeneratorException, to indicate that the generator is no longer available for iteration.

<?php

// Code example from Ben Peachey (see external links)
// Adapted for presentation purposes

class CustomException extends Exception {}

function from() {
    yield 1;
    throw new CustomException();
}

function gen($gen) {
    yield from $gen;
}

$gen = from();
$gens[] = gen($gen);
$gens[] = gen($gen);

foreach ($gens as $g) {
    $g->current(); // init.
}

foreach ($gens as $i => $g) {
    try {
        $g->current();
        $g->next();
    } catch (\ClosedGeneratorException $e) {
        print 'Caught ClosedGeneratorException'.PHP_EOL;
    } catch (\Exception $e) {
        print 'Caught Generic Exception'.PHP_EOL;
    }
}

?>

Documentation

See Also

Closure Binding

A closure acquires values from its context of creation. When the closure is created in a different context than wished, one may rebind the closure to another context.

This is done with the two methods Closure::bind() and Closure::bindTo().

<?php

    class Elephpant {
        private static function trumpet() { return 1;}
    }

    $closure = function() {
        // Self is undefined here, since it is not inside a class
        return self::trumpet();
    };

    // Self now defined, and set to Elephpant
    $bcl1 = Closure::bind($closure, null, 'Elephpant');

?>

Documentation

See Also

Closure Class

Closure is a PHP native class that is the result of the closure syntax. It is also the result of an arrow function syntax, and a call to first class callable.

The Closure class offers methods to call the closure, bind it to new objects, or create more, from a callable.

<?php

$closure = function ($a) use ($b) {
    return $a + $b + 1;
};
var_dump($closure);

$arrowFunction = fn () => 1;
var_dump($arrowFunction);

$firstClassCallable = strtolower(...);
var_dump($firstClassCallable);

?>

Documentation

See Also

Closure

Closures, also called lambda functions, are anonymous functions: functions without a name. They are also supported by the eponymous Closure class.

They are close to the arrow-functions. They are also created with the ... operator, also known as the first class callable.

<?php

    $closure = function ($a) use ($b) {
        return $a + $b + 1;
    };
    print get_class($closure); // Closure

    $closure2 = strtolower(...);
    print get_class($closure2); // Closure

    $closure3 = fn($a, $b) => $a + $b;
    print get_class($closure3); // Closure

?>

Documentation

See Also

Cloud

Cloud computing refers to the delivery of computing services, servers, storage, databases, networking, software, analytics…, over the internet. Instead of owning and maintaining physical hardware, developers and organizations rent these resources from cloud providers on a pay-as-you-go basis.

The main service models are:

  • IaaS, Infrastructure as a Service: virtual machines, storage, networking
  • PaaS, Platform as a Service: managed runtime environments, databases, deployment pipelines
  • SaaS, Software as a Service: fully managed applications

For PHP applications, cloud platforms provide hosting environments, e.g. AWS Elastic Beanstalk, Google Cloud Run, Azure App Service…, managed databases, object storage like S3, and serverless functions. The cloud enables horizontal scaling, geographic distribution, and resilience.

<?php

    // Reading AWS S3 object using the AWS SDK
    require 'vendor/autoload.php';

    $s3 = new Aws\S3\S3Client([
        'region'  => 'eu-west-1',
        'version' => 'latest',
    ]);
    
    $result = $s3->getObject([
        'Bucket' => 'my-bucket',
        'Key'    => 'my-file.txt',
    ]);
    
    echo $result['Body'];

?>

Documentation

See Also

Content Management System (CMS)

A CMS stands for Content Management System. It’s software that creates, edits, organizes, and publishes content on a website without needing to write code.

PHP has a lot of CMS. Here is a list:

  • WordPress
  • TYPO3
  • Textpattern
  • Sulu
  • ProcessWire
  • octoberCMS
  • Joomla
  • Drupal
  • Bolt CMS

A CMS is a application that deals with publishing content online.

CMS may be open source or proprietary. They usually come with a marketplace, which publishes third-party plugins, extensions or components.

The list above is not exhaustive. It is in alphabetical order.

Documentation

See Also

Coalesce Operator

The coalesce operator ??, also called the null coalesce or null ternary operator, returns its first operand if it is set and not NULL. Otherwise it will return its second operand. It was introduced in version 7.0 to replace the common but verbose isset($x) ? $x : $default pattern, while also silencing the notice that would normally be raised when reading an undefined variable, array key, or property.

The operator is chainable: $a ?? $b ?? $c evaluates left to right and returns the first operand that is set and not NULL, falling through to the last operand otherwise. Since PHP 7.4, it also has an assignment form, ??=, which assigns the right-hand value only if the left-hand variable is currently unset or NULL, making it convenient for lazily initializing defaults.

Because ?? only checks for NULL, it is not a general-purpose replacement for the ternary operator: falsy-but-non-NULL values such as 0, "", or false are returned unchanged rather than replaced by the fallback.

<?php

    class Elephpant { }

    // instantiation
    $trunk = new Elephpant;

    // cloning
    $herd = clone $trunk;

?>

Documentation

See Also

Code Architecture

Code architecture refers to the high-level design and organization of a software system. It defines how the codebase is structured, how components interact, and the principles or patterns used to ensure the system is maintainable, scalable, and robust. Good code architecture is the foundation for building software that is easy to understand, extend, and debug.

Key Aspects of Code Architecture:

  • Modularity: breaking the codebase into smaller, reusable modules or components, e.g., classes, functions, packages
  • Separation of Concerns: dividing the system into distinct layers or components, each responsible for a specific task, e.g., presentation, business logic, data access
  • Directory Layout: organizing files and folders in a logical way, e.g., by feature, layer, or domain
  • Namespace Layout: code organization by namespaces

Frameworks bring their own code architecture.

Documentation

See Also

Code Coverage

Code coverage lists all the source code lines that were used while executing a test.

Each line that is reported by code coverage is a line that contributed to the success of the test. By extension, each line that was not part of the code coverage may be hosting an unexpected behavior, leading to a bug.

Documentation

See Also

Code Formatter

A code formatter is an automated tool that apply coding conventions to the source code.

It may, for example, move the opening bracket of a block on the name of the signature or below; it may add a space between a cast operator and its expression; etc.

Code formatters modifies the presentation of the code, and do not change the underlying execution of it: although, some of the coding conventions may cross that line. For example, rewriting != clauses to == in ifthen usually leads to voluminous modifications.

Some code formatters only report specifications violations. Others apply corrections automatically.

Popular coding conventions are PSR-12, or per framework, such as Symfony Coding Standard, CakePHP, CodeIgniter, Wordpress, etc.

<?php

    // two distinct coding conventions.
    function trumpet() { return 1; }

    function forage()
    {
        return 2;
    }

?>

Documentation

See Also

Coding Formatting

Coding formatting is a coding convention that specify how the code should be written and presented. Formatting only impacts the presentation of the code, not its execution.

For example, arrays must be in short array form [1,2,3] instead of long form array(1,2,3). They also should always be on several lines when the number of items is over 5, and the last element must have the trailing comma.

Documentation

See Also

Code Freeze

A code freeze, also called a feature freeze, is a common practice in software development where all changes to the source code are temporarily halted or restricted for a specific period, typically leading up to a major release or milestone.

Documentation

See Also

Code Generation

Code generation is the automatic production of source code from a higher-level specification, model, schema, or set of rules. Rather than writing repetitive or boilerplate code by hand, a generator reads a description and emits the corresponding PHP source, which is then used directly or compiled into the application.

Code generation takes several forms:

  • Schema-driven generation: an ORM such as Doctrine generates entity classes, migration files, and repository stubs from a database schema or mapping configuration.
  • Attribute-driven generation: attributes on classes, properties, and methods, in versions 8.0+, are read by tools such as Symfony’s DI container or Doctrine to emit container configuration, proxy classes, or metadata caches as a build step.
  • Scaffolding: frameworks such as Laravel, with artisan make:*, and Symfony, make:entity, make:controller, generate controllers, models, migrations, and test stubs from a single command.
  • Proxy generation: libraries such as ocramius/proxy-manager emit subclass proxies at runtime or ahead of time to implement lazy loading, access interception, or decoration without touching the original class.
  • AST rewriting: nikic/php-parser parses PHP source into an AST, applies transformations via a visitor, and regenerates source, used by Rector for automated refactoring and upgrade migrations.
  • Template-based generation: tools such as twig or custom scripts emit PHP classes, configuration files, or API clients from templates.

Generated code is typically committed to the repository, so that deployment does not require a build step, or kept out of version control and regenerated as part of CI. The choice depends on whether the generated output is considered an artefact or a first-class source file.

Code generation differs from metaprogramming in that it produces static files before runtime; metaprogramming operates on the live program at runtime.

<?php

    // Doctrine: generate entity proxy classes ahead of time (CLI build step)
    // php vendor/bin/doctrine orm:generate-proxies

    // Symfony: scaffold a new entity with make:entity
    // php bin/console make:entity User

    // nikic/php-parser: generate a getter method and write it back to the file
    use PhpParser\BuilderFactory;
    use PhpParser\PrettyPrinter\Standard;

    $factory = new BuilderFactory();
    $method  = $factory->method('getName')
        ->makePublic()
        ->setReturnType('string')
        ->addStmt(new \PhpParser\Node\Stmt\Return_(
            new \PhpParser\Node\Expr\PropertyFetch(
                new \PhpParser\Node\Expr\Variable('this'), 'name'
            )
        ))
        ->getNode();

    $printer = new Standard();
    echo $printer->prettyPrint([$method]);

?>

Documentation

See Also

Code Generator

A code generator is a tool or library that automates the creation of repetitive, boilerplate, or complex code based on predefined templates, configurations, best practices or rules. The goal is to save time, reduce human error, and ensure consistency in the codebase.

PHP code generators are widely used in:

  • Scaffolding, that is generating CRUD controllers, models, and views
  • API development that is generating API endpoints and documentation
  • Database interactions generating ORM classes or PHP code from schema
  • Testing, that is generating test cases
  • Caching, that is replacing complex build up with inlined code
  • Framework-specific code, that is generating Lumen/Laravel migrations or seeders

Code generators are a good choice to speed up creation or update of repeatable code writes. They are not adapted when the code needs to be customized or adapted to a specific circumstance.

Code generators are based on custom templating or facilities that generates arbitrary code using an object-oriented interface.

<?php

    use Laminas\Code\Generator\ClassGenerator;
    use Laminas\Code\Generator\MethodGenerator;
    use Laminas\Code\Generator\FileGenerator;
    
    $class = new ClassGenerator('UserDto');
    $class->addProperty('name', null, ClassGenerator::FLAG_PRIVATE);
    $constructor = new MethodGenerator('__construct', ['string $name'], MethodGenerator::FLAG_PUBLIC);
    $constructor->setBody('$this->name = $name;');
    $class->addMethod($constructor);
    $file = new FileGenerator();
    $file->setClass($class);
    file_put_contents('UserDto.php', $file->generate());

?>

Documentation

See Also

Code Injection

A code injection is a vulnerability, where external data is used as PHP code.

In the example below, $_GET is directly used in the eval() function. By using a clever string, as shown in the illustration below, it is possible to assign the variable, and run the phpinfo() command.

Among the solutions to mitigate this problem: filter adequately the incoming data; use prepared statements.

Some PHP functions are sensitive to this kind of attack: eval(), include(), include_once(), require(), require_once(). Dynamic calls are also susceptible to code injection.

<?php

    // $_GET['userInput'] = '1; phpinfo()';
    eval($myvar = $userInput);
    
    // $_GET['method'] = 'getSafe';
    // Any method may be called on the safe object
    $data->$method();

?>

Documentation

See Also

Code Reuse

Code reuse, as in any programming language, refers to the practice of writing code that can be used in multiple parts of an application or across different projects. This approach offers several benefits, including:

  • Efficiency: instead of writing the same functionality multiple times, the code is written once and used wherever needed
  • Consistency: reusing code promotes consistency across the application and projects, as the same logic is used in multiple places
  • Maintenance: when the code needs to be updated or fixed, there is only one place to do it, reducing the time to spread the fix

Code reuse can be achieved through various techniques, including functions, classes, traits, file inclusions and composer components.

<?php

    // list elements like humans.
    function implodeWithAnd(array $array) : string {
        $last = array_pop($array);
        return implode(', ', $array).' and '.$last;
    }
    
    print implodeWithAnd(['Alice', 'Bob', 'Eve']);
    
    print implodeWithAnd(['Tom', 'Jerry']);

?>

Documentation

See Also

Code Review

Code review is a systematic process where developers examine each other’s code to identify mistakes, improve quality, check local values usage and ensure adherence to best practices.

Code review is especially valuable due to the language’s flexibility, and multiple solutions to the same problem.

There may be several goals of a code review, including:

  • Bug Detection: catch logical errors, or edge cases
  • Security: identify vulnerabilities like SQL injection, XSS, or CSRF
  • Consistency: ensure the code follows team or project standards
  • Performance: optimize slow or inefficient code
  • Knowledge Sharing: help team members understand the codebase.

Documentation

See Also

Code Smell

A code smell refers to any characteristic or symptom in source code that indicates a potential problem or violation of good programming practices. It is a metaphorical term used to describe code that may not be structured optimally or may be prone to bugs, maintainability issues, or other software development problems. Code smells are subjective indicators and do not necessarily indicate a bug or an error in the code, but they highlight areas that may require attention and refactoring.

Long methods, duplicate code are code smells.

Code smells are not strict rules or errors but rather indicators of areas that may need improvement. Recognizing and addressing code smells early in the development process can lead to cleaner, more maintainable, and bug-free code. Automated code analysis tools and code reviews can be helpful in identifying code smells and promoting better coding practices.

Documentation

See Also

Codepoint

A code point is a numerical value that represents a specific character in an encoding system, such as Unicode. Each character, symbol, or control command in a character set is assigned a unique code point, allowing it to be stored and transmitted in digital systems.

In Unicode, code points are written as U+ followed by a hexadecimal number. For example, the character A has the code point U+0041.

<?php

    // The ElePHPant code point
    echo $unicodeChar = "\u{1F418}"; //🐘

?>

Documentation

See Also

Coding Conventions

Coding conventions, also called code style, are a set of guidelines for PHP that recommend source code writing, programming style and practices.

Often, large projects have their own coding convention. When writing for a specific framework or plat-form, it is recommended to use their coding convention to reduce friction.

Documentation

See Also

Type Coercion

Type coercion, a form of weak typing, is the automatic conversion of a value to match a declared type, when it does not already have that type.

It happens with typed function parameters, return types, and typed properties, whenever strict_types is not active. In that mode, PHP accepts a wider range of scalar values, and converts them to the expected type: a string like '42' is coerced to the integer 42 when a parameter expects int, a number is coerced to a string, and so on.

Not every value can be coerced: an array cannot be coerced to an int, and a non-numeric string cannot be coerced to a float. In such cases, PHP still raises a TypeError, even without strict_types.

Coercion only applies to scalar type declarations. Objects, arrays, and callable are never coerced: they must already match the declared type, or a TypeError is raised, regardless of strict_types.

Coercion is a specific case of type juggling, restricted to the boundary of typed declarations, such as parameters, return values and properties.

<?php

    function double(int $trunk): int {
        return $trunk * 2;
    }

    echo double('21'); // 42 : the string is coerced to an int

    echo double('abc');
    // TypeError: double(): Argument #1 ($trunk) must be of type int, string given

?>

Documentation

See Also

Cognitive Complexity

Cognitive complexity is a way of measuring how difficult a piece of code is for a human to understand. Unlike metrics that focus purely on structure or execution paths, cognitive complexity tries to reflect the mental effort required to read, follow, and reason about code.

<?php

if ($a) {
    if ($b) {
        if ($c) {
            // hard to follow
        }
    }
}

if ($a == 1) {}
elseif ($a === 2) {}
elseif ($a === 3) {}
elseif ($a === 4) {}
else {}

?>

Documentation

See Also

Cohesion

Cohesion measures how closely related and focused the responsibilities of a single module, class, or function are. High cohesion means that a unit has a single, well-defined purpose and all its parts work toward that purpose. Low cohesion means it handles many unrelated concerns.

High cohesion is a desirable property: it makes code easier to understand, test, maintain, and reuse. It is the C in the SOLID principle of Single Responsibility, or SRP, and is the counterpart of low coupling.

Robert C. Martin’s common forms of cohesion, from weakest to strongest:

  • Coincidental: parts are grouped arbitrarily, worst case
  • Logical: parts perform similar operations, e.g., a utility class
  • Temporal: parts are executed at the same time
  • Procedural: parts follow a sequence of steps
  • Communicational: parts operate on the same data
  • Sequential: output of one part is input to the next
  • Functional: all parts contribute to a single well-defined task, best case

Architectes aim for high cohesion and low coupling.

<?php

    // Low cohesion: the class does too many unrelated things
    class Utilities {
        public function sendEmail(string $to, string $body): void { /* ... */ }
        public function calculateTax(float $price): float { return $price * 0.2; }
        public function parseDate(string $date): DateTime { return new DateTime($date); }
    }
    
    // High cohesion: each class has one focused responsibility
    class Mailer {
        public function send(string $to, string $body): void { /* ... */ }
    }
    
    class TaxCalculator {
        public function calculate(float $price): float { return $price * 0.2; }
    }

?>

Documentation

See Also

Cold Cache

A cold cache is a cache that holds little or none of the data an application is about to request, so almost every read falls through to the slower source of truth: a database, an external API, a filesystem, or a heavy computation. The opposite state is a hot-cache, where frequently requested data is already sitting in fast storage.

A cache goes cold after a restart, a deployment that recycles processes, a flush or invalidation, or simply because it was never used before, such as right after provisioning a new server. In-process caches, such as a plain PHP array or opcache, are always cold at the start of every request or every worker process, which is why shared caches, such as Redis or APCu, exist: they stay warm across requests.

A cold cache is not just slower, it is dangerous under load: if many requests hit a cold cache at once, they all fall through to the same backend simultaneously, which is the cache-stampede failure mode. This is why production systems favor cache-warming before traffic arrives, rather than letting the cache go cold and warm up under live load.

<?php

function getUser(CacheInterface $cache, int $id): array
{
    // Right after a deploy, the cache is cold: every request below is a miss,
    // so every one of them queries the database directly.
    return $cache->get("user:$id", function () use ($id) {
        return queryDatabaseForUser($id); // slow path, hit on every cold request
    });
}

// Simulating a cold cache right after a restart: no entries yet
$cache = new ArrayCache(); // starts empty: fully cold

foreach ([1, 2, 3] as $id) {
    getUser($cache, $id); // all 3 calls miss and hit the database
}

// After this point, the same 3 users are cached: the cache is now warmer
getUser($cache, 1); // hit: served from the cache, no database call

?>

Documentation

See Also

Cold Start

A cold start, also known as the cold start problem or cold start latency, is the delay incurred when a serverless function or containerised service must be initialised from scratch before handling a request. The runtime environment, aka the container, the PHP process, the class autoloading, is not yet warm, so the first invocation takes significantly longer than subsequent ones.

In a FaaS environment, aka AWS Lambda, Google Cloud Functions, etc., a cold start involves: provisioning a container, downloading the function package, initialising the PHP runtime, and executing any bootstrap code, framework boot, DI container compilation, autoloader initialisation. For PHP, cold starts commonly range from a few hundred milliseconds to over a second depending on framework size.

Subsequent invocations reuse the warm container and execute in milliseconds. Containers are typically kept warm for a few minutes of inactivity before being torn down.

Mitigation strategies include: provisioned concurrency by pre-warming a fixed number of instances, reducing the deployment package size and bootstrap time, using slim frameworks or no framework for latency-sensitive functions, and keeping functions warm via scheduled pings.

<?php

    // Bref, PHP on Lambda, minimise cold start by avoiding heavy bootstrap
    // Bad: full Symfony kernel boot on every cold start
    $kernel = new Kernel('prod', false);
    $kernel->boot(); // loads 300+ classes, compiles DI container
    
    // Better for Lambda: pre-compiled container, minimal bootstrap
    // Or use a micro-runtime that skips the framework entirely
    return function (array $event): array {
        // Lightweight handler: only what this function needs
        $name = $event['queryStringParameters']['name'] ?? 'world';
        return [
            'statusCode' => 200,
            'body'       => json_encode(['message' => 'Hello, ' . $name . '!']),
        ];
    };
    
    // Provisioned concurrency (configured in AWS, not in PHP):
    // keeps N containers permanently warm, eliminating cold starts for baseline traffic

?>

Documentation

See Also

Collation

Collation is the set of rules that define how strings are compared and sorted, and it is far less obvious than it sounds because different languages order the same characters differently. A naive comparison, such as PHP’s strcmp or a plain sort(), compares strings byte by byte according to the underlying encoding, which places accented letters, ligatures, and non-Latin scripts in positions that look wrong to a human reader; for example, byte order alone may sort ‘pêche’ after ‘z’ instead of next to ‘pomme’ as a French speaker would expect. Proper, locale-aware sorting instead follows the Unicode Collation Algorithm, aka UCA, which PHP exposes through the Collator class in the intl extension: constructing a Collator for a given locale and calling its sort() or compare() methods orders strings the way a native reader of that language expects, correctly handling accents, case, and script-specific ordering rules. The same underlying idea also appears outside PHP itself, notably as the COLLATE clause in databases like MySQL and PostgreSQL, which determines how that database engine compares and indexes text columns.

<?php

    $words = ['pomme', 'poire', 'pêche', 'prune'];
    
    $collator = new Collator('fr_FR');
    $collator->sort($words);
    
    print_r($words);
    // pêche, poire, pomme, prune

?>

Documentation

See Also

Collection

A collection is an array in which only elements of the same type can be stored.

Collections may be build with array, or dedicated classes. There is native no support for native PHP collections, although there are several packages which provide such features.

Documentation

See Also

Collision

A collision, or name collision, happens when two entities of the same type have two distinct definitions. This usually leads to a PHP Fatal error, as the engine can’t tell the difference between the two structures.

Note that structures of different types may have the same name, although it might lead to ambiguities.

Structures with the same name, and defined in different namespaces are possible. The naming collision may happen at import time, a.k.a. with a use expression, and may be solved with an alias.

Some structures resolve collisions by simply overwriting the previous one: this is the case for variables.

<?php

    function trumpet() {}

    // name collision: no two functions can have the same name
    // name collision: function names are case insensitive, so trumpet === TRUMPET
    // function TRUMPET() {}

    // TRUMPET as a constant and TRUMPET as a function are distinct elements.
    const TRUMPET = 1;

    // variable collisions are silent : the variable's value is simply changed
    $trunk = 1;
    foreach($herd as $trunk) {
        print $trunk; // may print a different value than 1
    }

?>

Documentation

See Also

Colon

Colons are used in a variety of situations:

  • With named parameters, to separate the name from the value
  • With labels, for goto
  • With ternary operator, separated or not from the question mark
  • In include_path and open_basedir, double-colon is used as a separator

The double colon is a distinct operator.

<?php

    goto there;
    there:

    foo(a: 3); // 

    $b = $a ? 'a' : 'b';
    $c = $c ?: 'a';

?>

Documentation

See Also

Column Database

A column database, or column-oriented database, columnar database, or column-store, stores data by column rather than by row. In a traditional row-oriented database, all the fields of a record are stored together. In a columnar database, each column’s values are stored contiguously.

This layout is particularly efficient for analytical queries that read only a few columns across a large number of rows, OLAP workloads, because:

  • Only the columns needed for a query need to be read from disk
  • Columnar storage compresses well, since similar values are adjacent
  • Aggregate functions, such as SUM, AVG, COUNT, etc. operate on contiguous memory

Popular columnar databases used with PHP include ClickHouse, Apache Parquet and its file format, Amazon Redshift, and Google BigQuery.

Row-oriented databases, such as MariaDB, MySQL, PostgreSQL, remain better for OLTP workloads that access full records.

<?php

    // Example: querying ClickHouse (columnar DB) via HTTP
    $ch = curl_init('http://localhost:8123/?query=SELECT+sum(price)+FROM+orders+FORMAT+JSON');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $result = curl_exec($ch);
    curl_close($ch);
    
    $data = json_decode($result, true);
    echo $data['data'][0]['sum(price)'];

?>

Documentation

See Also

Comma

Commas are syntax elements, to separate elements when provided as a list. There are several situations where a list of elements may be provided:

  • Argument separator, including with echo
  • Parameter separator
  • Trait name separator, in use expression when importing a trait in a class
  • Array element separator
  • List separator, where unused values may be omitted, leaving commas back to back

Comma are important in the CSV and JSON formats, and other such formats.

Comma do not have a value by themselves.

<?php

    function trumpet($trunk, $tusk) {
        return [$trunk, 2, $tusk];
    }

    list($herd, ,$ivory) = trumpet(1, 2);

    [$herd, ,$ivory] = trumpet(1, 2);
    
    echo 'a', 'b', 'c';

?>

Documentation

See Also

Command Bus

A command bus is a design pattern used in software development, particularly in the context of Domain-Driven Design, DDD, and CQRS, Command Query Responsibility Segregation. It helps to decouple the sender of a command from its handler, allowing for better separation of concerns and improving the overall architecture of the application.

A command bus works together with commands and command handlers.

Here’s a simplified overview of how a command bus works:

  • The sender, e.g., a controller in a web application, creates a command object and sends it to the command bus
  • The command bus examines the command object and identifies the appropriate command handler based on the type of the command
  • The command bus dispatches the command to the identified command handler
  • The command handler processes the command and performs the required actions.

Documentation

See Also

Command

The Command design pattern encapsulates a request as an object, allowing it to be stored, queued, logged, or undone. A command object contains all the information needed to execute an action: the receiver, the method to call, and any parameters.

The Command pattern separates the object that invokes an operation from the object that knows how to perform it. It is widely used in:

  • CLI applications: each CLI command is an object with an execute() method.
  • CQRS architectures: write operations are represented as command objects dispatched through a command bus.
  • Undo/redo systems: commands store enough state to reverse their effect.
  • Task queues: serialized command objects are placed on a queue and processed asynchronously.

Symfony Console and Laravel Artisan both build on this pattern for their CLI command systems.

<?php

    interface Command {
        public function execute(): void;
    }
    
    class CreateUserCommand implements Command {
        public function __construct(
            private string $email,
            private string $password,
        ) {}
    
        public function execute(): void {
            // Create user logic
            echo "Creating user: {$this->email}" . PHP_EOL;
        }
    }
    
    class CommandBus {
        public function dispatch(Command $command): void {
            $command->execute();
        }
    }
    
    $bus = new CommandBus();
    $bus->dispatch(new CreateUserCommand('user@example.com', 'secret'));

?>

Documentation

See Also

Comments

PHP comments are used to add explanatory notes or annotations within the code. Comments are not executed by the PHP interpreter; they are purely for documentation purposes, and they help the readers understand the code better. PHP supports two main types of comments:

Single-line comments: these are comments that span only one line. They are typically used for brief explanations or annotations within the code. Single-line comments can be created using either double slashes // or a hash symbol #.

Multi-line comments: these are comments that can span multiple lines, allowing for more extensive explanations or commenting out large sections of code. Multi-line comments are enclosed within /* and */.

It’s important to note that comments do not affect the execution of the PHP code; they are ignored by the PHP interpreter: in fact, they are omitted at parsing time, before execution. Comments are primarily for developers and maintainers of the code to understand its purpose, logic, or any special considerations. Well-documented code with meaningful comments can make it easier to read, understand, and maintain applications.

Comments may be formalized with a specific syntax, and create automated instruction for other application. For example, phpdoc comments are providing extra information with a specific syntax.

As a side feature, comments may also be started with the Unicode #️⃣️ character.

<?php

// This is a single-line comment
$variable = 42; // Assign a value to $variable
# Another single-line comment

    /*
    This is a multi-line comment.
    It can span multiple lines and is often used for
    longer explanations or for commenting out sections of code.
    */

    $variable = 43; 
    
    #️⃣️ One line comment

?>

Documentation

See Also

Commit

A commit is a validation of changes.

  • Commit in VCS: when the source code has been modified and may be changed in the main code base as an atomic diff
  • Commit in Database: when data have been checked and changed in the database, and the change may be stored and propagated to all other operations.

Documentation

Community

The PHP community is the global network of developers, contributors, and enthusiasts who use, improve, and promote PHP.

The community is known for its collaboration, innovation, and inclusivity, making PHP one of the most widely used languages for web development.

The community is recognizable via its various artefact, which go beyond the computer circles: logos, T-shirt, plush toys, legends, events, news stories, recurrent themes, think tanks, speakers, side projects, etc.

Documentation

See Also

Compact Array

An array is compact, or a packed array, if it only uses automated indices, starting with 0. This doesn’t really show in the written code, though performances are better for some operations.

Such array’s status may be reached by using array_values() or array_keys() on the array: such functions reindexes the values in the array.

This notion is not related to the compact() function.

<?php

    $array = [1,2,3];

    $notCompact = [1,2,3, 4=>4];

    $compactAgain = array_values($notCompact);

?>

Documentation

See Also

compact()

compact() is a native PHP function, which creates an array containing variables and their values, from a list of variable names.

It is the opposite of extract().

<?php

    $a = '1';
    $b = '2';
    
    $array = compact('a', 'b');
    // ['a' => 1, 'b' => 2];

?>

Documentation

See Also

Comparison

Comparison operators check how two values relate to each other. They may be equal or different, and, depending on the type of compared data, they may be greater or lesser than the other one.

PHP comparisons exists with type-juggling, ==, <>, <=>, switch() and !=, and with type checks, match(), === and !==. They are called loose comparison, as PHP applies some cast before executing the comparison. Inequalities only exist with type-juggling.

On the other hand, PHP has strict comparisons, which include comparing the type before running any further checks. They are === and !==.

There are also functions dedicated to comparisons, with specific applications: strcmp(), strcasecmp(), strnatcasecmp(), strcoll(), similar_text(), levensthein(), bccomp(), version_compare(), hash_equals().

Some of the functions include a loose or a strict version.

<?php

    if ($a == $b) {
        print 'a and b are equal';
    }

?>

Documentation

See Also

Compatibility

Compatibility refers to the ability of two or more things to work together without conflicts or issues.

Compatibility may refer to:

  • Version compatibility, when code works in both versions
  • System compatibility, when code works on different operating systems
  • Method compatibility, when methods are compatible in the parent and the child class.
<?php

    class Elephpant {
        function trumpet(int $trunk) {}
    }

    class AfricanElephpant extends Elephpant {
        // The type must be compatible with the one of the parent
        // The name does not have to be the same as in the parent
        function trumpet(int|null $tusk) {}
    }

?>

Documentation

See Also

Compensation Logic

Compensation logic, also called a compensating transaction or saga compensation, refers to the set of actions taken to undo or neutralise the effects of a previously completed step when a subsequent step in a distributed process fails. It is the rollback mechanism for operations that cannot be part of a single ACID transaction.

The concept originates in the Saga pattern: a long-running business process is split into a sequence of local transactions. If transaction N fails, compensation transactions are executed in reverse order, N-1, N-2, … to restore the system to a consistent state. Compensation is not always a perfect undo, a sent email cannot be unsent, a payment refunded is not the same as a payment never made.

Because compensation logic is domain-specific, it must be designed and tested explicitly. The failure modes of compensation steps themselves must also be handled.

Compensation logic is typically implemented as event handlers or command handlers that react to failure events published by downstream services.

<?php

    // Compensation handler: listens for PaymentFailed and cancels the order
    class CancelOrderOnPaymentFailed {
        public function __construct(
            private OrderRepository  $orders,
            private EventBus         $bus,
        ) {}
    
        public function handle(PaymentFailed $event): void {
            $order = $this->orders->findById($event->orderId);
    
            if ($order === null || $order->isCancelled()) {
                return; // idempotent: safe to call multiple times
            }
    
            $order->cancel(reason: 'payment_failed');
            $this->orders->save($order);
            $this->bus->publish(new OrderCancelled($order->id));
        }
    }

?>

Documentation

See Also

Compile-time Evaluation

Compile-time evaluation is the ability of a compiler to execute expressions or functions during compilation, embedding the computed result directly in the compiled output rather than deferring it to runtime. C++ constexpr in C++11+ allows functions and variables to be evaluated at compile time when their inputs are compile-time constants. Zig’s comptime keyword forces evaluation at compile time. Rust evaluates const fn calls in constant contexts. D calls the equivalent feature CTFE: Compile-Time Function Evaluation. In all cases, the intent is to move computation earlier, eliminating runtime overhead and enabling richer static guarantees.

PHP is an interpreted language. PHP source code is compiled to opcodes on every request, or cached by opcache, but there is no ahead-of-time compilation phase that evaluates user-defined functions. PHP does perform limited compile-time optimisations:

  • Constant folding: simple arithmetic and string concatenation on literal values, like 60 * 60, 'foo' . 'bar' is folded to a single value by the parser/optimiser before the opcode is emitted.
  • const declarations: scalar constant values are resolved at compile time. Constant expressions composed of other constants A * B are also folded.
  • Opcache: caches the compiled opcode representation, avoiding repeated parsing, but does not evaluate user functions at cache time.
  • JIT, PHP 8.0+: the Just-In-Time compiler can optimise hot paths at runtime, but this is runtime specialisation, not compile-time evaluation.

No PHP mechanism allows a user-defined function to be annotated as evaluable at compile time, and no result of such evaluation can be used as a class constant, a default parameter value, or an attribute argument.

<?php

    // PHP folds constant arithmetic expressions at compile time (parser level).
    const SECONDS_PER_MINUTE = 60;
    const SECONDS_PER_HOUR   = SECONDS_PER_MINUTE * 60;   // folded to 3600
    const SECONDS_PER_DAY    = SECONDS_PER_HOUR   * 24;   // folded to 86400

    // Enum backed values are constant expressions: also folded.
    enum Permission: int {
        case Read    = 1 << 0;   // 1
        case Write   = 1 << 1;   // 2
        case Execute = 1 << 2;   // 4
    }

    // The following is NOT possible in PHP: functions cannot be constexpr:
    //
    //   constexpr function factorial(int $n): int {
    //       return $n <= 1 ? 1 : $n * factorial($n - 1);
    //   }
    //   const FACT_10 = factorial(10); // evaluated at compile time
    //
    // In PHP, factorial(10) is always evaluated at runtime.
    function factorial(int $n): int {
        return $n <= 1 ? 1 : $n * factorial($n - 1);
    }

    echo factorial(10); // computed at runtime every call

?>

Documentation

See Also

Compile Time

Compile time, also called lint time or linting time, is a phase of PHP processing, where the source code is transformed into execution commands.

At that time, PHP figures out the syntax and code organisation, and also validates some aspects of the code, depending on the information availability. The information availability may depend on execution: for example, PHP validates interfaces when they are in the same file as the implementing class, but not when they are in different files, as autoloading needs to happen.

In particular, during compile time, PHP has only visibility on the current constant definitions: no inclusion, no define(). It has no result from any function call, or variables.

Compile time is related to execution time and late static binding. Attributes, default values, constants, with const, are fully compile time structures.

<?php

    const S = 'abc'; 
    
    class y {
        const T = 'abc';
        const string U = z::A ? '2' : 'abc'; // PHP waits for z 
    }
    
    class x {
       private int $a = S;     // execution time 
       //private int $b = y::T;  // compile time error
       private int $c = y::U;  // execution time error
    }
    
?>

Documentation

See Also

Compile

To compile, compiling, or compilation, is the process to turn the source code into machine code for direct execution, producing compiled code.

Generally speaking, PHP is interpreted, so its code is directly run by the PHP engine. It is initially linted, for syntax correctness, then converted into opcodes, which are run by the engine.

Some tools convert PHP directly to a binary, such as KPHP.

There are tools to convert PHP into a binary file, such as static-php-cli or roadrunner. These solutions merge the PHP engine with the target code.

Other tools transpile PHP code to another language, such as Rust or .NET, and then, compile it to a binary file. These are not common approaches.

Documentation

See Also

Compiler

A compiler is a program that performs compilation: it translates source code into another form, typically machine code or bytecode.

The term compiler can refer to:

  • The PHP compiler that translates PHP source code into opcodes
  • Tools like KPHP or static-php-cli that compile PHP to binary
  • The halt-compiler construct that signals end of PHP code in a file
  • The PHP-Parser library which provides a compiler-like AST transformation.

Documentation

See Also

Complexity

Complexity refers to how difficult the code is to understand, maintain, test, and modify. It may be objectively measured, but also subjectively estimated.

Complexity is measured with cyclomatic complexity, cognitive complexity, algorithmic complexity.

Complexity increases when:

  • Code takes many decisions in one context
  • Logic is deeply nested
  • Responsibilities are mixed and matched
  • Behavior is not obvious, and includes magic
  • Code is not readable
  • Naming is confusing

Non-complex code tends to:

  • Have small functions
  • Clear naming
  • Limited branching
  • Avoid exploding combinations as much as possible

Code complexity applies to all programming languages, and is not specific to PHP.

Documentation

See Also

Compliance

Compliance generally refers to adhering to a set of predefined rules, standards, or regulations. These can range from coding style guides and interoperability standards to legal requirements, like GDPR, or security mandates, like OWASP. They may also be standards set up in house, or tacitly accepted without being written.

Documentation

See Also

Component

A component is a part or element that combines with others to form a larger system, structure, or product. Components are code libraries, or groups of classes that work together.

Documentation

See Also

Composer

Composer is the most popular package manager for PHP.

Composer install and update packages, which are stored on the packagist website.

Composer is the work of Jordi Boggiano and Nils Adermann.

Documentation

See Also

composer.json

composer.json is the manifest file that Composer reads to manage a PHP project’s dependencies. It lives at the root of the project and declares, among other things, the runtime dependencies under require, the development-only dependencies under require-dev, the autoload mapping used to generate the class autoloader, and any custom scripts that can be run with composer run.

Version constraints in require follow semantic versioning ranges, such as ^2.0 or ~1.4, rather than pinning an exact version; the exact versions actually installed are recorded separately, in composer.lock.

composer.json is meant to be hand-edited, or edited through commands like composer require, and is committed to version control. It is distinct from composer.lock, which Composer generates and should not be edited by hand.

{
    "name": "acme/example",
    "require": {
        "php": ">=8.1",
        "monolog/monolog": "^3.0" 
    },
    "require-dev": {
        "phpunit/phpunit": "^10.0" 
    },
    "autoload": {
        "psr-4": {
            "Acme\\Example\\": "src/" 
        }
    }
}

Documentation

See Also

composer.lock

composer.lock is the file Composer generates after resolving the version constraints declared in composer.json. It records the exact package versions, and their exact commit or distribution hash, that were actually installed, so that running composer install on another machine, or in CI, or in production, reproduces the exact same dependency tree, rather than re-resolving constraints and possibly picking up newer releases.

composer.lock is generated by Composer and should not be edited by hand. It is updated automatically whenever composer update is run, or whenever composer require/composer remove changes composer.json.

For applications, composer.lock is generally committed to version control, so every environment installs identical versions. For libraries, whose consumers resolve their own dependency tree, it is common to leave it out of version control instead.

Documentation

See Also

Composite Type

Composite types combine multiple types into a single type expression. PHP supports three forms of composite types:

  • Union types A|B: the value must satisfy at least one of the listed types. Introduced in version 8.0, with catch clauses supporting multi-type syntax since PHP 7.1.
  • Intersection types A&B: the value must satisfy all of the listed types simultaneously. Restricted to class and interface names. Introduced in version 8.1.
  • DNF types (A&B)|C: disjunctive normal form, which combines intersections and unions. Introduced in version 8.2.

Composite types are accepted in parameter types, property types, and return types. catch clauses accept union types only. instanceof does not accept any composite form.

<?php

    // Union type
    function trumpet(int|string $id): void {}

    // Intersection type
    function forage(Countable&Iterator $col): void {}

    // DNF type
    function migrate((Countable&Iterator)|null $col): void {}

?>

Documentation

See Also

Composition

Composition is the creation of new classes, by including other classes, and delivering a specific interface over them. It expresses a has-a relationship, as opposed to inheritance’s is-a relationship: a class holds references to other objects as properties, and delegates part of its behavior to them, rather than inheriting it from a parent class. This favors loose coupling, since the composing class can expose only the methods it chooses, while the composed objects can be swapped, reused, or tested independently. Favor composition over inheritance is a well-known object-oriented design guideline, because it avoids the rigid, fragile class hierarchies that deep inheritance chains tend to produce.

<?php

class Wheel {
    public int $diameter;
}

class GasTank {
    public int $capacity;

    public function fillUp(int $amount) {
        $this->amount = $amount;
    }

    public function empty() {
        $this->amount = 0;
    }

}

// Car composes 2 other classes: GasTank and Wheel
// These object should be accessed via the Car class, not the direct objects
class Car {
    public Wheel $wheels;
    public GasTank $gasTank;
    
    public function fillUp(int $amount) {
        $this->gasTank->fillUp($amount);
    }

    // empty() the gasTank is now available via the car (just drive it, or and it to garage)
}

?>

Documentation

See Also

Compression

Compression is the representation of data in a format that uses less space that the original raw data.

A compression algorithm must provide a way to compress data, and a way to uncompress it, and give access to the original data.

There are lossless compression, which can provide the exact original data, for text, and lossy compression which degrades the original data for images, video.

PHP supports compression via zip, rar, zlib, bzip2, brotli, etc.

Documentation

See Also

Computed Property

A computed property is a property whose value is derived from an expression at the point of access, with no explicit getter method in user code. The computation is declared inline with the property itself, and the language runtime invokes it transparently when the property is read.

Languages such as Swift, Kotlin, and C# offer computed properties as a first-class syntax:

  • In Swift, var area: Double { width * height } defines a read-only computed property.
  • In C#, public int Area => Width * Height; uses an expression-bodied property.
  • In Kotlin, val area get() = width * height attaches a getter expression directly to the declaration.

In all these cases the computation is expressed as part of the property declaration, not as a separate method the programmer must name and call.

PHP does not support computed properties natively. PHP 8.4 introduced property hooks, with get and set, which come close: they attach getter and setter logic to a property declaration. However, property hooks still require explicit block or arrow syntax inside the property body and are closer to accessor methods than to the lightweight expr-body computed properties found in Swift or Kotlin.

Before PHP 8.4, the only option was a dedicated getter method, e.g. getArea(), which is a named method, not a property.

<?php

    // PHP 8.4 property hook: closest available approximation.
    class Rectangle {
        public function __construct(
            public float $width,
            public float $height,
        ) {}
    
        // get hook — behaves like a computed property, but requires
        // explicit hook syntax rather than a bare expression.
        public float $area {
            get => $this->width * $this->height;
        }
    }
    
    $r = new Rectangle(3.0, 4.0);
    echo $r->area; // 12.0
    
    // Before PHP 8.4, a dedicated method was the only option:
    // public function getArea(): float { return $this->width * $this->height; }

?>

Documentation

See Also

Concatenation .

Concatenation is the PHP feature that appends two strings together, to make a third, longer one.

Concatenation is also achieved with interpolation, inside a string; by calling echo, multiple times or with multiple arguments; by using the join() function.

Concatenation is done with the dot operator ..

<?php

    $a = "world";
    $b = "Hello ";
    echo $b . $a; 
    // displays Hello world

?>

Documentation

See Also

Concatenative

A concatenative structure is a structure that is valid after placing values one after the other.

For example, strings are concatenative, using the . dot operator. On the other hand, JSON is not concatenative, as two JSON strings placed one after the other does not create a valid JSON.

There are concatenative programming languages, and natural languages.

<?php

    $fullName = 'John' . ' ' . 'Doe';

?>

Documentation

See Also

Concrete Method

A concrete method is a method that has code. It is usually the opposite of an abstract method.

A concrete method may be part of an abstract class or not. It may also be overwritten, in a child class, though it is not compulsory, no always the case.

Interfaces cannot have concrete methods.

<?php

abstract class AbstractClass {
    abstract function trumpet(); // abstract method

    function forage() {
        return 1;
    } // concrete method
}

class ConcreteClass extends AbstractClass{

    function trumpet() {
        return 2;
    } // concrete method

    // No need to redefine the concrete methods.
    // Yet, it is still possible
}

?>

Documentation

See Also

Concrete Class

The contrary to abstract is concrete. PHP has abstract classes and methods. This is the default state of a method or class, when it has a code block with implementation. It also has no specific keyword to designate it.

<?php

    abstract class AbstractClass
    {
        // Concrete method
        public function printOut() {
            print $this->getValue() . "\n";
        }
    
        // Method without an implementation
        abstract protected function getValue();
    }

?>

Documentation

See Also

Concurrency

Concurrency, sometimes misspelled concurency, is a concept in computing where multiple tasks are in progress at the same time.

PHP uses several ways to handle concurrency:

  • Externally, by the webserver or PHP-fpm
  • Internally, with forked processes, with pcntl
  • Internally, with threads, with parallel
  • Cooperating, with fibers
  • Non-blocking IO, with swoole or amphp.

Documentation

See Also

Condition

Conditions are an expression that are either true or false.

They are used in conditional statement, to determine which code to process next.

There are conditions in conditional statements, such as if(), switch() and match(). There are conditions in loops, to determine if the loop shall continue or not: in for(), do-while() and while().

Conditions are expressed with comparisons operators. They are also expressed with raw data, which are converted to boolean, thanks to type-juggling.

Documentation

See Also

Conditional Structures

Conditional structures are instructions which run different code, based on a condition.

This includes if-elseif-then, switch(), match(), the ternary operators ? ... : and ?: and the coalesce operator ??.

<?php

    if (!function_exists('trumpet')) {
        function trumpet() {
            // doSomething
        }
    }

?>

Documentation

See Also

Conditional

Conditional means that some condition must be met for something to happen or to be. While conditions are used everywhere in code, some syntax are seen as fixed, but may be conditioned too.

  • Constant value: constant definitions, both global and class, may use the ternary operator and have a value depending on the context of execution.
  • Definition: old technique used to include definitions of classes, functions, etc. depending on versions. This is now replaced by holding all definitions in different namespaces: the namespace are conditionally used.
  • Constant definition: when specifying a global constant with const, the definition cannot be conditional: it cannot be set in a if-then block, or any other block, including functions or closures.
<?php

    // Conditioned constant value
    const A = PHP_OS == 'Linux' ? 'PHP On Linux' : 'PHP Not On Linux';
    
    if (PHP_OS == 'Linux') {
        // This is a syntax error
        const B = 1; 
    }

?>

Documentation

See Also

Conditioned Structures

Conditioned structures are definitions that are placed inside a condition structure.

For example, it is possible to create a function or a class, only if it doesn’t exist.

Classes, traits, interfaces, global constants, with define(), enumerations, functions may be conditioned.

Class constants, properties, methods and cases, for enum, cannot be conditioned.

Conditioned structures adapt the PHP context to external condition. For example, some function may become native after a specific PHP version, and is only redefined for older installation.

Some structures do not accept condition, such as global constants with const keyword. With define() function, it is OK.

<?php

    if (!function_exists('trumpet')) {
        function trumpet() {
            // doSomething
        }
    }

?>

Documentation

See Also

Configuration

Configuration is a set of data that conditions the execution of the program.

Generally, configuration isn’t changed during the execution of the program.

PHP has three locations for configuration: php.ini, .htaccess and usage of the ini_set() functions.

Each item of configuration is called a directive.

Documentation

See Also

Connection Pool

A connection pool, or connection pooling, is a set of pre-established, reusable connections, most often to a database or another network service, that are handed out to callers on demand and returned to the pool instead of being closed after use. Pooling avoids paying the cost of establishing a new TCP connection, and possibly a new TLS and authentication handshake, on every single request, and it caps how many connections to a given dependency may be open at once.

That cap is itself a resilience mechanism: it acts as a bulkhead, preventing a burst of traffic, or a slow dependency, from opening unbounded numbers of connections and exhausting the dependency’s own connection limit, file descriptors, or memory. When the pool is exhausted, callers either wait, up to a configured timeout, or fail fast, depending on how the pool is configured.

Traditional PHP, being a share-nothing, one-request-per-process model, cannot keep a connection pool alive in application memory across requests the way a long-running process in another language would: each PHP-FPM worker opens its own connections, and true pooling across workers requires an external pooler such as PgBouncer for PostgreSQL, ProxySQL for MySQL, or a persistent connection, PDO::ATTR_PERSISTENT, kept open by the underlying process across requests within the same worker. Long-running PHP processes, such as Swoole, RoadRunner, or a queue worker, can maintain an in-memory pool for their entire lifetime, closer to how connection pools work in other languages.

<?php

    // Persistent PDO connection, reused across requests handled by the same worker
    $pdo = new PDO($dsn, $user, $password, [
        PDO::ATTR_PERSISTENT => true,
    ]);

?>

Documentation

See Also

Connection

Connection, or connexion in French, refers to the communication link established between a running instance of PHP and a remote server.

The connection may be established with different kind of servers: web, SQL, NoSQL, FTP, etc.

The connection may be protected by a login and password, or other identification and authentication methods.

Once the connection is established, PHP sends queries to the remote server, and receives results set.

The remote server may be on the same physical machine as PHP: it is considered remote as it acts autonomously.

Documentation

See Also

Connexion Persistence

Connexion persistence refers to the practice of reusing the same database connection across multiple requests, rather than opening and closing a connection for each individual request. This is typically achieved using persistent connections, also called a persistent connexion.

Documentation

See Also

Consistency

Consistency means writing code that follows predictable patterns, standards, and conventions across a project or team. The reference may be public, and available throughout the community, or local, and specific to a project or a team.

Consistency ensures that:

  • Code behaves the same way in similar situations
  • Style and structure are uniform, making it easier to read and maintain
  • Team members can collaborate without confusion.

Documentation

See Also

Const

const is a PHP keyword, that creates constant definitions.

const is allowed inside classes, interfaces, enumerations and traits, to create static constants. const is also allowed in the global scope, to create global constants.

const is only allowed in the body of a classes, interfaces, enumerations and traits, and the first level of a main file. It is not possible to create conditioned constants with a if-then structure and const: this requires an include.

<?php if ($a == 5): ?>
A is equal to 5
<?php endif; ?>

Documentation

See Also

Constant Case

Constant case, also written CONSTANT_CASE, is a way of writing constant names, without spaces. The rules are:

  • All the letters are set to upper case
  • Each word is separated from the other by an underscore

Constant case is used for constants, both global and class. It is not used for magic constants, which are case insensitive.

<?php

    const CONSTANT_CASE = 1;
    
    class Elephpant {
        const CLASS_CONSTANT_CASE = 1;

        function trumpet() {
            echo __METHOD__;
            echo __method__; // same as above
        }
    }

?>

Documentation

See Also

Constant Combination

PHP combines predefined constants using bitwise operators. This is heavily used with error level constants, file permissions, and various flags.

Combine two constants into one, with the | or operator: E_NOTICE | E_WARNING. This might also be achieved with + operator.

Check if a flag is set, with the & and operator: E_ALL | E_WARNING.

Exclude one flag, with the ~ tilde operator: E_ALL & ~E_WARNING.

Toggle flags, with the ^xor operator: E_ALL ^ E_WARNING.

These combinations are possible when the constants are distinct powers of 2. That way, combining E_WARNING = 2 // 0010 and E_NOTICE = 8 // 1000 gives E_WARNING | E_NOTICE = 10 // 1010 (both bits set).

Constant combination is used with such functions as error_reporting(), phpcredits(), htmlentities(), sort() though not with all constants, etc.

<?php

    // Combine multiple error levels
    error_reporting(E_NOTICE | E_WARNING | E_ERROR);
    
    // More common: start from ALL and exclude some
    error_reporting(E_ALL & ~E_DEPRECATED & ~E_NOTICE);
    
    // -1 represents a flag with ALL activated 
    error_reporting(-1); 

?>

Documentation

See Also

Constant Expression

A constant expression is an expression built with others constants and a limited subset of PHP operators. They can be used as a value for constants of default values.

<?php

    const A = 1;
    const B = A + 1;

?>

Documentation

See Also

constant()

The constant() function is a native function, which provide the value of a declared global constant, a class constant or an enumeration case.

For class constant and enumeration cases, it may be replaced with the dynamic class constant syntax, introduced in version 8.3.

<?php

    const A = 1;
    
    echo constant('A');
    
    enum E: string {
        case B = 'abc';
        const C = 'def';
    }
    
    echo constant('E::B')->value; // abc
    echo constant('E::C');        // def

?>

Documentation

See Also

Constants In Trait

Constants were added to trait in version 8.3. Before that, they were not allowed.

After PHP 8.3, they are added to the host class, with less precedence than the host own constants, but higher precedence than the host parent’s constants.

It is not possible to call a trait constant directly via its trait’s name: this has to be done via the host class.

<?php

    trait Trunk {
        private const HABITAT = 1;
    }

    class Elephpant {
        use Trunk;
    }

    echo HABITAT::Trunk;

?>

Documentation

See Also

Constant Scalar Expression

A constant scalar expression is an expression that can be evaluated at compile time and consists only of scalar values, constants, and some operators operators.

Constant scalar expressions are used to initialize constants, and default values for parameters and properties.

<?php

    const A = 1;
    const B = A + 10;

?>

Documentation

See Also

Constants

Constants are named values, that never change.

Constants may be created with the const keyword or the define() function. They may be tested for existence with the defined() function.

There are global constants, which are accessible with their name and their namespaces. There are also constants in classes, interfaces, enums and traits. Those are called class constant.

Constants are namespace dependent. They can be imported using the use const command.

Constants are usually written in uppercase.

Global constants used to be case insensitive, when created with define(). This feature was removed in version 8.0. Nowadays, both const and define create case insensitive values.

<?php

const A = 1;
define('B', 2);

// displays 1
echo A;

?>

Documentation

See Also

Constraint

A constraint is a syntactic or semantic restriction on how a language construct may be used. Constraints are the rules a program must satisfy beyond mere grammatical correctness: for example, a break statement is only valid inside a loop or switch, and a class marked final cannot be extended.

Violating a constraint typically produces a compile-time error, though some constraints are only checked at run time. Code that violates a constraint the engine does not check at all is a common source of undefined behavior.

<?php

    final class Sealed {}

    // violates a constraint: a final class cannot be extended
    class Broken extends Sealed {}

?>

Documentation

See Also

Constructor

The constructor is a magic method in a class, which is called at instantiation of an object, with the provided arguments. It is called __construct.

The constructor is an optional method: a class may be created without it. Though, it is very common to have it.

Parent’s constructor are not automatically called, when a child class defines a constructor. They have to be called explicitly.

When a class has a parent, with a constructor, and not constructor itself, then the parent constructor is automatically called, by inheritance.

A constructor may have a visibility, and be not available to the outside. In particular, when creating named constructors, the magic method __construct is usually made private and object instantiation happens in a static method of that same class.

<?php

    class Elephpant {
        private $trunkLength;

        function __construct($value) {
            $this->trunkLength = $value;
        }
    }

    $elephpant = new Elephpant(1);

?>

Documentation

See Also

Container Orchestration

Container orchestration is the automated management of the full lifecycle of containerised workloads across a cluster of machines: scheduling containers onto nodes, scaling replicas up or down, restarting failed containers, routing network traffic, managing rolling updates and rollbacks, and injecting configuration and secrets.

Without orchestration, deploying many containers manually is error-prone and does not scale. Orchestration platforms solve the operational burden of running containers in production.

Kubernetes is the dominant container orchestration platform. Docker Swarm is a simpler alternative built into Docker Engine. Managed cloud offerings, the like of AWS ECS, AWS EKS, Google GKE, Azure AKS, etc. run Kubernetes with reduced operational overhead.

PHP applications benefit from container orchestration through: horizontal scaling, like adding replicas under load, zero-downtime rolling deploys, like old pods kept alive until new pods are healthy, and self-healing, like crashed PHP-FPM pods are automatically restarted.

# Scale a PHP deployment to 10 replicas
# kubectl scale deployment order-service --replicas=10

# Roll out a new image with zero downtime
# kubectl set image deployment/order-service php-fpm=myregistry/order-service:v2

# Horizontal Pod Autoscaler: scale based on CPU usage
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: order-service-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: order-service
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70

Documentation

See Also

Container

There are several usages of the word container:

  • Docker container, for PHP or other related technologies
  • Dependency injection container
  • Any structure that stores data: variables, properties, array elements.

Documentation

See Also

Continuation

A continuation represents the rest of a program’s computation at a given point, reified as a callable value. Scheme’s call-with-current-continuation captures this rest of the program and hands it to the current function as an ordinary function value; invoking that captured continuation later, even from a completely different call frame, resumes execution exactly where it was captured, as many times as desired, effectively implementing arbitrary non-local control flow: early exits, generators, backtracking, or cooperative threads can all be built on top of it.

This is a strictly more general mechanism than exceptions or generators: a continuation can be invoked more than once, including after the function that captured it has already returned, which exceptions and generators cannot do.

PHP has no continuations and no call/cc equivalent. Non-local control flow is limited to a fixed set of built-in constructs: exceptions unwind the stack once and cannot be resumed, and Generator/Fiber can only be suspended and resumed by their own caller, in a strictly linear, single-shot fashion. There is no way to capture the current point of execution as a value and invoke it later, from anywhere else, as call/cc allows.

Documentation

See Also

Continue

continue is used within looping structures to skip the rest of the current loop iteration and resume the execution at the condition evaluation and then the beginning of the next iteration.

continue is not possible inside a switch() structure.

<?php

    foreach ($arr as $key => $value) {
        if (!($key % 2)) { // skip even members
            continue;
        }
        do_something_odd($value);
    }

?>

Documentation

See Also

Design By Contract (DBC)

Design by Contract, or DbC, is a software development approach that focuses on specifying the expected behavior of software components through preconditions, postconditions, and invariants. Although DbC is not natively supported, any application may incorporate its principles into its source code using libraries and coding practices.

Documentation

See Also

Contribution

A contribution, or open-source contribution, is a change submitted to a software project, typically in the form of a pull request or patch. Contributing to open-source projects is a core part of the PHP ecosystem: the language itself, its extensions, and the majority of popular frameworks and libraries are developed collaboratively.

Contributions can take many forms:

  • Bug reports and reproducible test cases
  • Code fixes, new features, and refactoring
  • Documentation improvements
  • Test coverage additions
  • Translations and localization

Many Open Source projects provide a CONTRIBUTING.md file that describes coding standards, testing requirements, and the review process.

PHP’s own development process goes through RFCs voted on by internals contributors.

<?php

// Example: typical open-source contribution workflow (shell commands)
// git clone https://github.com/vendor/project
// cd project
// git checkout -b fix/issue-123
// # Make changes
// git add .
// git commit -m 'Fix: description of the change'
// git push origin fix/issue-123
// # Open a pull request on GitHub

?>

Documentation

See Also

Control Flow Analysis

Control flow analysis, or CFA, is a static analysis technique that examines the possible execution paths through a program. It builds upon the control flow graph to reason about which statements may be reached, which branches may be taken, and which code may be unreachable.

Applications include:

  • Dead code detection: identifying statements that can never be executed
  • Reachability analysis: determining whether a particular point in the code can be reached
  • Exception flow: tracing all paths through try/catch/finally blocks
  • Return path coverage: verifying that all execution paths through a function return a value

Control flow analysis is a prerequisite for more advanced analyses such as data flow analysis and taint analysis.

<?php

function divide(int $a, int $b): float {
    if ($b === 0) {
        throw new InvalidArgumentException('Division by zero');
    }

    return $a / $b;

    // Control flow analysis detects that the line below is unreachable
    echo 'done';
}

?>

Documentation

See Also

Control Flow Graph (CFG)

The Control Flow Graph is a logical representation of the execution of a source code. It takes into account the path that follow the execution in the source, including:

  • Sequential execution: one command at a time
  • Goto jumps: from one part of the code to another one
  • Branching: where one of two or more sequence of actions are exclusively executed, depending on conditions
  • Looping: where the same piece of code is executed repeatedly.

Control Flow Graph is used in code analysis, to audit the modifications of data.

Documentation

See Also

Control Flow

Control flow structures direct the way PHP executes the statements. For example, a loop repeats the same statements several times; a goto instruction jumps to another part of the code; a if-then statement applies a block of code or another, depending on a condition.

  • if
  • else
  • elseif/else if
  • Alternative syntax for control structures
  • while
  • do…while
  • for
  • foreach
  • break
  • continue
  • switch
  • match
  • return
  • require()
  • include()
  • require_once()
  • include_once()
  • goto

Control flow structures can’t be called dynamically: they have to be hardcoded, or nested in a closure or other function.

Each of these constructs answers a different question about the order of execution: conditionals, if, elseif, match, choose between branches; loops, while, do...while, for, foreach, repeat a block until a condition changes; jump statements, break, continue, return, goto, leave the current structure early or transfer control elsewhere; and the file-inclusion constructs, require, include, and their _once variants, bring another script’s control flow into the current one.

Understanding control flow is central to reading any PHP program, since it determines which statements actually run for a given input, in what order, and how many times. Poorly structured control flow, such as deeply nested conditionals or unbounded loops, is a common source of bugs and a frequent target of static analysis and refactoring.

<?php

    if ($a === 1) { 
        $b = 2;
    } else {
        $b = 3;
    }

?>

Documentation

See Also

Control Structures

Control structures are PHP statements that control the flow of execution.

  • if / elseif / else if
  • while
  • do-while
  • for
  • foreach
  • break
  • continue
  • switch
  • match
  • declare
  • return
  • require()
  • include()
  • require_once()
  • include_once()
  • goto
  • throw

Usually, instructions and commands are executed one after another. With control structures, this flow is changed and the execution will go to another part of the code for its next step. For example, inside a loop, when PHP encounters a break command, it will then execute the next command after the loop, instead of the next command sequentially.

PHP offers each control structure in a curly-brace form and, for use inside templates mixed with HTML, an alternative syntax that replaces braces with a colon and matching end...; keywords endif, endwhile, endfor, endforeach, endswitch. Both forms are functionally equivalent; the alternative syntax is mostly a readability choice when PHP blocks are interleaved with markup.

Control structures cannot be assigned to variables, passed as callbacks, or invoked dynamically the way functions can: their names are reserved keywords parsed directly by the engine, which is what allows them to alter the normal top-to-bottom execution order in the first place.

<?php

    if (rand(0, 1) > 0) {
        print 'Hello, world.';
    } else {
        print 'World : hello!';
    }

?>

Documentation

See Also

Controller

Controllers takes in charge one or several URL, extract data from the request, pass them to the model and finally, create and returns the view.

Controllers orchestrate the execution of the request, and act as gatekeeper, ensuring that data are correctly processed.

Documentation

See Also

Convention

A convention is a way in which something is usually done.

There are coding conventions, which is the way the code is presented and should be shared among a or several teams.

There is also the concept of convention over configuration, where the common behaviors, also known as the convention, is used as default, and any unusual aspect must be configured.

Documentation

See Also

Convert

To convert is to transform a piece of data, from one format to another.

The conversion may be lossless, when it may be reverted without loss of information. It is lossy when it cannot be reverted, or if this operation is very expensive.

PHP has several conversion systems:

  • Cast, with (int), (array), (string), etc
  • String format conversion, with iconv(), mb_convert_encoding(), or UConverter::transcode.
  • Number base conversion, with base_convert() and intval().

To convert may also be called cast, encode/decode, escape, crypt/decrypt, hash, sign, etc. depending on the context.

<?php

    // convert an array to a JSON string
    // This is also called 'encoding', and may be decoded
    $array = ['a' => 1];
    $json = json_encode($array);
    
    // convert a string to its MD5 signature
    // it cannot be reverted easily, and it is considered lossful
    $string = 'PHP rocks';
    $hash = md5($string);

?>

Documentation

See Also

Cookie

Cookies serve as a fundamental web technology that enables websites to store small pieces of data directly within a user’s web browser. This stored information persists across browsing sessions, allowing websites to remember specific details about visitors when they return. The primary purposes include tracking user behavior, maintaining login states, personalizing content, and identifying returning visitors to provide customized experiences based on their previous interactions with the site.

<?php

setcookie('aCookieName', 'Cookie value', time()+3600);  /* expire in 1 hour */

?>

Documentation

See Also

Copy On Write (COW)

Copy on write, or COW, is a data management technique where data is shared between contexts, until it is actually modified. When a modification happens, the data is then duplicated, to avoid polluting the original data. Otherwise, simple reads keep the data intact, and save a copy operation and memory.

PHP uses this technique for arrays and strings, unless they are passed by reference. It is totally transparent for the code.

<?php

    $array = [1,2,3];
    
    function trumpet($a) {
        echo $a[1]; // 
        
        $a[2] = 4; // $a is copied, then modified.
    }

?>

Documentation

See Also

Core

Core is the name of the main PHP engine part, which provides the base features of the language. It has a name to differentiate it from the other extensions, although it is also designed as PHP itself.

In particular, Core functions are not the math, string or arrays functions: these are in a distinct extensions.

<?php

    var_dump(1);

?>

Documentation

See Also

Coroutine

Coroutines are methods whose execution may be suspended and resumed.

PHP generators are a sort of coroutines.

Swoole, Openswoole and fibers extensions offer coroutines.

<?php

    // Example from OpenSwoole (https://openswoole.com/docs/modules/swoole-coroutine)
    Co\run(function()
    {
        go(function()
        {
            Co::sleep(1);
            echo "Done 1\n";
        });
    
        go(function()
        {
            Co::sleep(1);
            echo "Done 2\n";
        });
    });

?>

Documentation

See Also

Correlation ID

A correlation ID is a unique identifier attached to a request or event so that all related operations across multiple services or log entries can be linked together.

In a distributed system, a single user action may trigger calls to several microservices, each writing their own logs. Without a shared identifier, reconstructing the full lifecycle of that request requires matching timestamps and guessing at relationships. By generating a UUID at the entry point, API gateway, queue consumer, CLI command, and forwarding it in every outbound call and log line, all related activity shares the same correlation ID and can be retrieved as a group.

Correlation IDs are typically propagated through HTTP headers, e.g. X-Correlation-ID or X-Request-ID, or as metadata in message queue payloads. Middleware or a centralized logger injects the value at the boundary and makes it available throughout the request lifecycle, often via a PSR-3 logger context or a dependency injection container.

A correlation ID is not secret and is not a security token. Its sole purpose is observability.

<?php

    use Ramsey\Uuid\Uuid;

    // At the entry point (e.g. a middleware)
    $correlationId = $_SERVER['HTTP_X_CORRELATION_ID'] ?? Uuid::uuid4()->toString();

    // Forward it to downstream services
    $client->request('POST', $url, [
        'headers' => ['X-Correlation-ID' => $correlationId],
    ]);

    // Include it in every log line
    $logger->info('Order placed', ['correlation_id' => $correlationId]);

?>

Documentation

See Also

count()

count() is a native PHP function, that returns the number of elements in the argument.

count() is basically meant to work on arrays: it returns the number of elements in the array. count() is also able to run recursively, when provided the second argument.

By extension, count() works on classes of objects that implement the Countable interface.

It is a Fatal error to call count() on an object that can’t be counted. Use is_countable() or type validation to make sure the data may be counted.

<?php

echo count([1,2,3]); // 3

echo count([1,2,3, [4, 5]], COUNT_RECURSIVE); // 6 == 4 + 2 

class Elephpant implements Countable {
    function count() : int {
        // arbitrary count
        return 7;
    }
}

echo count(new Elephpant); // 7

?>

Documentation

See Also

Countable Interface

The Countable interface is a native built-in interface that allows objects to be counted using the count() function.

By implementing the Countable interface, a class defines custom logic for determining its count.

<?php
class Collection implements Countable
{
    private $list = [];
    
    public function add($tusk) {
        $this->list[] = $tusk;
    }

    public function count()
    {
        return $this->count;
    }

}

$count = new Counter;
$count->inc();
$count->inc();

print count($count).PHP_EOL;

?>

Documentation

See Also

Coupling

Coupling refers to the degree of dependency between different classes of a software. It measures how interconnected or interdependent these classes are. There are several types of coupling, ranging from loose to tight.

  • Content Coupling: this is the strongest form of coupling, where one module directly accesses or modifies the internal data or methods of another class. It’s considered the most undesirable type of coupling, as it makes the modules highly dependent on each other and difficult to change independently.
  • Common Coupling: in this type, multiple modules share the same data or a common storage location. Changes to this shared data can impact multiple modules simultaneously, leading to potential issues in understanding and maintaining the codebase.
  • External Coupling: this type of coupling occurs when two modules rely on the same external interface, such as a file, a database, or a communication protocol. Changes to the external interface can affect multiple modules, but at least the internal details remain separate.
  • Control Coupling: control coupling happens when one module passes control information, e.g., flags, status, or control variables to another module. The receiving module behaves differently based on this information, introducing dependencies between them.
  • Data Coupling: data coupling is a better form of coupling compared to the above ones. It happens when two modules share data through parameters or arguments, but they do not directly access each other’s internal data. It promotes encapsulation and makes it easier to maintain and understand the system.
  • Message Coupling: in this type, modules communicate by passing messages, which can be in the form of method calls, function calls, or events. The modules don’t need to know each other’s internal details, and they interact based on well-defined interfaces.
  • No Coupling or Content Independence: the ideal type of coupling is no coupling at all, where modules are entirely independent of each other. Each module operates in isolation, and changes to one module do not affect others

Software designers aim to achieve low coupling and high cohesion in their systems to improve maintainability, reusability, and overall system design.

The opposite of coupling is decoupling.

<?php

// User class with high coupling (Content Coupling)
class User {
    private $username;
    private $email;

    public function __construct($username, $email) {
        $this->username = $username;
        $this->email = $email;
    }

    // Content coupling: EmailSender is directly accessed here
    public function register() {
        // Register the user in the database

        // Send a welcome email
        $emailSender = new EmailSender();
        $emailSender->sendWelcomeEmail($this->username, $this->email);
    }
}

?>

Documentation

See Also

Coverage

The coverage is the concept that an operation has been applied to every part of a whole body.

PHP uses this notion with tests, where code coverage is expected to use as much as possible of the code; and type coverage, where as many types as possible have been applied.

Usually, coverage refers to code coverage.

Documentation

See Also

Command Query Responsibility Segregation (CQRS)

CQRS is an architectural pattern that separates read operations, Queries from write operations, Commands, into distinct models. It was popularized by Greg Young, building on Bertrand Meyer’s Command-Query Separation principle.

Read and write workloads often have very different performance and scaling needs, so treating them as a single unified model creates unnecessary friction. By separating them, it is possible to optimize each side independently: for example, using denormalized read models or dedicated indexed projections on the query side without affecting your write logic.

It also simplifies complex domain logic. Commands encapsulate intent and business rules cleanly, without being cluttered by the concerns of how data is presented or fetched. This makes the write side easier to test and reason about.

CQRS pairs especially naturally with Event Sourcing, where state changes are stored as a sequence of events rather than overwriting rows: but it’s worth noting that Event Sourcing is not necessary to benefit from CQRS. The two are complementary, not dependent on each other.

Documentation

See Also

Crack

Cracking, also called password cracking or hash cracking, refers to breaking a security mechanism. Most commonly, it means recovering a plaintext password from its hash. Attackers crack hashes using:

  • Brute force: trying every possible input
  • Dictionary attacks: trying common words and known passwords
  • Rainbow tables: precomputed hash linked to plain-text mappings
  • Rule-based attacks: applying transformations like capitalisation, digit appending, … to existing word lists

In any application, passwords must be stored using a strong, salted hashing algorithm such as bcrypt or Argon2. These algorithms are deliberately slow and include a random salt, making cracking computationally expensive and rendering rainbow tables useless.

Using weak algorithms such as MD5 or SHA-1 for passwords is a critical vulnerability, as they can be cracked rapidly with modern GPUs.

<?php

    // WRONG: MD5 is trivially crackable
    $hash = md5('password123'); // 482c811da5d5b4bc6d497ffa98491e38
    
    // CORRECT: use password_hash() — bcrypt with automatic salt
    $hash = password_hash('password123', PASSWORD_BCRYPT);
    
    // Verify
    if (password_verify('password123', $hash)) {
        echo 'Password is correct';
    }
    
    // Even stronger: Argon2id (PHP 7.3+)
    $hash = password_hash('password123', PASSWORD_ARGON2ID);

?>

Documentation

See Also

Cyclic Redundancy Check 32-bit (CRC32)

CRC32 stands for Cyclic Redundancy Check 32-bit. It is a hash function that produces a 32-bit, or 8-character hexadecimal, checksum or hash value from a given input, typically a sequence of bytes or a string. The primary purpose of CRC32 is error-checking and data integrity verification.

PHP calculates CRC32 values with the native crc32() function, and the hash() function, although with slight differences.

<?php
    
    $checksum = crc32("The quick brown fox jumped over the lazy dog.");
    printf("%u\n", $checksum);
    
    hash('crc32b', $str) === str_pad(dechex(crc32($str)), 8, '0', STR_PAD_LEFT);

?>

Documentation

See Also

CRLF Injection

CRLF injection, also called header injection, is a security vulnerability that occurs when an attacker can insert a carriage-return, the \r char and line-feed, the \n char sequence into data that is later included in an HTTP response header, an email header, or another line-delimited protocol message.

In HTTP, headers are separated from each other by \r\n and the header section is terminated by \r\n\r\n. If user-controlled input reaches a call to header() without sanitisation, an attacker can inject additional headers or even start a second HTTP response body. Such an attack is historically called HTTP response splitting.

A typical payload looks like this: Location: https://example.com\r\nSet-Cookie: session=evil.

This causes the browser to see two separate headers, potentially enabling session fixation, cross-site scripting via injected HTML, or cache poisoning.

The native function header() has blocked embedded newlines since version 7.2 and the CVE-2018-7584 that addressed the related edge cases, but older stacks, custom header-building code, and curl-based HTTP clients that assemble raw request headers remain at risk.

Sanitize any value destined for a header by stripping or rejecting \r and \n before use. The function str_contains() or a regex check makes this straightforward.

<?php

    // Vulnerable: user input placed directly in a redirect header
    $url = $_GET['url'];
    header('Location: ' . $url); // attacker sends url = https://x.com\r\nSet-Cookie: x=1

    // Safe: strip CR and LF before building the header value
    $url = str_replace(["\r", "\n"], '', $_GET['url']);
    header('Location: ' . $url);

?>

Documentation

See Also

Cron

A cron job is a scheduled task that runs PHP code automatically at specified times or intervals, without a web request.

It’s usually handled by the operating system, such as Linux/Unix cron daemon, not by PHP itself.

There are many cron alternatives, like systemd timers, framework schedulers, components schedulers, Windows Task Scheduler, Kubernetes CronJobs, cloud-native schedulers, database-backed schedulers, HTTP-based scheduling, and workflow schedulers.

Documentation

See Also

Cross-cutting Concerns

Cross-cutting concerns are aspects of a system that affect multiple layers or components but cannot be cleanly encapsulated in any single module. They cut across the boundaries of the architecture rather than living within one well-defined layer.

Common examples: logging, authentication and authorisation, caching, transaction management, error handling, input validation, and metrics collection.

The problem is that naively implementing a cross-cutting concern leads to code duplication: the same logging or auth check is copy-pasted into dozens of classes. When the requirement changes, every copy must be updated.

Possible solutions:

  • Middleware, PSR-15: HTTP pipeline stages that wrap every request/response
  • Event listeners / hooks: framework events dispatched at lifecycle points
  • Decorators: wrap a service class to add behaviour without modifying it
  • PHP Attributes + compile-time code generation, such as AOP with Spiral Framework
  • Aspect-Oriented Programming, AOP: intercepts method calls to inject cross-cutting logic.
<?php

// Middleware: authentication as a cross-cutting concern
class AuthMiddleware implements MiddlewareInterface {
    public function process(ServerRequestInterface $req, RequestHandlerInterface $next): ResponseInterface {
        $token = $req->getHeaderLine('Authorization');
        if (!$this->auth->validate($token)) {
            return new Response(401);
        }
        return $next->handle($req); // all subsequent handlers see an authenticated request
    }
}

// Decorator: caching as a cross-cutting concern
class CachedOrderRepository implements OrderRepository {
    public function __construct(
        private OrderRepository $inner,
        private CacheInterface  $cache,
    ) {}

    public function findById(int $id): ?Order {
        return $this->cache->get(order:$id, fn() => $this->inner->findById($id));
    }
}

?>

Documentation

See Also

Create, Read, Update And Delete (CRUD)

CRUD stands for Create, Read, Update and Delete. Those are the four primitive operation for storage.

They are usually the basic operations needed whenever PHP communicates with a storage system.

Documentation

See Also

To Crypt

To crypt is to apply a data transformation that keeps the original information, but makes it impossible to read without decrypting. Usually, the transformation involves a key, which stays secret, and is only known from the author or the receiver of the data.

Crypting data may be done for the transit of information, or its storage, in a database, until its usage. In both cases, privacy is critical.

Since the data may be decrypted, it is always possible that an unwanted actor accesses the crypted data. The notion of impossible to read is related to the difficulty to perform the decryption without the critical key.

The opposite to crypt is to decrypt, when it is a legit operation, or to crack, when it is an unwanted operation.

<?php

    // Encryption
    $key = openssl_random_pseudo_bytes(32); // 256-bit key
    $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
    
    $plaintext = 'PHP rocks';
    $ciphertext = openssl_encrypt($plaintext, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
    $encrypted = base64_encode($iv . $ciphertext);
    
    // Decryption
    $decoded = base64_decode($encrypted);
    $iv = substr($decoded, 0, openssl_cipher_iv_length('aes-256-cbc'));
    $ciphertext = substr($decoded, openssl_cipher_iv_length('aes-256-cbc'));
    $decrypted = openssl_decrypt($ciphertext, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
    
    echo 'Encrypted: ' . $encrypted . PHP_EOL;
    echo 'Decrypted: ' . $decrypted . PHP_EOL;

?>

Documentation

See Also

Cryptography

Cryptography is the practice and study of techniques for secure communication in the presence of adversarial behavior. It includes techniques like hashing and encryption.

PHP include native cryptographic features, like hash() and crypt(), and also extensions, such as openssl or sodium.

<?php

    echo hash('ripemd160', 'The quick brown fox jumped over the lazy dog.');

?>

Documentation

See Also

Content Security Policy (CSP)

Content Security Policy, or CSP, is an HTTP response header that lets a server declare which sources of scripts, styles, images, fonts, and other resources a browser is allowed to load and execute for a given page.

CSP is a defense-in-depth measure against XSS: even if an attacker manages to inject a <script> tag or an inline event handler, a strict policy can make the browser refuse to execute it, because the payload does not come from an allowed source or violates the 'unsafe-inline' restriction. CSP does not prevent injection itself, and is not a substitute for output encoding; it only limits the damage once injection has already happened.

Common directives include script-src, style-src, and default-src. Modern policies favor per-request nonces or hashes over 'unsafe-inline', so that only script blocks explicitly marked by the server are allowed to run.

<?php

    // A nonce-based policy: only <script> tags carrying this nonce may execute.
    $nonce = base64_encode(random_bytes(16));

    header("Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{$nonce}'");

?>
<script nonce="<?= $nonce ?>">
    // allowed to run
</script>

Documentation

See Also

Cross Site Request Forgery (CSRF)

A CSRF, or XSRF attack happens when a malicious website tricks a logged-in user’s browser into sending an unwanted request to another application. CSRF requires both an intermediate website and a victim website.

CSRF is often confused with SSRF, the server-side request forgery, but the two are distinct: CSRF forges a request from the victim’s browser, while SSRF forges a request from the server itself.

Documentation

See Also

CSS

CSS, the Cascading Style Sheets, is the language used to describe the visual presentation of HTML documents. It controls layout, colours, fonts, spacing, animations, and responsiveness across devices.

While CSS itself is a client-side technology, PHP frequently interacts with it:

  • Generating dynamic CSS values for theming, user preferences, etc.
  • Injecting CSS variables from server-side configuration
  • Rendering HTML templates that include or link stylesheets
  • Parsing or minifying CSS on the server

When PHP outputs CSS content directly, care must be taken to escape values correctly to prevent CSS injection. It is a form of XSS where an attacker injects malicious CSS rules.

In modern PHP applications, CSS is typically bundled by a frontend build tool and linked from PHP templates.

Although they have overlappign concerns, CSS and XSS are two distinct things: one is a language, the other is a security vulnerability.

<?php

    // Generating a dynamic CSS custom property from a user setting
    $primaryColor = '#3498db'; // from database / user preference
    $primaryColor = preg_replace('/[^#a-fA-F0-9]/', '', $primaryColor); // sanitize
    
    header('Content-Type: text/css');
    
    echo ":root {
        --primary-color: {$primaryColor};
    }
    ";

?>

Documentation

See Also

CSV Injection

A CSV injection is a vulnerability, where a csv file triggers the execution of a formula, stored in a cell. Formulas in cells starts usually with =, and may also use +, -, @, tabulation and carriage return.

Depending on the opening spreadsheet software, various targets may be achieved, ranging from sending local data to a remote server, to take over the computer.

CSV injections rarely target PHP itself, as it is not a spreadsheet, nor support formulas in CSV files. Also, components such as PHPspreadsheet are able to run a wide range of formulas.

PHP may relay an injection by saving it in a CSV file.

Documentation

See Also

Comma Separated Values (CSV)

CSV is a data format, where values are separated by commas.

Each line represents a data record. The first line may be a header line, or not.

CSV is not fully standardized: it represents in fact several formats, with different features. In particular, nested new lines and escape sequences may vary from format to format.

Documentation

See Also

Capture The Flag (CTF)

Capture The Flag, abbreviated CTF, is a type of cybersecurity competition in which participants solve security challenges to find hidden strings called flags. Each flag, once submitted, awards points. Challenges span categories such as web exploitation, binary exploitation, reverse engineering, cryptography, and forensics.

Web CTF challenges frequently involve PHP applications with intentional vulnerabilities: type juggling, code injection via eval(), file inclusion via unsanitised input, insecure deserialisation, or logic flaws in authentication. Solving them requires understanding both the PHP language and common attack patterns.

CTFs are used for learning, hiring, and security research. They are legal and controlled environments for practising offensive techniques that would be illegal on real targets.

Documentation

See Also

Ctype

ctype is a set of functions used for character type checking. These functions are primarily designed to determine the type of characters in a string. They are useful for tasks such as input validation, data processing, and character manipulation. The ctype functions are part of PHP’s standard library.

<?php

    $strings = ['KjgWZC', 'arf12'];
    foreach ($strings as $testcase) {
        if (ctype_alpha($testcase)) {
            echo "The string $testcase consists of all letters.\n";
        } else {
            echo "The string $testcase does not consist of all letters.\n";
        }
    }

?>

Documentation

See Also

Client URL (CURL)

Curl is both a PHP extension and a multiprotocol file transfer library.

The cURL, for client URL, extension is a powerful library that allows to transfer data to and from servers using various protocols. It enables to make HTTP requests, handle responses, and perform various network-related tasks from within source code.

The cURL extension provides a set of functions that can be used to perform different tasks, such as making GET and POST requests, sending custom headers, handling cookies, and more.

cURL is used to access remote resources, using various protocols such as DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, POP3, POP3S, RTMP, RTMPS, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET and TFTP.

<?php

// Example from the PHP manual
$ch = curl_init("http://www.example.com/");
$fp = fopen("example_homepage.txt\, \w");

curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);

curl_exec($ch);
if(curl_error($ch)) {
    fwrite($fp, curl_error($ch));
}
curl_close($ch);
fclose($fp);
?>

Documentation

See Also

Curly Brackets

Curly brackets have different usage:

  • Delimit a block of code
  • Represents a variable delimiter inside string
  • It used to identify a single byte in a string, with an array syntax

They are also called curly braces.

<?php

    for($a = 1; $a < 10; ++$i) {
        // block
        
        // delimit a variable to avoid confusing it with $vars
        echo "{$var}s";
    }

    // old syntax: it used to be the second character in the string
    // This is a removed feature in PHP 8.0+
    // modern syntax : use angular brackets
    echo $string{1};

?>

Documentation

See Also

Currying

Currying is the transformation of a function that takes multiple arguments into a sequence of functions that each take a single argument. The name comes from mathematician Haskell Curry.

In a language with native currying, calling a multi-argument function with fewer arguments than it expects does not produce an error: it returns a new function that expects the remaining arguments. This allows building specialised functions from general ones with no extra syntax.

Native currying is available in Haskell, F#, OCaml, and Erlang, where all functions are curried by default. Scala and Kotlin support it explicitly.

PHP does not support currying natively. It can be approximated by returning closures manually, but there is no syntactic or runtime support.

Because building a curried function usually starts from partial application, the two are sometimes referred to jointly as partial application currying.

<?php

    // Manual simulation of currying with closures
    $add = fn($tusk) => fn($ivory) => $tusk + $ivory;

    $add5 = $add(5);
    echo $add5(3); // 8

?>

Documentation

See Also

Custom Function

A custom function, or user-defined function, is a function declared by the developer, as opposed to a native PHP function provided by the engine or an extension. Custom functions encapsulate reusable logic under a named callable.

Functions are declared with the function keyword and may be defined in any scope. Unlike many languages, PHP functions are global by default once declared: a function defined inside a conditional block or another function is still globally accessible after that point is reached at runtime.

Custom functions can be:

  • Regular functions: function myFunction() {}
  • Closures: $fn = function() {}
  • Arrow functions: $fn = fn() => expression
  • Static methods: functions bound to a class

PHP also supports first-class callables, since PHP 8.1, and can call custom functions by name stored in a variable, as a dynamic calls.

<?php

    // Regular custom function
    function clamp(int $value, int $min, int $max): int {
        return max($min, min($max, $value));
    }
    
    echo clamp(150, 0, 100); // 100
    
    // Anonymous function stored in a variable
    $double = function(int $n): int {
        return $n * 2;
    };
    
    echo $double(5); // 10
    
    // Arrow function
    $triple = fn(int $n): int => $n * 3;
    echo $triple(5); // 15
    
    // First-class callable syntax (PHP 8.1)
    $fn = clamp(...);
    echo $fn(42, 0, 50); // 42

?>

Documentation

See Also

Custom

A feature is called custom when it is not part of the standard installation of PHP, any PHP extension or a publish library. For example, the function trumpet() is generally a custom function.

Any declaration object may be custom: constants, variables, classes, interfaces, enums, traits.

A custom asset is usually the last to be defined, and, as such, has to use a distinct name. For example, declaring a function called wp_header is possible as long as the code is not part of Wordpress, which does declare it as a common set of features.

<?php

// This is a custom function
function trumpet() {}

?>

Documentation

See Also

Common Vulnerabilities And Exposures (CVE)

CVE, or Common Vulnerabilities and Exposures, is a standardized, industry-recognized list of publicly disclosed cybersecurity vulnerabilities and exposures in software and hardware. Maintained by the MITRE Corporation, it acts as a dictionary that assigns unique identifiers, e.g. CVE-2022-44702, to security flaws. This allows professionals to uniformly identify, track, and remediate risks.

Documentation

See Also

Concurent Version System (CVS)

CVS is Concurrent Versions System. It is a revision control system. It is a version control system that allows multiple users to collaborate on a project by managing the changes made to files and keeping track of different versions of those files. CVS was one of the earlier popular version control systems, introduced in the 1980’s.

With CVS, developers can check out a copy of a project’s source code, make changes to files, and then commit those changes back to the repository. It provides features like branching and merging, which allow parallel development and the integration of changes from different branches.

Documentation

See Also

Cyclomatic Complexity

Cyclomatic complexity is a software metric of the complexity of a program.

This metric measures the number of decisions happening within the code. Those decisions are commands such as If/then, loops, or ternary operators.

<?php

    function trumpet() {
        if ($a) {
    
        } else {
    
        }
    }

?>

Documentation

See Also

Dangling Reference

In a foreach loop, a variable is used for looping through the array. When this variable is configured as a reference, the reference survives after the end of the loop. When this variable is reused later, it applies to the last element of the array and overwrites its value.

This doesn’t happen when the second loop doesn’t use a reference.

It is recommended to unset the referenced variable, after the loop. It destroys the reference, not the value.

<?php

    $array = ['a', 'b', 'c'];
    
    foreach($array as &$tusk) { 
        // doSomething() or even do nothing! 
    }
    
    // second loop, no reference
    foreach($array as $tusk) { 
        // doSomething() or even do nothing! 
    }
    
    var_dump($array);
    $array = ['a', 'b', 'b'];

?>

Documentation

See Also

Data Access Object (DAO)

Data Access Object is a design pattern used to abstract and encapsulate all access to a data source, typically a database. The DAO manages the connection with the data source to obtain and store data, leaving the rest of the application decoupled from the persistence layer.

Documentation

See Also

Data Container

A data container is a structure that stores data. It is a generic concept, that covers variables, both local and global, properties, both static and simple, and array elements.

<?php

    $a = 1;
    $object->property = 'b';
    $array = ['a', 3, 4.4];

?>

Documentation

Data Flow Analysis (DFA)

Data flow analysis, or DFA, is a static analysis technique that tracks how data values move through a program. It follows variables from the point where they are defined or assigned to the points where they are used.

Common data flow problems include:

  • Reaching definitions: which assignments of a variable can reach a given use
  • Live variables: which variables hold values that may still be used later
  • Taint analysis: whether user-supplied data can reach a sensitive sink without sanitisation
  • Type inference: propagating known type information across the program
  • Null propagation: detecting paths where a null value is used without a check

Data flow analysis requires a control flow graph. It is foundational for security tools that detect injection vulnerabilities and for compilers that optimise code.

<?php

function process(string $input): string {
    $sanitized = htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
    // Data flow analysis confirms $sanitized is safe to echo
    return $sanitized;
}

function unsafe(string $input): void {
    // Data flow analysis flags $input as tainted at this sink
    echo $input;
}

?>

Documentation

See Also

Data Hiding

Data hiding is a core principle of object-oriented programming that restricts direct access to certain components of an object. It is achieved through visibility modifiers: private, protected, and public.

By hiding internal state, a class controls how its data is accessed and modified, preventing accidental corruption and enforcing invariants. This leads to more maintainable, testable, and robust code.

PHP provides several mechanisms for data hiding:

  • Visibility modifiers on properties and methods: private, protected, public
  • The readonly keyword for immutable properties
  • The __get() and __set() magic methods for controlled access
  • Typed properties which enforce type constraints on assignment

Data hiding is closely related to the concept of encapsulation, which bundles data and methods that operate on that data within a single unit, controlling external access.

<?php

    class BankAccount {
        private float $balance;
        private string $owner;

        public function __construct(string $owner, float $initialBalance) {
            $this->owner = $owner;
            $this->balance = $initialBalance;
        }

        // Controlled access through methods
        public function deposit(float $amount): void {
            if ($amount <= 0) {
                throw new \InvalidArgumentException('Amount must be positive');
            }
            $this->balance += $amount;
        }

        public function getBalance(): float {
            return $this->balance;
        }
    }

    $account = new BankAccount('Alice', 1000);
    // $account->balance = 999999; // Fatal error: cannot access private property
    $account->deposit(500);
    echo $account->getBalance(); // 1500

?>

Documentation

See Also

Data Leak

A data leak is the publication of unwanted information, which leads to further security attack, or actual data theft.

A data leak may be both a successful breach, when it collects directly usable information, such as reading private information; it may also be a stepping stone for a following and more complex attack, such as identifying the PHP version or the underlying framework.

Documentation

See Also

Data Mapper

A data mapper, also called an object mapper, performs a bidirectional conversion of data, between PHP’s OOP representation and a database storage.

The data mapper is responsible for CRUD operations: create, read, update and delete.

Documentation

See Also

Data

Data is a broad term that refers to information, facts, or statistics that are represented in a form suitable for processing, interpretation, or communication. Data can take various forms, including numbers, text, images, sounds, and more. In the context of computing and technology, data often refers to digital information that can be manipulated, stored, and analyzed by computer systems.

Data may be structured or unstructured, raw or processed, insecure or validated. There is also the expression of big data for large datasets.

Documentation

See Also

Database Commit

A database commit makes a transaction’s changes permanent. Once committed, the modifications are durable and visible to other connections.

A commit is issued via a call to a commit method, such as PDO::commit() or mysqli_commit() after a sequence of statements executed inside a transaction started with PDO::beginTransaction() or mysqli_query(). If any step fails, PDO::rollBack() or mysqli_rollback() reverts all changes.

Auto-commit mode is enabled by default in PDO: each statement is immediately committed unless an explicit transaction is open.

Each database extension has its own commit method. There is often an auto-commit mode, where the commit is implicit after each query: it must be disabled to allow multiple queries in the same transaction.

<?php

    $pdo = new PDO('mysql:host=localhost;dbname=shop', 'user', 'pass');

    try {
        $pdo->beginTransaction();

        $pdo->exec("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
        $pdo->exec("UPDATE accounts SET balance = balance + 100 WHERE id = 2");

        $pdo->commit();
    } catch (Exception $e) {
        $pdo->rollBack();
        throw $e;
    }

?>

Documentation

See Also

Database

A database is an organized set of data, which may be queried.

The database differs from the dataset by the query mechanism.

The database may be managed by a server, though it is not necessary.

Documentation

Dataset

A dataset is an organized collection of data.

The data may be structured or not. The dataset needs a programming language to query it, or will be imported in a database for further processing.

Documentation

Datastack

A data stack is a LIFO data structure: the last data added to the stack is the first to get out.

A data stack may be implemented with an array, and the array_push(), or $array[] operator, and the array_pop() functions.

There is also a class called SplStack, in the spl extension, and Ds\Stack in the ds extension.

<?php

    $stack = [];
    $stack[] = first;
    $stack[] = second;
    // same as array_push($stack, second);
    
    echo array_pop($stack); // Outputs: second

?>

Documentation

See Also

Data Structure

A data structure is a way of organizing and storing data in memory to enable efficient access and modification. PHP’s primary data structures are the classes and arrays, which include indexed arrays, associative arrays, anonymous classes and nested structures in a single construct.

For more specialized needs, the spl and ds extensions offer types beyond the default PHP ones.

Choosing the right data structure has a direct impact on algorithmic complexity and memory usage.

<?php

    use Ds\Vector;
    use Ds\Map;
    
    $vector = new Vector([1, 2, 3]);
    $map    = new Map(['key' => 'value']);
    
    $stack = new SplStack();
    $stack->push('first');

?>

Documentation

See Also

Dates

These functions allow to get the date and time from the server where the application is running. These functions format the date and time in many different ways.

<?php

    $dt = new DateTimeImmutable('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 = $dt->add(new DateInterval('PT3H'));
    echo 'End:   ', $dt->format('Y-m-d H:i:s P'), PHP_EOL;

?>

Documentation

See Also

DateInterval

DateInterval is a class for the representation of period of time, or stretch of time. It may be added to DateTimeImmutable and DateTime objects. It is only created as a time duration.

<?php

    // Create a specific date
    $someDate = \DateTime::createFromFormat('Y-m-d H:i', '2022-08-25 14:18');
    
    // Create interval
    $interval = new \DateInterval('P7D');
    
    // Add interval
    $someDate->add($interval);
    
    // Convert interval to string
    echo $interval->format('%d');

?>

Documentation

See Also

Datetime Trap

When using Datetime objects, be aware that methods that return the modified date are actually returning the object itself. This means that calculating a difference with diff(), add(), modify() methods also changes the underlying object.

This trap is also set in packages that are built on top of Datetime.

To avoid this trap, use the DatetimeImmutable class. This class is not modified by those methods, but returns a new object every time.

<?php

    $today = new Datetime('now');
    print $today->format('d-m-Y').PHP_EOL;
    // for example, 24-11-2026
    
    $tomorrow = $today->add(new DateInterval('P1D'));
    print $tomorrow->format('d-m-Y').PHP_EOL;
    // 25-11-2026 (as expected)
    
    $twoDaysLater = $today->add(new DateInterval('P2D'));
    print $twoDaysLater->format('d-m-Y');
    // 27-11-2026 (one day overshoot!)

?>

Documentation

See Also

DateTime

DateTime and DateTimeImmutable is a class for the representation of date and time. It has two variants: DateTimeImmutable cannot be modified after creation, while DateTime can.

Both classes comes with the DateTimeInterface, for typing purposes.

DateTime objects may be created with the constructor, and with several specific methods, such as createFromInterface, createFromFormat or createFromImmutable.

<?php

    $date = new DateTimeImmutable('2024-02-24 11:45 America/Montreal');
    
    $mutable = DateTime::createFromInterface($date);
    
    $date = new DateTime('2014-06-20 11:45 Europe/Amsterdam');

?>

Documentation

See Also

DateTimeInterface

DateTimeInterface is a PHP interface implemented by both DateTime and DateTimeImmutable. It defines the common API shared by both mutable and immutable date-time objects.

Using DateTimeInterface as a type in function signatures accepts either class, making code agnostic to mutability. It cannot be implemented by user-defined classes directly; it exists solely to type both built-in date-time classes.

DateTimeInterface exposes methods such as format(), getTimestamp(), getTimezone(), and diff().

<?php

    function formatDate(DateTimeInterface $date): string {
        return $date->format('Y-m-d');
    }
    
    // both classes satisfy the type
    echo formatDate(new DateTime('2024-01-15'));
    echo formatDate(new DateTimeImmutable('2024-06-03'));

?>

Documentation

See Also

Days Are Not 86400 Seconds

Days in seconds is a classic bug when dealing with dates. It happens when adding 86400 seconds to a time to get the same time on the next day.

The bug will happen most commonly twice a year, at the change of time from winter to summer time. Those days are one hour longer or shorter and lead to calculating the wrong time on the next day.

This bug may also have an impact when the internal clock of the server is updated, or when extra leap seconds are added, on December 31st or June 30th. It depends on the years.

When dealing with days, it is recommended to use an interval, or use a relative expression like 'tomorrow'.

<?php

    $tomorrow = new DateTime('tomorrow');
    $secondsLeft = $tomorrow->getTimestamp() - time();
    echo $secondsLeft;

?>

Documentation

See Also

Days In Month

Days in month is a classic bug when dealing with dates. It happens when adding a month to a date and ending up two months later.

This happens when adding a month to the last day of a month, while this month is longer than the next. For example, January 31st, or Halloween October 31st. After adding a month, PHP calculates it as the November 31st, which doesn’t exists. Yet, PHP converts it to December 1st.

When dealing with months, it is recommended to use expressions like ‘first day of this month’, or ‘next month’, instead of adding a month to an existing date.

<?php

    echo date('d-m-Y', strtotime('+1 months', strtotime('31 October 2000')));

    echo (new DateTime('first day of this month'))->format('jS, F Y');

    echo (new DateTime('next month'))->format('jS, F Y');

?>

Documentation

See Also

Database Abstraction Layer (DBA) Extension

The Database Abstraction Layer, or DBA, extension provides a unified and consistent programming interface for interacting with various key-value database systems, especially those that follow the Berkeley DB-style architecture. This extension allows developers to perform database operations like reading, writing, updating, and deleting records using the same set of functions, regardless of the underlying database type. It simplifies the process of working with different flat-file database formats by abstracting away their individual APIs, making the code more portable and easier to maintain when switching between supported database engines like DBM, GDBM, or Berkeley DB.

<?php

// Example from the PHP manual

$id = dba_open('/tmp/test.db', "\n", 'db2');

if (!$id) {
    echo "dba_open failed\n";
    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);
?>

Documentation

See Also

Database Abstraction Layer (DBAL)

A Database Abstraction Layer, a DBAL, provides one unique interface to build, and execute queries on different databases. This is said to help with migration between different flavors of databases, yet SQL language usually prevents it.

Documentation

Domain Design Driven (DDD)

Domain-Driven Design, aka DDD, is a software development approach that emphasizes structuring and modeling software based on the real-world domain it is meant to represent. It was popularized by Eric Evans in his book Domain-Driven Design: Tackling Complexity in the Heart of Software.

Documentation

See Also

Distributed Denial Of Service (DDOS)

Distributed Denial Of Service, or DDOS, is a type of attack where many computers flood a target, like a website or server, with traffic to overwhelm it and make it unavailable.

Often, the DDOS uses an operation on the target that is long or costly, so that the number of requests generates a large load on the server.

https://en.wikipedia.org/wiki/Denial-of-service_attack

Documentation

See Also

Dead Code

Dead code refers to sections of code that are no longer executed or reachable during the program’s execution. It includes any lines or blocks of code that do not contribute to the program’s functionality or produce any observable results. Dead code can be the result of code modifications, changes in requirements, or mistakes during development.

Dead code is also known as unused code. It happens to any defined structure. Variables, methods, functions, classes, interfaces, etc..

<?php

    // stampede is dead code : never executed
    function stampede() { echo 'World'; }

    // trumpet() is alive code : it is executed
    function trumpet() { echo 'Hello'; }

    echo trumpet();

?>

Documentation

See Also

Deadline

A deadline, and the act of carrying it down through the call chain, deadline propagation, is an absolute point in time by which an entire unit of work, potentially spanning several retries and several downstream calls, must finish, as opposed to a timeout, which bounds a single call. Where a timeout answers ‘how long may this one attempt take’, a deadline answers ‘when must all of this be done, no matter how many attempts or hops it takes to get there’.

A deadline is set once, near the entry point of a request, for example a controller, and is then propagated down through every layer that makes further calls: a service, a repository, an HTTP client, a retry loop. Each layer computes the time remaining and uses it to size its own timeout, and to decide whether it is even worth attempting another retry: once now() > deadline, the operation is abandoned and reported as failed, rather than retried again with whatever time-bounded budget the next layer would otherwise allow. This prevents death by a thousand retries, where several layers each retry independently, and their retries multiply into a response time far larger than any individual timeout would suggest.

PHP has no built-in deadline primitive comparable to Go’s context.Context or gRPC deadlines: applications propagate a deadline by hand, typically as a timestamp carried in a request-scoped object, in Laravel’s Context facade, or as an extra argument threaded through the call chain, and subtract elapsed time from it before each downstream call or retry attempt.

<?php

    function withDeadline(callable $operation, float $deadline): mixed {
        $remaining = $deadline - microtime(true);
        if ($remaining <= 0) {
            throw new \RuntimeException('Deadline already exceeded');
        }
        return $operation($remaining); // pass the remaining budget down
    }

    $deadline = microtime(true) + 2.0; // 2 seconds for the whole operation
    withDeadline(
        fn ($budget) => $client->request('GET', $url, ['timeout' => $budget]),
        $deadline
    );

?>

Documentation

See Also

Technical Debt

Debt generally refers to technical debt, as a whole.

Technical debt represents the extra development work that arises when code is written in a quick-and-dirty way instead of following best practices. Previous work has left issues to be fixed later and that later is now.

Technical debt is not built visibly on the spot, but is usually assessed later, when the need for a previous chore becomes a reality. It may be opposed to YAGNI: you are not going to need it.

There are many types of debt: code, maintenance, documentation, readable, visual, etc.

By extension, anything that currently slows down development is considered a debt.

Documentation

See Also

Debug

Debugging is the action to diagnostic a bug, find its root cause, quick workaround and definitive fix for it.

Debugging is a complex tasks.

Debugging uses various tools of analysis:

  • Log
  • Event log
  • Audit trail
  • Traces, with print_r(), var_dump(), debug_backtrace()
  • Debuggers, such as xdebug, php debugger, php-dbg.

Documentation

See Also

debug_backtrace()

debug_backtrace() is a PHP native function that generates a backtrace.

debug_backtrace() is used for inline debugging, or to collect more information before logging errors.

debug_backtrace() returns a dataset concerning the current situation of execution. It does not display anything: that function is either custom made, or devoted to debug_print_backtrace().

<?php

    function trumpet() {
        print_r(debug_backtrace());
        /**
        Array
(
    [0] => Array
        (
            [file] => /tmp.php
            [line] => 7
            [function] => trumpet
            [args] => Array
                (
                )

        )

)
*/
    }

    trumpet();

?>

Documentation

See Also

Debugger

A debugger is an extension or an external program that is used to help when searching for bugs or issues in source code. They provide extra visibility on the internal working of the application, including variable content.

As there are many tactics to search for a bug, there are many tools available.

The PHP ecosystem of debuggers includes:

  • PHP native functions such as var_dump(), print_r(), debug_backtrace()…
  • PHP external components like kint, whoops, krumo
  • Debuggers: interactive PHP Debugger, xdebug, PHP debugger, etc.

Debugging includes executing the code step by step, displaying and modifying the content of variables.

Debuggers are integrated into IDEs, or work as standalone applications.

<?php

    // simple debug system with native PHP print_r
    print_r($_GET);

?>

Documentation

See Also

decbin()

decbin() is a PHP native function that converts a decimal integer to its binary string representation.

decbin() takes a single integer argument and returns a string of 0 and 1 characters, without any 0b prefix. Negative numbers are converted using the 32-bit or 64-bit two’s complement representation, depending on the platform, which produces a long string of ones.

The reverse operation is bindec(), which converts a binary string back to a decimal number. Related functions convert to and from other bases: dechex() and hexdec() for hexadecimal, decoct() and octdec() for octal. base_convert() handles arbitrary bases.

<?php

    echo decbin(12);  // 1100
    echo decbin(26);  // 11010
    echo decbin(-1);  // 1111111111111111111111111111111111111111111111111111111111111111 (on 64-bit)

?>

Documentation

See Also

Declaration

A declaration is a statement that defines a structure, such as a function, a class, method, property, etc. A declaration must occur before the usage of the declared resource.

PHP requires a declaration for some structures, and allows its omission for others. For example, a class must be declared before usage, while a variable can be used without declaration. Properties are currently being moved to a compulsory declaration.

<?php

// cannot call a function before defining it
trumpet();

function trumpet() {}

class Elephpant {
    function forage() {
        // This is a warning since PHP 8.2, planned to be a fatal error in PHP 9.0
        $this->undeclaredProperty = 1;
        
        // $b is undefined. It creates a warning, but the code keeps executing.
        $a = $b + 1;
    }
}

?>

Documentation

See Also

Declarative Programming

Declarative programming is a programming style, where the goal of the task is described, but not the method to reach it. This is left to the source code to solve it in the way it sees fit.

Declarative programming is flexible in the way it expresses its requirements. It leaves room to optimization: as long as a step fulfills its mission, it may be used. On the other hand, several versions of the step may be created, with various optimisations. When several options are available, it requires a way to make a choice.

Documentation

See Also

declare Encoding

declare() with the encoding keyword specifies the encoding of the file that holds PHP script. This applies to the current file only. It affects both syntax, that PHP processes, and the literal values, which are ultimately displayed.

<?php

    declare(encoding='UTF-8');

?>

Documentation

See Also

declare()

declare()is used to set execution directives for a block of code.

declare() may set the following values:

  • strict_types: strict typing in the block
  • ticks: generate a tick event
  • encoding: per-file encoding directive

declare() affects some configuration for the next block of code.

It is a language construct.

<?php

    declare(strict_types=1, encoding='UTF-8');

?>

Documentation

See Also

Decode

To decode is to transform a piece of data, from a specialized format to a human readable one.

The conversion is lossless, and shall be reverted with an encode operation.

<?php

    // convert an array to a JSON string
    // This is also called 'encoding', and may be decoded
    $array = ['a' => 1];
    $json = json_encode($array);
    
    $original = json_decode($json);

?>

Documentation

See Also

Decorator Pattern

A decorator, or decoration, is a design pattern used to add behavior or responsibilities to objects dynamically, without altering their code. Decorators are often used to extend the functionality of classes or objects by wrapping them in additional classes that provide the desired functionality.

<?php

    interface Coffee {
        function cost();
    }
    
    class SimpleCoffee implements Coffee {
        public function cost() {
            return 5;
        }
    }
    
    class MilkDecorator implements Coffee {
        protected $coffee;
    
        public function __construct(Coffee $coffee) {
            $this->coffee = $coffee;
        }
    
        public function cost() {
            return $this->coffee->cost() + 2;
        }
    }

?>

Documentation

See Also

Decoupling

Decoupling refers to the software engineering concept where different parts of a system are made as independent from each other as possible. This means one component can change, be replaced, or fail without strongly affecting other components.

The opposite of decoupling is coupling.

Documentation

See Also

To Decrypt

To decrypt is to apply a data transformation on encrypted data to access the original and readable information. Usually, the transformation involves a key. That key may be public or private.

Decrypting data may be done after the transit of information, or its storage, in a database. In both case, privacy is critical.

The opposite to crypt is to crypt, when it is a legit operation. The evil equivalent to decrypt is to crack, when the secrets have been forced by any mean.

<?php

    // Encryption
    $key = openssl_random_pseudo_bytes(32); // 256-bit key
    $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
    
    $plaintext = 'PHP rocks';
    $ciphertext = openssl_encrypt($plaintext, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
    $encrypted = base64_encode($iv . $ciphertext);
    
    // Decryption
    $decoded = base64_decode($encrypted);
    $iv = substr($decoded, 0, openssl_cipher_iv_length('aes-256-cbc'));
    $ciphertext = substr($decoded, openssl_cipher_iv_length('aes-256-cbc'));
    $decrypted = openssl_decrypt($ciphertext, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
    
    echo 'Encrypted: ' . $encrypted . PHP_EOL;
    echo 'Decrypted: ' . $decrypted . PHP_EOL;

?>

Documentation

See Also

Deduplication

Deduplication is the process of detecting and discarding duplicate occurrences of an operation, message, or record. It ensures that even when the same input arrives more than once, it is processed only once.

Deduplication is related to, but distinct from, idempotency. An idempotent operation can safely be executed multiple times because repeated executions have no additional effect. Deduplication prevents the repeated execution from happening at all, typically by tracking a unique identifier and short-circuiting on a match.

In applications, deduplication is commonly applied to webhook deliveries, queue message processing, and form submissions, using a cache or database table to record seen identifiers within a retention window.

Documentation

See Also

Deep Clone

A deep clone is an object cloning, where the cloned object also clone its own object properties. This prevents the original object to share data with the cloned one, yet it is slower to process.

Deep cloning is achieved by using the __clone magic method. By default, PHP does shallow clones.

<?php

    class Dog {
        private $name = '';
        private Address $address;
    
        function __construct(string $name, Address $address) {
            $this->address->setName($address);
        }
        
        function moves(string $address) {
            $this->address->setName($address);
        }
    
        function __clone() {
            $this->address = clone $this->address;
        }
    }
    
    $spike = new Dog('Spike', new Address('Acme city'));
    $medor = clone $spike;
    $medor->moves('Upstate farm');
    
    // spike and medor do now share the same address

?>

Documentation

See Also

Default Parameter

Methods may define a default value for parameters. That way the parameter may be omitted during the call, and this value will be used.

The default value may be a static expression, and, since PHP 8.1, also includes a new expression.

The default parameter must be the last of the parameters: adding a parameter without default value after one will yield an error and mess up the call parameters.

<?php

function makeCoffee($type = 'latte') {
    return 'Making a cup of $latte';
}

?>

Documentation

See Also

Default Value

Default value is the value that a parameter or a property takes when it is used for the first time, and have not been provided.

Arguments and properties may have a default value. That way, arguments may be skipped when the method is being called, and the properties do not have to be initialized before usage.

Variable have a default value of null. Their initial assignment is considered a default value, as it replaces the null one.

<?php

    function trumpet($a = 1) {
        echo $a;
    }

    trumpet('one ');
    trumpet();
    
    // displays one 1

?>

Documentation

See Also

Default

default is a PHP keyword, used with switch() and match() structures. It represents any case that was not already considered.

In a switch() statement, default is optional, and may be placed anywhere among the case labels, though it is conventionally written last. It is only executed when none of the case values matches the tested expression, using loose comparison, ==. If a switch() has no default and no case matches, the statement simply does nothing, and execution continues after the block. Unlike case, default never needs a value, since it always matches by exclusion.

In a match() expression, introduced in version 8.0, default plays the same role, but the comparison uses strict equality ===, and a missing default combined with no matching arm throws an UnhandledMatchError at runtime, rather than doing nothing. Because match() is an expression, its default arm must also return a value, just like every other arm.

Static analysis tools often flag a switch() without a default case as a potential source of silently unhandled values, especially when the tested expression can later gain new possible values, such as an enum case or a class constant.

<?php

    switch ($i) {
        case 0:
            echo 'i equals 0';
            break;
        case 1:
            echo 'i equals 1';
            break;
        default:
            echo 'i is not 0 nor 1';
            break;
    }

?>

Documentation

See Also

default_charset

default_charset is the default value for the character encoding with htmlentities(), html_entity_decode() and htmlspecialchars(), when the encoding parameter is omitted.

It also defines the default character set for iconv and mbstring extensions, and for the Content-Type HTTP headers, when custom versions are not defined.

The value of default_charset must be a valid IANA character set name. Possible values include UTF-8, by default, ISO-8859-1, also known as Latin1, Windows-1252, ISO-8859-15, Shift_JIS, EUC-JP, GB2312, Big5. The charset is case-insensitive, so big5 and BIG5 and Big5 are all valid. An invalid charset defaults, again, to UTF-8.

Documentation

See Also

Defensive Programming

Defensive programming is a programming approach where the code is written assuming that things can go wrong, even when they shouldn’t, and it should actively guard against incorrect input, unexpected states, or misuse.

<?php

try {
    $number = random_int(0, 10);
} catch (Random\RandomException $e) {
    // This handle cases where no entropy sources are found 
    // This is very rare
}

?>

Documentation

See Also

Defer Statement

Go’s defer statement schedules a function call to run when the enclosing function returns, regardless of which return statement was reached or whether a panic is in flight: defer file.Close() right after opening a file guarantees the close happens at every exit path, without needing a finally block. Multiple deferred calls run in last-in-first-out order, and they can still read and modify the function’s named return values before it actually returns.

Unlike a try/finally block, defer is not tied to a lexical block: it can be scattered anywhere in the function body, right next to the resource acquisition it cleans up, rather than requiring the rest of the function to be wrapped in a block.

PHP has no defer statement. Guaranteed cleanup on every exit path is expressed with try/finally, which does require wrapping the relevant code in a block, or with a destructor __destruct() that runs when the object holding the resource is garbage-collected, which is not guaranteed to happen at a predictable point in the function’s execution.

<?php

    // No defer: cleanup must be wrapped, or moved into a destructor.
    function readConfig(string $path): array {
        $handle = fopen($path, 'r');
        try {
            return parse($handle);
        } finally {
            fclose($handle);
        }
    }

?>

Documentation

See Also

define()

define() is a PHP function that introduces global constant definitions.

define() is a function, and may be called anywhere. It is slower than const, as it is only executed at runtime. define() doesn’t allow the creation of class constants.

define() used to create case-insensitive constants, and this was abandoned in version 7.3.

define() cannot create class constants.

<?php
    define('HELLO', 'Hello');
    
    print HELLO . " world\n";
?>

Documentation

See Also

defined()

defined() checks if a constant or a class constant is defined in the current context of execution.

defined() is a function, and may be called on any piece of string. true is returned when the string is a valid name of a constant, and a value for it was found. Otherwise, it returns false, without error.

defined() doesn’t take into account the use const expressions: it should be a fully qualified constant name, or a relative one.

defined() is a native function.

<?php

    var_dump(defined('UNKNOWN'));         // false
    var_dump(defined('Not a constant'));  // false
    var_dump(defined('E_ALL'));           // true
    var_dump(defined('\E_ALL'));          // truet
    
    // use expression are not handled
    use const E_ALL as E;
    var_dump(defined('\E'));               // false

    // with class constants
    class E { const E = 1; }
    var_dump(defined('E'));                // false
    var_dump(defined('E::E'));             // true

    // do not confuse the constant and its value
    const F = 'E';
    var_dump(defined(F));                  // false

?>

Documentation

See Also

Definition

A definition is the description of a particular constant, function, method, property, class, trait, interface or enum.

A variable also has a definition, also called an initialisation: variables have no formal definition. They use an unconditional assignation to do so.

The definition is also called a declaration. The declaration must happen before usage.

Definitions happens in custom code, in libraries or in extensions.

There are functions dedicated to listing defined elements: get_declared_constants(), get_declared_traits(), get_declared_interfaces(), get_declared_classes(), get_class_vars() and get_class_methods().

<?php

    //function declaration
    function trumpet() {
        print 'OK';
    }

    // call to the function trumpet
    trumpet();

?>

Documentation

See Also

delayedtargetvalidation

The DelayedTargetValidation attribute is meant to make other PHP engine attributes optional. It will shut down complains from the PHP engine for attributes, allowing for future compatibility.

<?php
class Child extends Base {
    #[\DelayedTargetValidation]
        #[\Override]
        const NAME ='Child';
}
?>

Documentation

See Also

Delimiter

Delimiters are specific characters that start and end a specific area. They are used in structured datasets, to identify a special value among others.

Delimiters are a kind of separator: while separators are the boundary between two distinct values, delimiters frame them with a beginning and an end.

Delimiters may be the same at the beginning and the end. For example, single or double quotes for strings. Or the classic / for regexes, which may actually be any non-alpha-numeric character.

Delimiters may be different at the beginning and the end. For example, parentheses () and curly braces {}, or the PHP tags, <?php ?>.

Inside the structure, the delimiters are forbidden, to avoid confusing them with the actual limits of the data. If the delimiter characters are needed inside the structure, they may be escaped with another character, such as the backslash inside strings '\''; the delimiters may be replaced by another delimiter, such as in regex where a lot of delimiters are possible; they may also be deactivated with options, such as \Q and \E in regexes.

<?php

    // delimiters for strings
    echo '';
    
    // special options in regexes
    print preg_match('/^\Q'.$regex.'\E$/i', 'tests') ? 'match' : 'nomatch';

?>

Documentation

Dependency Injection Container

A dependency injection container is a tool to make dependency injection easy to use.

The application requests an object of class Foo to the container. The container then build any dependency for that object, then build that object and returns it.

PSR-11 is related to containers.

Documentation

See Also

Dependency Injection

Dependency injection, or DI, is a design pattern in which an object receives other objects that it depends on. Dependency injection is a design pattern where an object receives its dependencies from external sources rather than creating them internally. This promotes loose coupling, easier testing, and greater flexibility in code maintenance. By injecting dependencies, developers can swap implementations more easily, making systems more modular and adaptable to change.

<?php

    class MyObject {
        function __construct(private readonly Connection $database) {}
        
        function load(int $id): self {
            return $this->connection->select($id);
        }
    }

?>

Documentation

See Also

Dependency Inversion (DIP)

The Dependency Inversion Principle, or DIP, is the D in SOLID. It states: high-level modules should not depend on low-level modules; both should depend on abstractions. Abstractions should not depend on details; details should depend on abstractions.

In practice, this means a business-logic class should type-hint an interface, not a concrete implementation. The concrete class is injected from the outside, typically by a dependency injection container. The high-level class has no knowledge of which concrete class it will receive.

Dependency inversion has two effects: it decouples the high-level policy from low-level implementation details, and it makes the high-level class testable: a test can inject a mock or in-memory implementation instead of the real dependency.

Dependency inversion is often confused with dependency injection, or DI. DI is the mechanism for delivering the dependency; DIP is the principle that governs which direction the dependency arrow should point. You can have DI without DIP, but DIP requires DI, or a service locator, to be applied.

DIP is expressed through interfaces, abstract classes, and a DI container.

<?php

    // Violation: high-level class depends on a concrete low-level class
    class OrderService {
        private MySQLOrderRepository $repo; // concrete, tightly coupled
    
        public function place(array $data): Order {
            return $this->repo->save(Order::from($data));
        }
    }
    
    // DIP applied: both depend on an abstraction (interface)
    interface OrderRepository {
        public function save(Order $order): Order;
        public function findById(int $id): ?Order;
    }
    
    class OrderService {
        public function __construct(
            private OrderRepository $repo, // abstraction, no concrete dependency
        ) {}
    
        public function place(array $data): Order {
            return $this->repo->save(Order::from($data));
        }
    }
    
    // In tests: inject an in-memory implementation
    $service = new OrderService(new InMemoryOrderRepository());
    
    // In production: inject the real implementation via DI container
    // $container->bind(OrderRepository::class, MySQLOrderRepository::class);

?>

Documentation

See Also

Dependency

A dependency refers to something that the current source code relies on to function correctly. Dependencies can take many forms, depending on the context: it may be an external component, a PHP feature, resources such as memory or CPU, data or external services.

In the PHP world, dependencies often refers to components, and is related to composer.

Documentation

See Also

Dependent Type

A dependent type is a type whose definition depends on a value.

PHP does not support dependent type explicitly, though several situations behaves in a similar manner.

<?php

    print abs(-1); // 1, as integer
    print abs(-1.33); // 1.33, as float

?>

Documentation

See Also

Deployment

Deployment, sometimes misspelled deploiment, refers to the process of making a web application or website available for use on a server or hosting environment. It involves transferring the necessary files and configuring the environment to run the PHP code.

Documentation

See Also

Deprecated

Deprecated is a native PHP attribute. It marks a method, function or class constant as available, but soon to be removed.

The Deprecated attribute accepts an argument, that is shown to help users move to an alternative.

<?php

#[Deprecated]
function trumpet() {}

trumpet();
//Deprecated: Function trumpet() is deprecated

#[Deprecated('Use forage instead.')]
function trample() {}

trample();
//Deprecated: Function trample() is deprecated, Use forage instead.

?>

Documentation

See Also

Deprecation

Deprecation, or making a feature obsolete, is the state of a feature which is still available, but not recommended anymore. The next stage of life for the feature is the removal, usually in a major release.

<?php

1 ? 2 : 3 ? 4 : 5;   // deprecated in PHP 7.4, removed in PHP 8.0
(1 ? 2 : 3) ? 4 : 5; // ok

?>

Documentation

See Also

Depth-First Search

Depth-first search, or DFS, is an algorithm for traversing or searching a tree or graph that follows one branch as far down as it can go before backtracking and trying the next unexplored branch. Starting from a root node, it moves to an unvisited neighbor, then to one of that neighbor’s unvisited neighbors, and so on, only stepping back once it hits a node with no unvisited neighbor left.

DFS is naturally implemented with recursion, since each recursive call handles one node and calls itself on the next unvisited neighbor, or explicitly with a stack, pushing neighbors and popping the most recently pushed one first. This last-in-first-out order is what produces the deep, branch-by-branch traversal, in contrast with breadth-first search, which uses a queue and explores level by level.

DFS is used for tasks where the full extent of a branch matters more than distance from the start, such as detecting cycles in a graph, finding connected components, topological sorting of a dependency graph, or exhaustively walking a directory tree or an abstract syntax tree. Its memory usage is generally lower than BFS on wide graphs, since it only needs to remember the current path rather than an entire frontier of nodes.

<?php

    function dfs(array $graph, string $node, array &$visited = []): array {
        $visited[$node] = true;
        $order = [$node];

        foreach ($graph[$node] ?? [] as $neighbor) {
            if (!isset($visited[$neighbor])) {
                $order = [...$order, ...dfs($graph, $neighbor, $visited)];
            }
        }

        return $order;
    }

    $graph = [
        'A' => ['B', 'C'],
        'B' => ['A', 'D'],
        'C' => ['A', 'D'],
        'D' => ['B', 'C'],
    ];

    print_r(dfs($graph, 'A')); // ['A', 'B', 'D', 'C']

?>

Documentation

See Also

Depth

Depth is a measure of how many an operation has been repeatedly applies, over and over.

It applies to several concepts:

  • Multi-dimensional array depth: $array['d1']['d2']['d3']['d4']
  • Recursion depth: see example
  • Nested loop depth: number of loops inside a loop
  • Callstack depth: number of functions calling another one
  • Object inheritance depth: the maximum number of extension levels in a class hierarchy

Depth might be limited, when it is prevented from going beyond a certain level, or unlimited, when there is no such limit. For example, xdebug offers a directive called xdebug.max_nesting_level that limits nesting depth.

<?php

    // The recursion depth is limited to 5
    function trumpet($level = 0) {
        if ($level < 5) {
            return trumpet($level + 1);
        }
        return 1;
    }

?>

Documentation

See Also

Deque

A deque, short for double-ended queue, pronounced “deck”, is a linear data structure that generalizes both a stack and a queue by allowing elements to be inserted and removed efficiently, in constant time, from either end: the front and the back. Unlike a plain queue, which is restricted to FIFO access, inserting at one end and removing at the other, or a plain stack, which is restricted to LIFO access, inserting and removing at the same end, a deque supports all four basic operations: push front, push back, pop front, and pop back. This extra flexibility makes it a natural building block for algorithms that need both stack-like and queue-like behavior at once, such as sliding-window problems, undo and redo history, work-stealing task schedulers, palindrome checking, and breadth-first search variants that must inspect or remove elements from both ends of the frontier. A deque is provided by the Ds\Deque class from the Data Structures ds extension, which stores its elements in a resizable array buffer rather than a doubly linked list, giving amortized constant time for insertions and deletions at either end while also allowing constant time random access by index, capacity pre-allocation, and standard iteration through the Traversable interface.

<?php

    $deque = new \Ds\Deque();
    
    $deque->insert(0, e);             // [e]
    $deque->insert(1, f);             // [e, f]
    $deque->insert(2, g);             // [e, f, g]
    $deque->insert(0, a, b);        // [a, b, e, f, g]
    $deque->insert(2, ...[c, d]);   // [a, b, c, d, e, f, g]
    
    var_dump($deque);

?>

Documentation

See Also

Dereferencing

Dereferencing is the action to access a value, which is referenced with a pointer. Since PHP has no pointer, dereferencing applies to accessing an element in an array or an object.

Dereferencing is also possible to function and methods calls: when a function returns an array or an object, it is possible to immediately access one of the element by using the array or method syntax.

<?php

$array = ['a', 'b', 'c'];

echo $array['b'];

function trumpet() {
    return ['x', 'y', 'z'];
}

// Function Array Dereferencing
trumpet()[2]; // display z

?>

Documentation

See Also

Design Pattern

A design pattern, or simply a pattern, is a general solution to a common problem. Design patterns also get a name, for easy reference.

Common design patterns:

  • Factory
  • Dependency injection
  • Decorator
  • Module
  • Iterators
  • This list is not exhaustive…

Design patterns are not dedicated to PHP, though most of them do apply to PHP.

Documentation

See Also

Desktop Application

A desktop application runs natively on a user’s local operating system and has direct access to the file system, hardware, and system APIs. PHP is not traditionally used for desktop applications, but projects like NativePHP wrap a PHP runtime inside Electron or NativeApp to ship PHP code as a cross-platform desktop app. Desktop apps differ from web apps in that they do not require a browser or a remote server to function.

Documentation

Destructor

The destructor is a magic method in a class, which is called at shutdown of an object, in order to do any last minute cleaning. It is called __destruct.

Most of the time, the destructor is automatic: removing scalar values may be sufficient. In cases of resources, or other objects, it is recommended to issue the graceful commands to shut them down in turn.

Destructors are usually called after the end of the script, and has no access to any display, including stdout. As such, calls to echo are ineffective, and it is recommended to store the needed logs in another system.

<?php

class Elephpant {
    private $file;

    function __construct($path) {
        $this->file = fopen($path, 'w');
    }

    function __destruct() {
        fwrite($this->file, 'End');
        fclose($this->file);
    }
}

$elephpant = new Elephpant('/tmp/test.txt');
unset($elephpant);

?>

Documentation

See Also

Destructuring

Destructuring is a general programming concept where the individual elements of a compound value, such as an array, a list, or an object, are extracted in one step and bound to separate variables, instead of being accessed one at a time by index or property.

Many languages have dedicated destructuring syntax that also supports skipping elements, providing default values, capturing remaining elements, and destructuring nested structures in a single expression.

Destructuring is provided by list() and its short array syntax [ ] on the left side of an assignment, and by foreach() when iterating over arrays of arrays. PHP does not support destructuring of arbitrary objects, though list() may be combined with ArrayAccess-implementing objects.

<?php

    // array destructuring, PHP style
    [$a, $b, $c] = [1, 2, 3];

    // skipping an element
    [$first, , $third] = [1, 2, 3];

    // keyed destructuring
    ['name' => $name, 'age' => $age] = ['name' => 'Ann', 'age' => 30];

    // nested destructuring
    [[$trunk, $ivory], [$tusk]] = [[1, 2], [3]];

    // destructuring while iterating
    foreach ([[1, 2], [3, 4]] as [$left, $right]) {
        echo $left + $right, "\n";
    }

?>

Documentation

See Also

Determinism

A deterministic function or algorithm always produces the same output for the same input, regardless of when or how many times it is called. It has no side effects and does not rely on external or mutable state.

Determinism is relevant to caching strategies, testing, and the correctness of pure functions. Non-deterministic sources such as rand(), time(), microtime(), or global state break determinism and make functions harder to test and reason about.

Determinism is a core property of pure functions in functional programming and is closely related to idempotence.

<?php

    // deterministic: same input always yields same output
    function add(int $a, int $b): int {
        return $a + $b;
    }
    
    // non-deterministic: depends on current time
    function currentHour(): int {
        return (int) date('H');
    }

?>

Documentation

See Also

Deterministic

A deterministic function is a function that produces the same output, based on the same input.

strlen() is a deterministic function: it always returns the length of a string the same way.

time() is not a deterministic function: it always returns a different value, as time passes. rand(), time() are non-deterministic.

A function becomes non-deterministic when it relies on systems that may change between two calls. This is the case for files or database accesses.

Documentation

See Also

DevOps

DevOps, or development operations, is a set of cultural practices, tools, and methodologies that combine software development, the Dev part and IT operations, the Ops part, to shorten the systems development lifecycle and deliver high-quality software continuously.

Key DevOps practices relevant to PHP projects include:

  • Continuous Integration, CI: automatically building and testing code on every push
  • Continuous Deployment, CD: automatically deploying tested code to production
  • Infrastructure as Code, IaC: managing servers, containers, and services via version-controlled configuration files
  • Containerisation: packaging PHP applications in Docker containers for consistent environments.
  • Monitoring and observability: tracking application performance, errors, and uptime.
  • Automated testing: unit, integration, and end-to-end tests run in the pipeline.

Documentation

See Also

Dictionary

A dictionary is a data structure that holds a collection of values with a unique identifier. Each identifier is an integer or a string and may be other types in rarer occasions. The related values may be of any type.

A dictionary structure relies often on the array data structure.

<?php

$dictionary = ['a' => 'blue',
               'b' => 'pink',
               'c' => ['green', 'yellow'],
              ];

?>

Documentation

See Also

Diff

A diff is the textual difference between two versions of code. It represents the added, removed and modified lines.

Diffs are a staple of CVS systems. They are important when reviewing a PR, as they represent only the changed lines.

Diffs are used to identify modifications, although they fail at identifying exhaustively all impacts in the code.

Diff is also the name of the software that calculates the difference between two files.

A diff is not always unique: two files’ difference may be represented by two distinct diffs, or more.

Documentation

See Also

Digital Signature

A digital signature is a method to ensure that a message was sent by a specific recipient. It uses mathematical methods to combine the original message, plain text or not, with a private key, to produce a piece of data which may be verified later with the public key. Then, the pair of private key and public key gives a high level of confidence that the message was coming from the known sender.

PHP can sign data with openssl and sodium extensions.

A checksum can be considered a signature without a private key: it computes a short version of a file, and is difficult to reproduce without the original data. Any attempt at modifying the original data can then be detected, although the checksum itself has now to be trusted.

A signature is distinct from the sign of a number, + or -.

<?php

    function trumpet(string $message): string {

        // adapted from the PHP manual
        // fetch private key from file and ready it
        $pkeyid = openssl_pkey_get_private(file://src/openssl-0.9.6/php/sign/key.pem);

        // compute signature
        openssl_sign($message, $signature, $pkeyid);

        // free the key from memory
        openssl_free_key($pkeyid);        
        
        // This returns the signature of the message for 'php' user.
        // It may be checked with the public key
        return $signature;
    }

?>

Documentation

See Also

Dir

A directory, or dir, is a named collection of files on the file system.

A dir may also be called a folder.

There is a magic constant called __DIR__, which holds the current directory of the current file.

<?php

    $d = dir('/path/to/folder');
    while (false !== ($fileOrDir = $d->read())) {
       echo $fileOrDir.PHP_EOL;
    }
    $d->close();
    
    print_r(scanddir('/path/to/folder'));

?>

Documentation

See Also

Direct Output

Direct output is the characteristics of a function or method to write data directly to the output stream.

A good practice is to passe the output data to the calling context, for it to decide how to handle it.

Errors, exceptions, and debug often use direct output. Specific functions, such as echo, print_r, debug_print_backtrace() output directly on purpose.

Direct output is the root for the infamous Headers already sent error.

The alternative is to output to logs, or return the results.

Documentation

See Also

Directives

Directives are the configuration option of PHP. They may be set in the php.ini file, in HTTP server files like .htaccess, or accessed via the ini_get() and ini_set() native calls.

Directives are also set by PHP extensions or by PHP applications.

<?php

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

?>

Documentation

See Also

DIRECTORY_SEPARATOR

The DIRECTORY_SEPARATOR constant provides the character to distinguish one directory from the next, in a path.

DIRECTORY_SEPARATOR is / most of the time. On Windows, it may be \, although / is also valid at the same time, for compatibility reasons.

Using DIRECTORY_SEPARATOR to build paths or split a string into its components, means that the resulting data is valid on every underlying system.

<?php

    $path = 'folder' . DIRECTORY_SEPARATOR . 'subfolder' . DIRECTORY_SEPARATOR . 'file.txt';
    echo $path;

?>

Documentation

See Also

DirectoryIterator

The DirectoryIterator class provides a simple interface for viewing the contents of filesystem directories and files.

It is an iterator, and may be recursively traversed, like a file system.

<?php

    $iterator = new DirectoryIterator(__DIR__);
    while($iterator->valid()) {
        $file = $iterator->current();
        echo $iterator->key() . " => " . $file->getFilename() . "\n";
        $iterator->next();
    }

?>

Documentation

See Also

dirname

dirname() is the name of the path to a file.

In the path /var/www/index.php, the dirname is /var/www.

dirname() provides the dirname from a path, based on the / separator. It has to be combined with basename() to get the name of the directory, without its path.

Documentation

See Also

Disable Classes

This directive disables the provided list of classes in the php.ini.

Once disabled, the classes may be created again, via an extension or in the custom PHP code. Custom classes may still be created and used.

Documentation

See Also

Disable Functions

The disable_functions PHP directive prevents specific native functions from being executed when called from code. It helps mitigate potential security vulnerabilities or enforce practices by forbidding usage of specific functions, even when they are compiled into the engine.

This directive requires a list of PHP functions, separated by a comma, and set in the PHP.ini file: this is read at startup time and cannot be changed later.

disable_functions only works on native functions, and extension functions. It is not possible to preemptively disable a custom function: this may be achieved by defining the forbidden function, and assigning it a warning, or no operation.

A disabled function may be recreated as a custom function in the code.

Disabled functions appear as undefined: in fact, they can also be redefined, with a custom code and then used.

Documentation

See Also

Disable

To disable is to prevent a feature from performing. For example, using disable_functions=foo prevents the function foo from being available at the start of execution, even if PHP has a definition for it. The function foo cannot be run anymore, unless defined again.

Another example is memory_limit=-1, which sets the maximum memory used by a PHP application to -1, effectively disabling the control of the maximum amount of used memory.

Putting a piece of code in a comment is a way to disable it: it cannot be run anymore.

To disable implies a permanent state: it is different from a conditional statement.

Documentation

See Also

display_errors

display_errors configures the display of PHP errors, warnings and notices to the standard output. By default, it is on, with the value 1.

In production environments, it is recommended to set display_errors to 0. The error messages should be send to a logging system, for further exploitation. Otherwise, it is considered a data leak, and may lead to a vulnerability.

Documentation

See Also

Distributed Monolith

A distributed monolith is an anti-pattern where a system is deployed as multiple separate services but remains tightly coupled in practice, changes to one service still require coordinated changes to others, defeating the purpose of the distribution.

Common symptoms: shared database between services, synchronous call chains where all services must be available for any request to succeed, shared code libraries with business logic, deployment dependencies where service A must be deployed before service B, and a lack of independent scalability.

The distributed monolith combines the worst of both worlds: the operational complexity of microservices without the benefits.

The root cause is usually an attempt to split a monolith by technical layer, splitting into a frontend service and backend service, rather than by business capability. True microservices require domain-driven boundaries and decentralised data management.

<?php

    // Symptom: all services share one database, tight coupling at the data layer
    // Service A writes orders; Service B reads orders directly from the same schema.
    // A schema migration in Service A breaks Service B without any API change.
    
    // Symptom: synchronous chain, no service can fail independently
    // UserService -> OrderService -> PaymentService -> InventoryService
    // If Inventory is down, the entire chain fails, same as a monolith.
    
    // Correct approach: each service owns its data and communicates via events or APIs
    // Order placed -> event published -> Inventory consumes event independently

?>

Documentation

See Also

Distributed State

Distributed state refers to application state that is scattered across multiple, loosely-connected locations rather than being owned by a single, well-defined component.

Distributed state creates several detectable problems:

  • Implicit coupling: changing state in one file silently breaks another
  • Unpredictable execution order: the value depends on when code runs, not just what it does
  • Untestable code: a function cannot be tested in isolation if it reads global state
  • Hidden dependencies: the function signature lies. It looks pure but reads from $_SESSION or a static.
<?php

  //Global variables spread across files:
  $config = [];  // set in bootstrap.php
  // ... modified in module1.php, module2.php, read everywhere
  
  Static class properties shared across classes:
  class Auth { public static $user = null; }
  class Logger { /* reads Auth::$user */ }
  class Cart   { /* also reads Auth::$user */ }
  
  Superglobals ($_SESSION, $_COOKIE, $_SERVER) accessed everywhere:
  // session key 'cart' written in CartController, read in CheckoutController,
  // cleared in OrderController — no single owner
  $_SESSION['cart'][] = $item;

?>

Documentation

See Also

Distributed Systems

A distributed system is a collection of independent computers that appear to their users as a single coherent system. Components run on separate nodes, communicate via a network, and coordinate to achieve a common goal.

Distributed systems introduce a class of problems absent in single-process applications: partial failures where one node fails while others continue, network partitions where nodes cannot communicate, clock skew where no shared global time exists, and concurrency across nodes.

The CAP theorem states that a distributed system can guarantee at most two of three properties simultaneously: consistency or all nodes see the same data, availability or every request gets a response, and partition tolerance or the system continues despite network splits. Real networks always partition, so the practical choice is between CP consistency over availability and AP availability over consistency, i.e., eventual consistency.

Distributed systems arise in microservices, multi-region deployments, distributed caches, such as Redis Cluster, Memcached, and queue-based architectures.

<?php

    // PHP interacts with distributed systems through clients:
    
    // Redis Cluster — distributed key-value store
    $redis = new Redis();
    $redis->connect('redis-cluster.internal', 6379);
    $redis->set('session:abc', json_encode($sessionData), 3600);
    
    // RabbitMQ / SQS — distributed message passing
    $channel->basic_publish(
        new AMQPMessage(json_encode($payload)),
        exchange: '',
        routingKey: 'orders',
    );
    
    // HTTP service call — network may fail, retry with backoff
    $response = $httpClient->request('POST', 'https://payments.internal/charge', [
        'json'    => $payload,
        'timeout' => 3.0,
    ]);

?>

Documentation

See Also

Distributed Tracing

Distributed tracing, or a distributed trace, tracks a single request as it flows through multiple services in a distributed system. Each service records a span and propagates a trace context to downstream services via HTTP headers or message metadata. All spans sharing the same trace ID are assembled into a trace: a complete picture of the request’s journey.

Without distributed tracing, debugging latency or errors in a microservices system means correlating logs across dozens of services manually. Distributed tracing provides a visual timeline, the waterfall diagram, showing which service took how long, where errors occurred, and how services depend on each other.

The W3C Trace Context standard, the traceparent header, defines the propagation format. OpenTelemetry is the vendor-neutral SDK and API for instrumenting PHP applications with OpenTelemetry tracing. Jaeger and Zipkin are common open-source backends; commercial alternatives include Datadog APM, New Relic, and Honeycomb.

OpenTelemetry provides a native SDK for manual and automatic instrumentation. The ext-opentelemetry extension enables zero-code instrumentation for frameworks and HTTP clients.

<?php

    use OpenTelemetry\API\Globals;
    
    // Manual span creation
    $tracer = Globals::tracerProvider()->getTracer('order-service');
    
    $span = $tracer->spanBuilder('place-order')->startSpan();
    $scope = $span->activate();
    
    try {
        $order = $orderService->place($data);
        $span->setAttribute('order.id', $order->id);
    } catch (\Throwable $e) {
        $span->recordException($e);
        $span->setStatus(\OpenTelemetry\API\Trace\StatusCode::STATUS_ERROR);
        throw $e;
    } finally {
        $scope->detach();
        $span->end();
    }
    
    // The traceparent header is propagated automatically by the SDK
    // when making outbound HTTP calls via PSR-18 clients with the OTel middleware.

?>

Documentation

See Also

Distributed Transactions

A distributed transaction is a transaction that spans multiple independent data stores or services, requiring all participants to agree on the outcome. This means all commit or all abort.

The classic protocol is Two-Phase Commit, 2PC: a coordinator sends a PREPARE request to all participants; if all reply OK, the coordinator sends COMMIT; otherwise it sends ROLLBACK. 2PC is blocking: if the coordinator crashes after PREPARE, participants may be locked indefinitely.

In microservices, distributed transactions are largely avoided because they require all participating services to be available simultaneously, undermining the independence and fault isolation that microservices are designed to provide.

The preferred alternative is the Saga pattern: a long-running business process is decomposed into a sequence of local transactions, each publishing an event. If a step fails, a compensation transaction undoes the previous steps.

PHP applications typically avoid distributed transactions by using a single database, or by embracing eventual consistency and the Saga pattern in microservices contexts.

<?php

    // Saga pattern: choreography-based (event-driven)
    // Each service handles its local transaction and publishes an event.
    // No central coordinator — services react to each other's events.
    
    // 1. OrderService places order and publishes OrderPlaced
    $order = Order::place($data);
    $orderRepository->save($order);
    $eventBus->publish(new OrderPlaced($order->id, $order->total));
    
    // 2. PaymentService listens for OrderPlaced, charges the card
    //    On success: publishes PaymentProcessed
    //    On failure: publishes PaymentFailed -> OrderService compensates (cancels order)
    
    // 3. InventoryService listens for PaymentProcessed, reserves stock
    //    On failure: publishes StockUnavailable -> PaymentService compensates (refund)

?>

Documentation

See Also

Distributed

When something is distributed, it is spread across several autonomous instances, though it is reputed working as one.

The independent servers pass messages among each other, in order to be synchronised.

There are distributed transactions over multiple SQL server; distributed sessions, over multiple web server; etc.

Documentation

See Also

Division

Division is the mathematical division. It applies to numbers: integers and float.

It also works with booleans and null, which are converted to integers. Other types are not allowed for division and yield a fatal error.

Division may be resulting in an integer or a float, whatever the type of the initial operands. PHP produces integers whenever possible.

Division by zero, or by any value that is cast to 0, leads to a DivisionByZeroError.

The operator for division is the slash /. The backslash \ is used for namespaces.

There is a function for the integer division: intdiv(); and % for the modulo operator, aka the remaining.

<?php

$a = 10 / 2.5; // 4.0

?>

Documentation

See Also

DivisionByZeroError

The DivisionByZeroError exception is thrown when an attempt is made to divide a number by zero. It is never possible to divide by zero, the result is undefined. It is true for all zeroes: 0, +0, -0.

<?php

    try {
        echo 1 / $a;
    } catch(DivisionByZeroError $e){
        echo 'Trying to divide by 0';
    }

?>

Documentation

See Also

Disjunctive Normal Form (DNF)

DNF stands for Disjunctive Normal Form. It is a standard form used in propositional logic and Boolean algebra. DNF represents logical expressions as a disjunction OR of one or more conjunctions AND of literals. In simpler terms, it is a way to express logical statements using only the logical operators OR and AND.

The DNF form allows for the representation of any logical expression using a combination of OR and AND operators. It is particularly useful in logic analysis, theorem proving, and boolean circuit design.

<?php

    class Elephpant {
        private (A&B)|(C&D) $trunk;
    }

?>

Documentation

See Also

Domain Name System (DNS)

Domain Name System, or DNS, is the internet’s equivalent of a phone book, translating human-readable domain names, like php.net into machine-readable IP addresses, 172.217.3.110.

DNS is essential for the functioning of the internet, as it allows users to access websites and services using easy-to-remember names instead of complex numerical addresses.

DNS requires the configuration of various records, with different types: A, AAAA, CNAME, MX, TXT.

Documentation

See Also

Do While

Do While is a loop structure. It runs the block of code until the condition is not met anymore. The block is run once before the condition is checked, so it is always run at least once.

Part of the block execution may be skipped by using the continue keyword.

<?php

    $i = 1;
    do {
        print "$i\n";
    } while($i < 10);

?>

Documentation

See Also

Docblock

A docblock, or docblock comment, is a special kind of comment used to document any structure: classes, constants, traits, interfaces, variables, functions, methods, and properties. It is written in a specific format and is typically placed just before the element it describes. Docblocks are used by tools like phpDocumentor, PHPDoc, and IDEs to generate documentation and provide code hints.

Docblocks improve readability, enable IDE features, and automate reference documentation generation.

<?php

/**
 * A brief description of the function.
 *
 * A more detailed description, if needed.
 *
 * @param type $parameter_name Description of the parameter
 * @return type Description of the return value
 */
function exampleFunction($parameter_name) {
    // Function code here
    return $result;
}

?>

Documentation

See Also

Docker Container

A Docker container is a lightweight, standalone, executable unit of software that packages code and all its dependencies, like libraries, system tools, runtime, settings, so that the application runs quickly and reliably across different computing environments.

Documentation

See Also

Docker Image

A Docker image is a read-only template used to create Docker containers. It bundles the application code, runtime, libraries, environment variables, and configuration files needed to run an application.

Images are built from a Dockerfile and are composed of stacked, immutable layers. Each instruction in the Dockerfile adds a new layer; unchanged layers are cached and reused to speed up builds.

Official PHP images are available on Docker Hub in several variants: cli, fpm, apache, and zts, each based on Debian or Alpine Linux.

Documentation

See Also

Docker

Docker is an open platform for developing, shipping, and running applications inside isolated containers. It packages an application and all its dependencies into a self-contained unit that can run consistently on any host.

In the PHP ecosystem, Docker is widely used to standardise development environments, run PHP applications in production, and manage services such as web servers, databases, and caches.

Docker relies on images as blueprints and containers as running instances of those images. Images are distributed through registries such as Docker Hub, which hosts the official PHP images.

Documentation

See Also

Doctrine

Doctrine is a set of PHP libraries built around persistence and object-relational mapping. Its two flagship projects are Doctrine DBAL, a database abstraction layer providing one API over multiple database engines, and Doctrine ORM, built on top of DBAL, which maps PHP objects to database rows and back using the Data Mapper pattern, rather than Active Record, so entities stay ignorant of how they are persisted.

Doctrine ORM uses annotations, or attributes since PHP 8, or XML/YAML mapping files, to describe how a class’s properties map to a table’s columns. It tracks changes to managed entities through a Unit of Work, and only issues the SQL statements needed to persist them once flush() is called, instead of after every individual change.

Doctrine also ships companion libraries: Doctrine Migrations, to version and apply schema changes, and Doctrine Collections and Doctrine Inflector, both used well beyond the ORM itself. It is the default persistence layer of Symfony, and one of the most widely used ORMs in the PHP ecosystem, alongside Eloquent and Propel.

<?php

    // Doctrine ORM: entities are persisted through a Unit of Work
    $user = new User();
    $user->setName('Alice');

    $entityManager->persist($user); // schedules the insert
    $entityManager->flush();        // issues the actual SQL

?>

Documentation

See Also

Document Database

A document database, also called a document store, is a type of NoSQL database that stores data as semi-structured documents, typically in JSON, BSON, or XML format. Each document is a self-contained record with a flexible schema, unlike the fixed rows and columns of relational databases.

Common document databases used with PHP include MongoDB and CouchDB. PHP drivers and libraries such as the official MongoDB extension or Doctrine ODM provide integration.

Document databases are well suited to hierarchical or varying-structure data, but lack the relational joins and strict consistency guarantees of SQL databases.

<?php

    // MongoDB PHP driver example
    $client = new MongoDB\Client('mongodb://localhost:27017');
    $collection = $client->mydb->users;
    
    $collection->insertOne([
        'name'  => 'Alice',
        'email' => 'alice@example.com',
        'roles' => ['admin', 'editor'],
    ]);
    
    $user = $collection->findOne(['name' => 'Alice']);
    echo $user['email'];

?>

Documentation

See Also

Documentation

Documentation refers to the written material that describes a software project, its components, functionality, architecture, and usage. It serves as a reference guide for developers, testers, and users, ensuring clarity, consistency, and maintainability of the software.

Documentation may be categorized in four groups: tutorials, how-to guides, technical reference and explanation.

The PHP documentation is also called the PHP Manual. It is a reference documentation.

Documentation

See Also

Dog Fooding

Dog fooding, or eating your own dog food, is the practice of an organisation using its own product internally, in production conditions, instead of relying only on artificial tests.

Dog fooding surfaces usability issues, missing features, and bugs that would otherwise only be found by external users. It also builds confidence in the product, since the team relies on it for its own work.

For example, the PHP website is written with the PHP language.

Documentation

See Also

Dollar $

$ is character, used in various situations:

  • As the first character of a variable
  • As an operator, for variable variables.

When associated, PHP and $ often leads to the conversion rate of dollars to Philippine Pesos.

<?php

$a = 'b';
$b = 'c';

echo $$a; // 'c'

echo $\{$a}; // C

?>

Documentation

See Also

Document Object Model (DOM)

The Document Object Model, also called DOM, is a programming interface for HTML and XML documents. It represents the document as a tree of nodes that can be traversed, queried, and modified.

PHP provides the dom extension, which implements the W3C DOM specification via classes such as DOMDocument, DOMElement, DOMNode, DOMXPath, and DOMNodeList.

PHP 8.4 introduced Dom\HTMLDocument and Dom\XMLDocument as improved, spec-compliant replacements for the legacy DOMDocument, with better error handling and HTML5 parsing.

<?php

    $doc = new DOMDocument();
    $doc->loadHTML('<p class="greeting">Hello, <strong>world</strong></p>');
    
    $xpath = new DOMXPath($doc);
    $nodes = $xpath->query('//p[@class="greeting"]/strong');
    
    foreach ($nodes as $node) {
        echo $node->textContent; // world
    }

?>

Documentation

See Also

Domain Name

A domain name is a human-readable label that identifies a network resource, such as a web server. It is mapped to an IP address through the Domain Name System DNS.

Domain names appear in URLs, are parsed with parse_url(), and validated with the filter extension using FILTER_VALIDATE_DOMAIN.

<?php

    $host = parse_url('https://www.example.com/path', PHP_URL_HOST);
    // $host = 'www.example.com'
    
    $isValid = filter_var('example.com', FILTER_VALIDATE_DOMAIN);

?>

Documentation

See Also

Domain

In software development, a domain is a sphere of knowledge or activity that a system is designed to model. Domain-Driven Design, DDD, organises code around domains, using domain models to represent business concepts faithfully.

A domain is the core subject of the application: e-commerce, banking, healthcare, etc. The domain model captures the rules, entities, and behaviours that belong to that subject.

Documentation

See Also

DomainException

Exception thrown if a value does not adhere to a defined valid data domain. For example, it might be an invalid value for a class property and not its type.

<?php
function renderImage($imageResource, $imageType)
{
  switch ($imageType) {
  case 'jpg':
  case 'jpeg':
    header('Content-type: image/jpeg');
    imagejpeg($imageResource);
    break;
  case 'png':
    header('Content-type: image/png');
    imagepng($imageResource);
    break;
  default:
    throw new DomainException('Unknown image type: ' . $imageType);
    break;
  }
  imagedestroy($imageResource);
}
?>

Documentation

See Also

DOMChildNode

DOMChildNode is an interface introduced in version 8.0 for DOM nodes that can have siblings. It is implemented by DOMElement, DOMText, DOMComment, DOMProcessingInstruction, and DOMDocumentType.

It provides before() and after() to insert nodes adjacent to the current node, replaceWith() to replace it, and remove() to detach it from its parent.

<?php

    $dom = new DOMDocument;
    $dom->loadHTML('<p>Hello <b>world</b></p>');
    $b = $dom->getElementsByTagName('b')->item(0);
    $b->remove();

?>

Documentation

See Also

DOMParentNode

DOMParentNode is an interface introduced in version 8.0 for DOM nodes that can have children. It is implemented by DOMDocument, DOMElement, and DOMDocumentFragment.

It provides prepend() and append() methods to insert nodes as first or last children, and childElementCount, firstElementChild, lastElementChild properties.

<?php

    $dom = new DOMDocument;
    $dom->loadHTML('<p>Hello</p>');
    $p = $dom->getElementsByTagName('p')->item(0);
    $p->append($dom->createTextNode(' world'));

?>

Documentation

See Also

DOM

The DOM extension is an extension that allows developers to work with XML documents using the Document Object Model, DOM, API. It provides a set of classes and functions to parse, manipulate, and generate XML documents.

The DOM extension provides a tree-based representation of an XML document, where each element, attribute, and text node is represented as an object. This allows developers to traverse and manipulate the XML document easily.

<?php

// from PHP manual : https://www.php.net/manual/en/class.domcomment.php

   $xml = new DOMDocument();
    $xml->loadXML('<?xml version=\1.0\ encoding=\utf-8\?>
      <configuration version=\2\>
      <!-- test &#45;&#45;&gt; -->
      test &#45;&#45;&gt;
      </configuration>'
    );
$xpath = new DOMXPath($xml);
$comments = $xpath->query('//comment()');
$elements = $xpath->query('//configuration');

echo $comments[0]->textContent;
// result: test &#45;&#45;&gt;

echo $elements[0]->textContent;
// result: test -->

?>

Documentation

See Also

. Directory

The . directory represents the current directory. It is useful to designate the current directory, and apply an operation on all the files in that directory. It is also used in php.ini directives, to indicate a path relative to the current directory.

<?php

    // lists of the files in the current directory
    $files = glob('./*.php');

?>

Documentation

See Also

Dot-dot Directory ..

The .. directory represents the parent directory of the current one. This directory always exists, at the root directory, aka /, which is also its own parent.

<?php

    // lists of the files in the parent directory
    $files = glob('../*.php');

?>

Documentation

See Also

. File

The . files are files whose name start with a dot. By convention, they are considered hidden files, and are not listed when scanning a directory. Otherwise, they may be files or directories: .env, .ssh, .git, etc.

<?php

    // files
    $files = glob('./*');

    // hidden files
    $files = glob('./.*');

?>

Documentation

See Also

Dot Notation

The dot notation refers to a syntax to access deeply-nested elements in arrays. Instead of repeating the classic [index] notation, dot notation offers a way to chain the indices with dots to reach the value.

Dot notation is easier to read, in particular when there are numerous elements.

Dot notation is not a PHP native feature. It is available via independent packages or as a feature of frameworks.

<?php

    // example from https://github.com/adbario/php-dot-notation
    
    $array['info']['home']['address'] = 'Kings Square';
    
    echo $array['info']['home']['address'];
    
    // Kings Square
    
    $dot->set('info.home.address', 'Kings Square');
    
    echo $dot->get('info.home.address');

?>

Documentation

See Also

Double Arrow

The double arrow is the PHP token =>. It is an arrow, and the equal sign as body of the arrow gives it its name of double arrow.

The double arrow is used in several situations:

  • With arrow functions: fn($a) => $a + 1;
  • In arrays, to distinguish the key from the value: ['a' => 3]
  • In list, to distinguish the key from the value: ['a' => $b] = ['a' => 4]
  • In yield, to distinguish the key from the value: yield 'a' => $b;
  • In property hooks, to start the body of the hook: private $p { get => $this->p; }

=> has no relationship with <=, which is a comparison operator, nor with ->, which is the object operator.

<?php

    $array = ['a' => 3, 3];

?>

Documentation

See Also

Double Check

A double check happens when the same characteristics is checked twice.

Double check evolve naturally from code that does not take into account the entire system it is residing in.

Double check may be explicit, or implicit. The explicit are plainly written in the code, while implicit double check requires context knowledge.

Double checks are a feature of defensive programming, where everything is checked as needed, to ensure that a previous omission does not go unchecked, even at the cost of effort duplication.

<?php

// This condition is a double check with the one inside the function trumpet()
// This doublecheck uses 2 identical conditions, with different syntax
if ($j >= 0) {
    trumpet($j);
}

function trumpet(int $i): ?int {
    if ($i < 0) {
        return null;
    }
    
    return $i + 1;
}

// Foreach() checks for $items to be empty, and skips itself in that case.
// the empty() check is duplicate
if (!empty($items)) {
    foreach ($items as $item) {
        doSomething();
    }
}

?>

Documentation

See Also

Double Quotes Strings

Double quoted strings are strings, similar to the single quoted strings. They are also able to interpolate variables, properties and arrays, which are included at execution time.

Double quoted strings do not interpolate constants.

Double quoted strings support escape sequences, such as u{1F3c} or \n.

This is an extended version of the single-quoted strings. They are similar to the heredoc syntax.

<?php

    // single quoted string : all literal values
    $name = 'Elephpant loves $signs.'; 
    
    // single quoted string : all literal values
    $signs = 'PHP';
    $name = 'Elephpant loves $signs.';  // Elephpant loves PHP
    
    echo "\u{01f418}"; // escape sequence of an elephant

?>

Documentation

See Also

Double

Double usually means that something is repeated once.

Double is opposed to single, but it may also be distinct with any other number of repetition, such as triple, quadruple, etc.

Things that may be double:

  • Double quotes "
  • Double equal ==, not to be confused with the single equal = or the triple one ===
  • Double colon ::, the static resolution operator
  • Double plus ++ and minus --, also called plus plus or minus minus, as post-increment and pre-increment operators
  • Double star **, or exponentiation operator
  • Double question mark ??, or coalesce operator
  • Double also refers to float or decimal point numbers.
<?php

    $a = 1;
    $a == 1;  // true 
    $a === 1; // true too. 

?>

Documentation

See Also

Downtime

Downtime represents periods where a service is not available.

Downtime may be unexpected, such as a bug, an attack on the server, or an unforeseen situation. It may be planned, such as a maintenance upgrade.

Documentation

See Also

Drop-in

A drop-in replacement is a library or a component which replaces entirely a previous one. It may add new features, but it does not break anything that was previously working.

Documentation

See Also

Don’t Repeat Yourself (DRY)

Don’t repeat yourself, or DRY, is a principle of software development aimed at reducing repetition of software patterns.

The concept was coined in Andy Hunt and Dave Thomas’s book The Pragmatic Programmer, in 1999.

This principle is also known as Duplication Is Evil, or DIE. Its nemesis is WET. It means write everything twice.

Documentation

See Also

Data Structure

Data Structures, is a PHP extension which provides efficient data structures, provided as an alternative to the array. It is available since PHP 7.

In particular, it provides the following structures:

  • Collection
  • Sequence
  • Vector
  • Deque
  • Map
  • Pair
  • Set
  • Stack
  • Queue
  • PriorityQueue.
<?php

    $stack = [];
    $stack[] = first;
    $stack[] = second;
    // same as array_push($stack, second);
    
    echo array_pop($stack); // Outputs: second

?>

Documentation

See Also

Data Source Name (DSN)

A DSN is a string that describes a database location and access.

The format of a DSN is usually specified by the target database. For example:

  • MySQL: ‘mysql:host=localhost;dbname=test’
  • Oracle: ‘oci:dbname=//localhost:1521/mydb’
  • PostgreSQL: ‘pgsql:host=localhost;port=5432;dbname=testdb;user=bruce;password=mypass’
  • SQLite: ‘sqlite:/opt/databases/mydb.sq3’

DSN is closely related to the PDO extension.

<?php

    $dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);

?>

Documentation

See Also

Data Transfer Object (DTO)

DTO stands for Data Transfer Object: it is an object that carries data between methods and different part of the architecture.

DTO is a class, with only properties. It replaces advantageously arrays. It may be used for typing, and do not hold methods.

DTO are easily confused with Value Object: the first one’s role is to carry data inside the application, the second one holds data, and can only be compared by its values.

Documentation

See Also

Duck Typing

In duck typing, an object is of a given type if it has all methods and properties required by that type.

It is described by this sentence: ‘If it walks like a duck and it quacks like a duck, then it must be a duck’.

This may apply to a class that offers a set of methods, that are listed in an interface, but the class doesn’t implement explicitly that interface.

<?php

    interface Trumpets {
        function trumpet() ;
    }

    // class Elephpant doesn't implement Trumpets, yet it is of type Trumpets because it implements trumpet()
    class Elephpant {
        function trumpet() {}
        function forage() {}
    }

?>

Documentation

See Also

Duplicate

There are things that PHP does not accept as duplicate:

  • Duplicate type %s is redundant
  • Duplicate named parameter $%s
  • Duplicate value in enum %s for cases %s and %s
  • Duplicate declaration of static variable $%s.

Documentation

See Also

Dynamic Call

A dynamic call happens when part of the syntax comes from a variable, and is not known at code writing time.

PHP allows every syntax to be used as a dynamic call.

<?php

    $constant = 'Name';
    echo constant($constant); 
    echo constant("someClass::$constant"); 
    
    $variable = 'a';
    $a = 'b';
    echo $$variable; // b
    
    $function = 'mine';
    $function($arg);
    
    $className = '\stdclass';
    new $className;
    
    $method = 'method';
    $object->$method();
    
    echo $object::CONSTANT;

?>

Documentation

See Also

Dynamic Class Constant

Dynamic class constant access has always been possible with a call to the constant() function. With the class::constant syntax, it is possible to reach any visible constant, or, also, enumeration cases.

A new syntax is available since version 8.3 to do the same: class::{$name}. The curly braces are important in that call.

<?php

    enum E: string {
        case A = 'abc';
        const B = 'def';
    }
    
    $name = 'E::A';
    echo constant($name)->value;
    // PHP 8.3+ 
    echo E::{$name}->value;
    
    $name = 'E::B';
    echo constant($name);
    // PHP 8.3+ 
    echo E::{$name};

?>

Documentation

See Also

Dynamic Class

A dynamic class is a class whose fully qualified name is defined at execution time.

This is convenient for module systems, where the actual class is named from an external configuration.

The name of the class is a string. It may be also accessed with the ::class operator.

For a dynamic call, the name of the class may or may not start with a \ char: both cases work.

Dynamic class may be used with static calls, class constants, enum cases, static method or static property. Here, the call is static, as it actually does not depends on the object, but on the class of the object.

It may also be used with the instantiation operator new.

It is also possible to use an object of the same class for all these calls.

<?php

    class AB {}
    
    class AC {}
    
    $name = '\A'.(rand(0, 1) ? 'B' : 'C');
    
    $object = new $name;    // creates a class of AB or AC
    $object2 = new $object; // creates another object of AB or AC, same as $object

?>

Documentation

See Also

Dynamic Constant

A constant is dynamic when its name is in a variable, or another container, and is accessed at execution time.

Reaching a constant’s value is done by using the constant() function, or the dynamic constant fetch with classes.

Sometimes, dynamic constants are also called variable constants.

<?php

    const A = 1;
    // simple case
    $a = 'A';
    echo constant($a); // displays 1
    
    // with leading backslash
    $b = '\A';
    echo constant($b); // displays 1
    
    // definition has no leading backslash
    define('B\C', d);
    // reading has no leading backslash, or not
    $c = '\b\C';
    echo constant($c); // displays d
    $c = 'b\C';
    echo constant($c); // displays d
    
    // constant() works also on class constants.
    class D {
        const E = 'f';
    }
    echo constant('d::E'); // displays f
    
    // dynamic constant access on classes or enumeration
    $k = 'E';
    echo D::{$k}; // f
    
    // constant works also on enumeration cases
    enum I: string {
        case G = 'h';
    }
    echo constant('I::G')->value; // displays h
    
    // dynamic constant access on classes or enumeration
    $g = 'G';
    echo I::{$g}->value; // h

?>

Documentation

See Also

Dynamic Expression

A dynamic expression is an expression that is only wholly defined at execution time. It needs to collect pieces of information before processing. This applies to elements that are usually static, such as class, function, method, constants, not to parameters which are expected to be variable.

<?php

    $config = new ConfigFile();

    $function = $config->sortingMethod; // sort, or rsort
    $function($array);

?>

Documentation

See Also

Dynamic Loading

Dynamic Loading is related to the loading of PHP extensions, at execution time.

Most of the time, the extensions are compiled with PHP, and loaded at startup. For development purposes, or for distribution purposes, some libraries may be loaded at execution time, with the dl() function.

dl() calls are considered bad for performances and for security.

<?php

    // add extra features to PHP
    dl('ldap.so');

?>

Documentation

See Also

Dynamic Method

A dynamic method is a method which is defined at execution time.

This is convenient for module systems or SOAP clients, where the actual methods are defined at the remote server.

PHP calls this overloading.

<?php

    class Elephpant {
        function __call($name, $args) {
            if ($name === 'trumpet') {
                echo 'OK';
                return;
            }
    
            if ($name === 'forage') {
                echo 'OK';
                return;
            }
    
            echo 'KO';
        }
    }
    
    $elephpant = new Elephpant;
    $elephpant->trumpet(); // OK
    $elephpant->forage(); // OK
    $elephpant->fly(); // KO

?>

Documentation

See Also

Dynamic Properties

Dynamic properties are properties created on the fly, without previous definition.

When the class implements the magic methods __get() and __set(), of if the class extends stdClass, then no warning is emitted.

<?php

    class Elephpant {
        private $property = 1;

        function trumpet() {
            // dynamic property
            $this->a = 1;
            
            // dynamic property with variable name 
            $b = 'abc';
            $this->$b = 1; 
            
            // static property
            $this->property = 1;
        }
    }

?>

Documentation

See Also

Dynamic Variable

A dynamic variable is a variable whose name stored in a variable or an expression.

They are identified by a double $ sign, though the same operator may be used multiple times.

They are also called variable variable.

<?php

    $a = 'b';
    $b = 'c';
    $c = 'd';
    
    echo $$$a; 
    echo $$b; 
    echo $c; 

?>

Documentation

See Also

Dynamic

Dynamic is a common concept, and may be used in three distinct situations:

  • Dynamic call, to call a function or method whose name is in a variable
  • Dynamic constant, to call a constant whose name is in a variable
  • Dynamic property, to access a property whose name is in a variable
  • Dynamic loading, for PHP to load an extension after the start of execution
  • Dynamic variable, to access a variable whose name is in another variable.
<?php

    // Dynamic call of a variable
    $a = K;
    $tusk = 'a';
    echo $$tusk; // K
    
    const A = 1;
    $name = 'A';
    echo constant($name); // 1

?>

Documentation

See Also

E

The letter e, or E, plays several distinct roles:

  • Floating number format: e is used as part of a float literal to denote a power of 10. 1.5e3 means 1.5 × 10³ = 1500, and 7E-10 means 7 × 10⁻¹⁰. The letter is case-insensitive in this context. It is not an operator; it is part of the numeric syntax
  • Exponential constant: M_E is a PHP predefined math constant equal to Euler’s number e ≈ 2.718281828459045. It is the base of the natural logarithm, and satisfies log(M_E) === 1. The function exp(1) also returns this value, although floating-point rounding means exp(1) === M_E may evaluate to false
  • Euler constant: M_EULER is a distinct PHP constant, equal to the Euler constant γ ≈ 0.5772156649015329. It is also called Euler-Mascheroni, or gamma. It should not be confused with M_E
  • Error constant prefix: all PHP error level constants start with E_: E_ERROR, E_WARNING, E_NOTICE, E_DEPRECATED, E_ALL, and others. They are used with error_reporting() and combined with bitwise operators
  • Escape sequence for escape character: in double-quoted strings and heredocs, \e is the escape sequence for the ESC character, ASCII 27, 0x1B. It is used in ANSI terminal escape codes.
<?php

    // e in float scientific notation
    $a = 1.5e3;   // 1500.0
    $b = 7E-10;   // 0.0000000007
    $c = 1e308;   // close to PHP_FLOAT_MAX

    // M_E : Euler's number
    echo M_E;             // 2.718281828459
    echo exp(1);          // 2.718281828459
    echo log(M_E);        // 1

    // M_EULER : Euler-Mascheroni constant (different from M_E)
    echo M_EULER;         // 0.57721566490153

    // E_ error level constants
    error_reporting(E_ALL);
    error_reporting(E_ERROR | E_WARNING);

    // \e escape sequence : ESC character for ANSI terminal codes
    echo "\e[31mRed text\e[0m\n";

?>

Documentation

See Also

each

each() was a native function, that would yield each element in an array. It was used in while() loops, to traverse lists.

It was deprecated during PHP 7.x and it is completely removed in version 8.0.

The classic while(list($key, $value) = each($array) structure, shown below, is, nowadays, advantageously replaced by a foreach() loop.

<?php

    $array = ['a' => 1, 'b' => 3, 'c' => 5];
    while(list($key, $value) = each($array)) {
        print $key . ' => ' . $value . PHP_EOL;
    }

?>

Documentation

See Also

Early Binding

Early binding is the feature that makes PHP allow using a class before its declaration, when the declaration is in same file. This is not always true, though, as other mechanisms may .

Documentation

See Also

Echo Tag

Echo tag is a special PHP opening tag: <?=. It combines the opening tag, and a call to the echo function.

The echo tag should not be confused with PHP short tags <?.

It is also called the short echo tag.

<?php $a = 1; ?><?= $a; ?>

Documentation

See Also

Echo

echo is a language construct used to output text to the browser or the output stream. It’s commonly used to display content on a web page, generate HTML, or provide feedback to users. The echo construct is often used to generate dynamic content that is sent to the client’s web browser.

echo is a language construct of PHP, not a function: it may be not be used as a callback.

echo works without parenthesis: then, it accepts an arbitrary number of arguments.

<?php

    echo 'Hello', ' ', 'world!';

?>

Documentation

See Also

Ecosystem

The PHP ecosystem refers to the entire environment around the language, made of the tools, communities, innovations, libraries, standards, events, and platforms built around, with and for the programming language.

An active ecosystem is a strong sign of good health for the underlying language.

Documentation

See Also

Edge Case

An edge case is a situation that occurs at the extreme ends of input, operating conditions, or environment. It requires exceptional conditions to happen, yet it is a possible situation.

<?php

// PHP addition always returns an integer
$integer = 2 + 1; 

// adding positive values to PHP_INT_MAX is an edge case
$integer = PHP_INT_MAX + 1; 

?>

Documentation

See Also

Edge Computing

Edge computing, also called compute at the edge, is a distributed computing paradigm that processes data at or near the source: at the network edge, close to the user or device, rather than routing all computation to a centralised data centre. The goal is to reduce latency, bandwidth consumption, and round-trip time.

In web development, the edge typically refers to CDN Points of Presence, PoPs, distributed globally. Logic executed at the edge runs within milliseconds of the end user, avoiding the latency of a transatlantic round trip to an origin server.

PHP at the edge is an emerging area. Cloudflare Workers do not natively support PHP, but experimental projects explore WebAssembly-compiled PHP. FrankenPHP supports edge-style persistent workers. AWS Lambda@Edge runs serverless functions at CloudFront PoPs, and Bref enables PHP on Lambda.

Common edge use cases: A/B testing, personalisation headers, authentication token validation, geo-routing, bot detection, and serving cached responses without hitting the origin.

<?php

    // PHP on the edge via AWS Lambda@Edge (using Bref)
    // Triggered at CloudFront request/response lifecycle
    
    return function (array $event): array {
        $request = $event['Records'][0]['cf']['request'];
        $headers = $request['headers'];
    
        // Geo-routing: redirect based on CloudFront-provided country header
        $country = $headers['cloudfront-viewer-country'][0]['value'] ?? 'US';
    
        if ($country === 'DE') {
            return [
                'status'      => '302',
                'statusDescription' => 'Found',
                'headers'     => [
                    'location' => [['key' => 'Location', 'value' => 'https://de.example.com' . $request['uri']]],
                ],
            ];
        }
    
        return $request; // pass through to origin
    };

?>

Documentation

See Also

Edge Triggered

Edge-triggered is an I/O notification mode where the system notifies a watcher only when the stream transitions from not-ready to ready, rather than continuously while the condition holds.

This is the opposite of level-triggered mode: a level-triggered watcher fires on every poll cycle as long as data is available, while an edge-triggered watcher fires exactly once per new arrival. As a consequence, edge-triggered handlers must drain the buffer completely on each notification, or they risk never being notified about the remaining data.

Edge-triggered mode reduces spurious wake-ups and is more efficient under high throughput, but it demands careful implementation. It maps to EPOLLET in the Linux epoll API and to EV_CLEAR in BSD kqueue.

In the future version 8.6, the Io\Poll API exposes edge-triggered behaviour through the Event::EdgeTriggered enum case, which can be combined with Event::Read or Event::Write when adding a watcher to a Context.

<?php

use Io\Poll\Context;
use Io\Poll\Event;

$context = new Context();

// Notify only on state transition, not continuously
$context->add($stream, Event::Read | Event::EdgeTriggered, function ($handle) {
    // Must read until fread() returns false or empty string
    while ($chunk = fread($handle->stream, 8192)) {
        echo $chunk;
    }
});

$context->run();

?>

Documentation

See Also

Effect System

An effect system, sometimes implemented as algebraic effects, is a type-system extension that tracks, in a function’s signature, which side effects it may perform: input/output, mutable state, exceptions, non-determinism, and so on. A function’s type then describes not only its inputs and outputs, but also what it is allowed to do while computing them.

Effect systems let a compiler enforce effect discipline: a function declared as pure cannot secretly perform I/O, and a caller can see, from the signature alone, that a function might throw, block, or write to a file. Effect handlers, found in languages such as Koka, Unison, and OCaml 5, let calling code intercept and reinterpret an effect, similarly to how exception handlers intercept exceptions, but generalized to any tracked effect.

PHP has no effect system. There is no way to declare, in a function’s signature, that it performs no I/O or is otherwise pure; a @throws docblock tag is documentation only, not enforced by the engine. Any function can perform any side effect at any time, and nothing in the type system tracks or restricts it.

Documentation

See Also

Egress Filtering

Egress filtering, or egress control, is the practice of monitoring and restricting outbound network traffic leaving a server or network, as opposed to ingress filtering, which controls incoming traffic.

Rules are typically enforced at the firewall, proxy or cloud security group level, allowing outbound connections only to known destinations, ports and protocols, and blocking or logging everything else.

For a PHP application, egress filtering is a defense-in-depth measure against Server-Side Request Forgery: even if an attacker manages to make the application issue an outbound request to an internal service or a malicious host, a properly configured egress rule can block the connection before it reaches its target.

Egress filtering also limits the damage of a successful compromise, by preventing a hijacked process from exfiltrating data or reaching a command-and-control server.

Documentation

See Also

Elephpant

The elephpant is the generic name for the unofficial logo of PHP. It was designed by Vincent Pontier.

Later, it was transformed into a cute plush toy by Damien Seguy.

The name elePHPant is a neologism, and is characteristic of the PHP community. The extra P in the word elephant makes the name of PHP appear, while turning the word into a tongue-twister.

Documentation

See Also

Ellipsis

Ellipsis operator is the ... operator. It also bears the name of three dots, and even dot dot dot.

It is used to implements the array spread feature, and the variadic arguments. The actual feature depends on the context.

Ellipsis is the classic punctuation description of the operator, and it applies to both features.

<?php

$array = [1, 2, 3];
$more = [...$array, 4, 5];

?>

Documentation

See Also

Email

Email, short for electronic mail, is a method of exchanging digital messages between people using electronic devices. These messages can contain text, attachments, images, and other multimedia elements. Email is a widely used communication tool for both personal and professional purposes.

PHP can send emails with the mail() function. PHP doesn’t receive emails, as it requires a server, so it relies on the imap extension.

PHP also offers special filter to validate email addresses, with the filter extension.

<?php

$to = 'destination@example.com';
$subject = 'Test Email';
$message = 'This is a test email.';

// Send the email
mail($to, $subject, $message);

?>

Documentation

See Also

Embed

To embed, or to be embedded, is integrating PHP code into another context, or vice versa.

Traditionally, it is possible to embed PHP inside HTML files: here, PHP embeds HTML. It is also possible to execute PHP code inside other languages, such as Java: in this case, Java embeds PHP.

Embedding usually means that the whole PHP engine is included in another technology: there, it acts as a part of that system. On the other hand, PHP extensions are a way to extend PHP features with other technologies. Here, the relationship is at the feature level, and may be tailored to PHP, rather than simply handing code as text to PHP, and acting upon its returned value.

Documentation

See Also

Embeddings

Embeddings, or vector embeddings, are numerical representations of data, such as text, images, audio, or video, expressed as vectors of floating-point numbers in a high-dimensional space.

Embeddings are produced by a model, usually a neural network, trained so that data with similar meaning ends up close together in that space, while unrelated data ends up far apart. This makes it possible to compare pieces of data by measuring the distance, or the cosine similarity, between their vectors, instead of comparing the raw data itself.

In applications, embeddings are typically generated by calling an external API, such as an LLM provider, or a local model, then stored and searched in a vector database. They are a core building block of semantic search, recommendation systems, and Retrieval Augmented Generation, RAG.

Documentation

See Also

Emoji

Emojis are small digital images or icons used to express ideas, emotions, objects, or concepts in electronic communication. The word emoji comes from Japanese, combining e, picture and moji, character or letter.

<?php

    // Emoji, directly in the string, when the file is also supporting Unicode, like with UTF8
    echo "Hello 😊";
    
    // Emoji, with a PHP escape sequence
    echo "\u{1F60A}";
    
    // Emoji, with an HTML escape sequence
    echo "&#128522;";

?>

Documentation

See Also

Empty String

The empty string is a string without any content. It may be built with single quotes, double quotes or the Heredoc and NowDoc syntaxes.

The empty string is the neutral element for concatenation: concatenating an empty string to another string does not change the latter.

The empty string may be used as an error report: for example, substr() returns an empty string when the offset is beyond the string range.

The empty string often serves as a default value, for properties and variables.

Comparisons between '' and other falsy values, such as 0, changed with PHP 8.0: it was true and became false.

The empty string is falsy: it is converted to the false boolean when implicit conversion is needed, such as in a condition.

<?php

    $emptyString1 = '';  // single quote
    $emptyString2 = "";  // double quote
    $emptyString3 = <<<STRING
STRING;
    $emptyString4 = <<<'STRING'
STRING;

?>

Documentation

See Also

Empty

Empty is a language structure, which determines whether a variable is empty.

A variable is considered empty if it does not exist or if its value equals false. This may overlap with the usage of isset().

empty() has an error suppression feature, that masks various errors, such as undefined offset or undefined variables. Some other errors, like an invalid type as offset, are still reported.

<?php

    // True
    var_dump(empty($a));
    
    $b = [];
    // True
    var_dump(empty($b));

?>

Documentation

See Also

Enable

To enable is to activate a feature and allow it to perform. For example, using --enable-soap when compiling PHP makes the ext/soap extension available. By default, it is disabled.

To enable implies a permanent state: it is different from a conditional statement.

Documentation

See Also

Encapsulation

Encapsulation is the practice of bundling data, in properties, and methods that operate on that data into a single unit, a class, while restricting direct access to some of the object’s components.

Encapsulation relies mostly on classes and visibility, to control access to data.

This is a fundamental principle of OOP, promoting security, modularity, and maintainability.

Documentation

See Also

Encode

To encode is to transform a piece of data, from a human readable format to a specialized format.

The conversion is lossless, and shall be reverted with a decode operation.

<?php

    // convert an array to a JSON string
    // This is also called 'encoding', and may be decoded
    $array = ['a' => 1];
    $json = json_encode($array);
    
    $original = json_decode($json);

?>

Documentation

See Also

Text Encoding

Encoding, or text encoding, is the way characters are organized to hold a meaning while being transmitted, stored or manipulated.

Encoding applies to PHP scripts, which should be UTF-8 encoded, although it might support other formats.

Encoding applies to incoming and outgoing data.

Encoding operations are provided with ext/mbstring, ext/iconv and ext/intl extensions.

Encoding is also used for code: the source is encoded when it is transformed in an unreadable yet still executable form.

Encoding is also called a character set.

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

echo 'Original : ', $text, PHP_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;

?>

Documentation

See Also

Encoding

Encoding is a generic term, and is used in different places:

  • Text encoding, for manipulations with iconv or mbstring
  • Declare encoding, with the declare keyword
  • HTTP encoding, for input and output operations

Text encoding is the process of converting characters into a specific format that can be stored, processed, or transmitted by computers. Different encodings represent characters as a series of bytes. The default encoding for text is UTF-8, which as the most general usage. Many other encoding exist.

Documentation

See Also

End To End Test

End to end tests are integration tests that cover the entire application, so it checks that it works correctly from the user’s perspective. End to end testing is simulating real user interactions through the actual UI, hitting real servers and databases.

End to end tests are critical to ensure a smooth experience for the user. They also require a duplication of the server environment, and they include the user’s scope, that may have high variability. E2E tests should be covering the most critical paths, not hundreds, as they’re slow and fragile.

Documentation

See Also

PHP Engine

The PHP engine, often referred to as the PHP interpreter, is the core component of the PHP programming language. It is responsible for translating and executing PHP code on a web server or other environments that support PHP. The engine takes the human-readable PHP code and converts it into machine-level instructions that the computer can understand and execute.

It is also called the php binary, or the PHP executable, although these names refer to the engine while its running, in a production or operating system environment.

The PHP engine is sometimes considered as a virtual machine.

Documentation

See Also

Entities

Entities are different things:

  • A type of data, which has an identity, independent from the properties
  • A way to unambiguously represent characters in HTML, using a sequence of characters.

Documentation

See Also

Enumeration Case

An Enumeration may have zero or more case definitions, with no maximum. A zero-case enum is syntactically valid, if rather useless.

Cases must have distinct names. Also, these names must be distinct with the constant names, since the syntax to reach them is the same.

Enumeration cases must be distinct: this is enforced by the engine with the unit enumerations, but not with the backed enumeration. It is possible to give identical values to the cases, and this yields an error as soon as the enumeration is loaded by PHP.

<?php

    enum Suit
    {
        case Hearts;
        case Diamonds;
        case Clubs;
        case Spades;
    }
    
    enum DayOfTheWeek: int
    {
        case Monday = 1;
        case Tuesday = 2;
        case Wednesday = 3;
        case Thursday = 4;
        case Friday = 4;    // This is an error, that lints but won't execute
        case Saturday = 6;
        case Sunday = 7;
        
        const string MONDAY = 'monday'; // constant MUST have distinct names from other constants and cases. 
                                        // names are case sensitive, so this one is valid.
    }

?>

Documentation

See Also

Enumeration (enum)

Enumerations are a restricting layer on top of classes and class constants, intended to provide a way to define a closed set of possible values for a type.

<?php

enum Suit
{
    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;
}

?>

Documentation

See Also

.env File

Environment files, also called dotenv files, are a way to store and access environment variables, and store them in a file, not in the OS environment.

The env file holds a set of environment variables and their values. It is loaded instead of the actual operating system value. That way, there may be several sets of values for the variables, each of them stored in a distinct file, and accessed via the file name.

Documentation

See Also

Environment Variables

Environment variables are a way to store and access configuration information or settings related to the runtime environment in which a PHP script is executed. These variables are part of the operating system’s environment and can be used to retrieve information about the server, the operating system, or custom configuration parameters that are set for a particular application. PHP provides a way to access these variables through the $_ENV superglobal array.

The environment variables are set in the operating system before the execution of the script, using commands such as export, setenv, or else, depending on the OS. They may also be provided at the start of containerized images.

<?php

    // print all available environment variables at the start of the script
    // it may be empty
    print_r($_ENV);
    
    // retrieve an environment variable 
    var_dump(getenv('MY_VARIABLE'));
    
    // sets an environment variable 
    var_dump(setenv('MY_VARIABLE', 2));

?>

Documentation

See Also

Environment

Environment variables are a way to store and access configuration information or settings related to the runtime environment in which a PHP script is executed. These variables are part of the operating system’s environment and can be used to retrieve information about the server, the operating system, or custom configuration parameters that are set for a particular application. PHP provides a way to access these variables through the $_ENV superglobal array.

The environment variables are set in the operating system before the execution of the script, using commands such as export, setenv, or else, depending on the OS. They may also be provided at the start of containerized images.

<?php

    // print all available environment variables at the start of the script
    // it may be empty
    print_r($_ENV);
    
    // retrieve an environment variable 
    var_dump(getenv('MY_VARIABLE'));
    
    // sets an environment variable 
    var_dump(setenv('MY_VARIABLE', 2));

?>

Documentation

See Also

Eponymous

Eponymous means that it carries the same name. For example, a variable called $variable, or a constant called CONSTANT.

PHP does not allow every structure to be eponymous. It is not possible to call a class class, but one may call a class anonymous: this won’t be eponymous, as an anonymous class doesn’t have a name.

<?php

    const CONSTANT = 'literal';
    
    $variable = CONSTANT;

?>

Documentation

See Also

Equal Operator

Equal, or equality, sometimes called double equal for the == operator, is the state of two variables, which contains the same data, after an optional cast to a common type. It is the same as identical, with possible silent type-juggling.

The equal operators are ==, !=, <>, and <=>. The switch() command also uses equal comparisons.

<?php

    var_dump(0 == '0000'); // true
    var_dump(0 == '0');    // false
    var_dump(0 == 0);      // true

?>

Documentation

See Also

Error Handler

The PHP error handler is a method that manages errors when they arise, instead of the default PHP handler.

The error handler is set with the set_error_handler() function.

The error handler is convenient to translate errors, handle custom levels of errors, or convert errors to exceptions.

There is a separate exception handler.

<?php

    set_error_handler('customErrorHandler');
    
    function customErrorHandler($errno, $errstr, $errfile, $errline, array $errcontext)
    {
        // Handles @ error suppression
        if (error_reporting === 0)
        {
            return false;
        }
    
        throw new Exception($errstr, 0, $errno, $errfile, $errline);
    }

?>

Documentation

See Also

Error Handling

Error handling is a broad concept that covers the different ways that PHP uses to signal that an error occurred.

The main systems are the error reporting, and the exceptions.

The error reporting is often associated with native errors, although it is possible to raise them and handle them with error-handlers.

The exception system is based on the throw, try and catch keywords.

<?php

    trigger_error('Cannot do this', E_USER_ERROR);
    
    try {
        throw new Exception('Cannot do this');
    } catch (Exception $e) {
        print $e->getMessage();
    }

?>

Documentation

See Also

Error Reporting

Error reporting is a feature, a directive and a PHP native function. They all work with the same concept.

Error reporting is the way PHP displays errors as they are detected during execution. The error_reporting() function and the error_reporting directive set the type of error to be reported: errors are of different types.

While error reporting sets the type of reported error, the display of error is handled by different directives: display_errors and html_errors.

Exceptions are not covered by the error reporting, even though one of the exceptions is called Error.

Error reporting may be further configured with an error handler function.

Error may be triggered manually with the trigger_error() function.

Documentation

See Also

Error Suppression

Error suppression is achieved with the @ operator placed before an expression. It silences any error, warning, or notice that expression might produce.

Using @ is widely considered bad practice: it hides bugs, degrades performance, and makes debugging harder. Better alternatives include proper validation, try/catch blocks, or a custom error handler.

The scream extension and scream.enabled ini directive can disable the @ operator entirely.

<?php

    // Bad practice: silences errors
    $result = @file_get_contents('missing.txt');
    
    // Better: check first
    if (file_exists('missing.txt')) {
        $result = file_get_contents('missing.txt');
    }

?>

Documentation

See Also

Error

The Error class is a base class for all internal PHP error exceptions. It represents an error that occurs during the execution of PHP code. The Error class extends the built-in Throwable interface, making it possible to catch and handle these error exceptions using try-catch blocks.

The Error class has several child classes that represent specific types of errors. Some common child classes include:

  • ParseError: represents a syntax error that occurs during parsing of PHP code
  • TypeError: represents a type-related error, such as passing an incorrect argument type to a function or method
  • DivisionByZeroError: represents an error that occurs when dividing a number by zero
  • OutOfMemoryError: represents an error that occurs when the PHP process runs out of memory

See the example that demonstrates catching and handling a ParseError below. In the example, the eval() function is used to evaluate a string of PHP code. However, the code contains a syntax error with a missing semicolon. This results in a ParseError being thrown. We use a try-catch block to catch the ParseError exception, and then display the error message using the getMessage() method.

It’s important to note that these errors are only thrown by internal PHP errors. User-generated errors, e.g., triggered using the trigger_error() function, are not instances of the Error class. Instead, they are represented by the ErrorException class, which extends Exception.

<?php

    try {
        eval('echo Hello, World!'); // Missing semicolon generates a ParseError
    } catch (ParseError $e) {
        echo 'Caught ParseError: ' . $e->getMessage();
    }

?>

Documentation

See Also

Error_log()

error_log() sends an error message to a logging destination: the web server log, a file, or a remote address, depending on the $message_type argument and the error_log PHP configuration directive.

With no $message_type, or $message_type = 0, the message goes to whatever destination is set by the error_log directive. $message_type = 3 appends the message to the file given as the $destination argument, while $message_type = 1 emails the message, and $message_type = 4 sends it directly to the SAPI logging handler, bypassing the error_log directive.

error_log() returns true on success, and does not throw. Because its actual destination depends on runtime configuration, code that relies on error_log() for anything beyond ad-hoc debugging is usually better served by a dedicated, configurable logger, such as one implementing the PSR-3 LoggerInterface.

<?php

error_log('Something went wrong while processing the order');

// append to a specific file, bypassing the error_log directive
error_log('Payment failed for order #42', 3, '/var/log/payments.log');

?>

Documentation

See Also

Error Reporting

Error reporting is the process to report any issue while executing the code. It is also the name of the eponymous function error_reporting() and also a php.ini directive: error_reporting. They all control the way errors are handled.

Error reporting is set by calling the error_reporting() function, with a combination of constants: E_ERROR, E_WARNING, E_PARSE, E_NOTICE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE, E_STRICT, E_RECOVERABLE_ERROR, E_DEPRECATED, E_USER_DEPRECATED, E_ALL. They are combined as a bitfield, or may be replaced by their integer counterpart. One special value is -1, which is the universal error reporting: it activates all types of errors, past present and future.

error_reporting, the directive, is set in the php.ini file. It doesn’t support the bitfield, so it must be set as an integer.

<?php

    // Turn off all error reporting
    error_reporting(0);
    
    // Report simple running errors
    error_reporting(E_ERROR | E_WARNING | E_PARSE);
    
    // Reporting E_NOTICE can be good too (to report uninitialized
    // variables or catch variable name misspellings ...)
    error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
    
    // Report all errors except E_NOTICE
    error_reporting(E_ALL & ~E_NOTICE);

?>

Documentation

See Also

Escape Character

Escape characters are special characters, that introduce a special meaning, for example when redacting an escape sequence.

Escape characters are often generating a special sequence to escape themselves and allow their literal meaning to be expressed.

In strings and HEREDOC, the escape character is the backslash: \.

<?php

    echo '<a href="https://www.exakat.io/" />';
    
    // This prevents the variable $trunk to be interpolated
    echo <<<HEREDOC
    echo $trunk;
HEREDOC;

?>

Documentation

See Also

Escape Data

Escaping data is a method to write data in a neutral syntax for a target technology.

For example, angular brackets and quotes are special characters for HTML: to display them without their actual HTML meaning, they have to be escaped as HTML entities, such as &quote or &gt;.

Escaping applies to technologies which mix raw strings and executable expression: SQL, CSV, HTML, LDAP, etc.

Escaping data replace some symbols with a longer sequence of symbols. The escaping is made with a special character, which must itself be escaped. For example, CSV escapes anti-slash with a double anti-slash.

PHP supports escape sequences for characters in a string. This is the same concept of escaping data: there, the target includes portability.

Documentation

See Also

HTML Escaping

HTML escaping, or HTML escape, also known as HTML encoding or character escaping, is a technique used to convert special characters in HTML markup into their corresponding HTML entities. This is done to prevent these characters from being interpreted as HTML code by the browser, which could potentially lead to security vulnerabilities or incorrect rendering of the webpage.

For example, the less-than sign < is represented as &lt; and the greater-than sign > is represented as &gt;. Similarly, characters such as ampersand & and double quotation marks " have their own HTML entities, resp. &amp; and &quote;.

HTML escaping is commonly used when displaying user-generated content on a webpage, such as comments or forum posts, to ensure that any HTML code contained within the content does not interfere with the structure of the page or execute malicious scripts. It helps maintain the integrity and security of the webpage.

<?php

    $str = "A 'quote' is <b>bold</b>";
    
    // Outputs: A 'quote' is &lt;b&gt;bold&lt;/b&gt;
    echo htmlentities($str);
    
    // Outputs: A &#039;quote&#039; is &lt;b&gt;bold&lt;/b&gt;
    echo htmlentities($str, ENT_QUOTES);

?>

Documentation

See Also

Escape Sequences

Escape sequences, also called string sequences when found inside string literals, are sequences of characters with a special meaning. Most of the time, the literal value of the character displayed is its meaning, while, sometimes, there are other hidden meanings.

Escape sequences are dedicated to a technology, and they are rarely the same between two technologies, or even, between two engines dedicated to that technology.

Here are some examples of escape sequences from PHP:

  • \n: new line
  • \t: horizontal tabulation
  • "\"": double quote, inside a double quoted-string
  • \' This is not an escape sequence: single-quoted strings do not recognize this
  • \u{01f418}: a unicode codepoint, representing an elephpant
  • \200: a character in octal notation
  • \x69: a character in hexadecimal notation

Here are some examples of escape sequences from HTML:

  • ´, an acute accent
  • ", double quote
  • There are many more of them. See external links.

Escape sequences should not be confused with escape characters, though they are related: some escape sequences are introduced by an escape character. Others rely on a format.

<?php

    // \1 is an escape sequence that represents the first capturing parenthsis. 
    // It is a special meaning for REGEX.
    preg_match('/(.)\1/', $string);
    
    // Displays AA
    echo "A\101";

?>

Documentation

See Also

escapeshellarg()

escapeshellarg() is a PHP function that wraps a string in single quotes and escapes any existing single quotes within it, making the string safe to pass as a single argument to a shell command.

It is used together with exec(), system(), passthru(), or shell_exec() when the argument is derived from user input or any untrusted source.

On Windows, escapeshellarg() uses double quotes and escapes double quotes, percent signs, and exclamation marks instead.

Note that escapeshellarg() escapes a single argument only. When the full command string needs to be sanitised, escapeshellcmd() should be used, though combining both functions correctly is preferred.

<?php

    $filename = $_GET['file'] ?? '';
    $safe     = escapeshellarg($filename);
    
    // Safe: $safe is a quoted, escaped argument
    exec('convert ' . $safe . ' output.png', $output, $exitCode);

?>

Documentation

See Also

escapeshellcmd()

escapeshellcmd() is a native function that escapes shell metacharacters in a full command string, preventing shell interpretation of characters such as &, ;, |, (, ), [, ], {, }, $, \`, \, ", ', and whitespace sequences that could alter the intended command.

Unlike escapeshellarg(), which wraps a single argument in quotes, escapeshellcmd() is applied to the entire command string and escapes individual special characters with a backslash. It is suitable when the command itself is dynamic, not just its arguments.

Important caveats:

  • escapeshellcmd() does not make arbitrary shell strings safe. It is designed for use with exec(), system(), passthru(), and shell_exec(), but cannot protect against every shell injection vector. Prefer escapeshellarg() on each argument individually, as this is generally more reliable.
  • On Windows, escapeshellcmd() has different behaviour: it escapes a different set of special characters. Code relying on it must be tested on the target platform.
  • The safest approach to shell execution is to avoid building a command string at all. Use proc_open() with an array argument form, where available via wrapper libraries, or pass arguments as an explicit array, which bypasses the shell entirely.
<?php

    $userInput = $_GET['path'] ?? '';
    
    // Escapes metacharacters in the whole command string
    $cmd = escapeshellcmd('ls -la ' . $userInput);
    exec($cmd, $output);
    
    // Preferred: escape each argument individually with escapeshellarg()
    $safeInput = escapeshellarg($userInput);
    exec('ls -la ' . $safeInput, $output);
    
    // Safest: avoid shell entirely with proc_open + array (Symfony Process component)
    // $process = new \Symfony\Component\Process\Process(['ls', '-la', $userInput]);
    // $process->run();

?>

Documentation

See Also

Extract, Transform, Load (ETL)

ETL, for Extract, Transform, Load, is a three-stage process used to move data from one or more source systems into a target system. Extract reads data from the source, for example a legacy database, a CSV export, or an API; transform converts, cleans, and reshapes that data to match the target’s schema and rules, such as mapping locale codes or resolving foreign keys; load writes the transformed data into the destination.

ETL is the backbone of data migrations, data warehousing, and platform-to-platform migrations, such as moving a store from one e-commerce platform to another. The transform stage is where most silent bugs live: a lookup that returns null instead of raising an error on an unmapped value, a string replacement that only handles the common case, or a locale code that does not match any entry in a mapping table, will quietly drop or nullify data instead of failing the migration.

A variant, ELT, for Extract, Load, Transform, loads raw data first and transforms it inside the target system, often using its own query engine. ETL steps are commonly implemented as CLI scripts or queued jobs, reading from one data source and writing through an ORM, or direct SQL, into another, with row counts and conversion rates tracked to detect when a stage silently drops far more rows than expected.

<?php

    // A minimal ETL step: extract, transform, load
    foreach ($source->fetchProducts() as $row) {          // extract
        $locale = $localeMap[$row['locale_code']] ?? null; // transform

        if ($locale === null) {
            $errors[] = $row['locale_code']; // don't fail silently
            continue;
        }

        $target->insertProduct($row, $locale);             // load
    }

?>

Documentation

See Also

Eval()

The eval() function executes a string as a PHP code.

eval() has been used originally to obtain features that PHP did not offer. Nowadays, those features are rare enough that it is recommended to find a safe alternative, before using on it.

When used, it is recommended to enclose eval() in a try-catch block, to catch syntax error.

<?php

    $name = 'v';
    $value = 'vvvv';
    
    // Set a variable with a dynamic name
    eval('$'.$name.' = '.$value);
    // equivalent to $$name = $value;

?>

Documentation

See Also

Event Driven

Event-driven programming is a programming paradigm that focuses on the flow of a program’s execution being determined by events or actions that occur, rather than following a strictly sequential, procedural path. In event-driven programming, the program responds to events generated by external factors, such as user interactions, sensor inputs, or messages from other software components. Events can trigger specific functions or pieces of code to execute in response.

Documentation

See Also

Event Loop

An event loop is a mechanism for handling asynchronous operations and event-driven programming. While PHP traditionally follows a synchronous execution model where each operation blocks the execution until it completes, the introduction of event loops enables non-blocking I/O operations and improves concurrency.

PHP event loops are often implemented using extensions like ReactPHP or Amp.

<?php

// Code from revolt's event loop
// https://revolt.run/fundamentals
require __DIR__ . '/vendor/autoload.php';

use Revolt\EventLoop;

$suspension = EventLoop::getSuspension();

$repeatId = EventLoop::repeat(1, function (): void {
    print '++ Executing callback created by EventLoop::repeat()' . PHP_EOL;
});

EventLoop::delay(5, function () use ($suspension, $repeatId): void {
    print '++ Executing callback created by EventLoop::delay()' . PHP_EOL;

    EventLoop::cancel($repeatId);
    $suspension->resume(null);

    print '++ Suspension::resume() is async!' . PHP_EOL;
});

print '++ Suspending to event loop...' . PHP_EOL;

$suspension->suspend();

print '++ Script end' . PHP_EOL;

Documentation

Event Replay

Event replay, also called event-sourcing replay, is the process of re-reading stored events from an event store to reconstruct the state of an aggregate, rebuild a projection, or bootstrap a new view of the data.

In event sourcing, the current state of any aggregate is not stored directly: it is always derived by loading the aggregate’s event stream and applying each event in order. This is event replay at the aggregate level. For a simple entity, replaying tens or hundreds of events takes microseconds; for aggregates with thousands of events, snapshots are used to avoid replaying the entire history on every load.

Replay is also used at the projection level: a read model can be dropped and rebuilt entirely from the event store by replaying all events through the projection’s handlers. This is invaluable for fixing bugs in projections, adding new read models, and migrating to a new schema.

Temporal replay enables querying the state of the system at any point in the past by replaying events up to a given timestamp.

<?php

// Reconstruct aggregate state by replaying its event stream
class Order {
    private string $status = 'new';
    private float  $total  = 0.0;

    public static function reconstitute(array $events): self {
        $order = new self();
        foreach ($events as $event) {
            $order->apply($event);
        }
        return $order;
    }

    private function apply(object $event): void {
        match (true) {
            $event instanceof OrderPlaced   => $this->total  = $event->total,
            $event instanceof OrderShipped  => $this->status = 'shipped',
            $event instanceof OrderCancelled => $this->status = 'cancelled',
            default                         => null,
        };
    }
}

// Rebuild a projection from the event store
class RebuildOrderSummaryProjection {
    public function run(EventStore $store): void {
        $this->db->exec('TRUNCATE order_summaries');
        foreach ($store->loadAll('orders') as $event) {
            $this->project($event);
        }
    }
}

?>

Documentation

See Also

Event Sourcing

Event Sourcing is a pattern where instead of storing the current state of an entity, the sequence of events that led to that state is stored. The current state is derived by replaying those events.

Event sourcing provides a full audit trail. It never loses history. Every change is recorded with a timestamp and context, which is invaluable for debugging, compliance, and support.

Event sourcing allows for time travel. It is possible to reconstruct the state of any entity at any point in the past by replaying events up to a given timestamp.

Event sourcing emphasize on decoupled side effects. Different parts of the system can react to events asynchronously, such as sending emails, updating read models, triggering workflows. All that without coupling them to the write logic.

Event sourcing pairs naturally with CQRS. The event stream is the write side; it relies on optimized read models, also called projections, and processes those events separately.

Documentation

See Also

Event Store

An event store, also called an event log, is an append-only database that stores domain events as the primary source of truth. Instead of persisting the current state of an entity, as a traditional relational database does, the event store records every state-changing event in the order it occurred. The current state is derived by replaying all events for a given aggregate.

Event stores have three fundamental properties: events are immutable, as in never updated or deleted, ordered, as in within an aggregate stream, and complete , as in no information is lost. This makes them naturally auditable, debuggable, and replayable.

An event store differs from a general-purpose message queue: it is designed for long-term persistence and random-access replay, not just for transient message delivery. EventStoreDB is a purpose-built event store. Kafka is also used as an event store when configured with long retention periods.

In event-sourcing implementations, the event store is typically an abstraction over a PostgreSQL table, with JSON event payloads, Kafka, or EventStoreDB. Libraries such as Prooph or Broadway provide event store interfaces.

<?php

// Simple append-only event store backed by PostgreSQL
class PostgresEventStore {
    public function append(string $streamId, array $events, int $expectedVersion): void {
        $this->pdo->beginTransaction();
        foreach ($events as $i => $event) {
            $stmt = $this->pdo->prepare(
                'INSERT INTO events (stream_id, version, event_type, payload, occurred_at)
                 VALUES (:stream, :version, :type, :payload, NOW())'
            );
            $stmt->execute([
                'stream'  => $streamId,
                'version' => $expectedVersion + $i + 1,
                'type'    => get_class($event),
                'payload' => json_encode($event),
            ]);
        }
        $this->pdo->commit();
    }

    public function load(string $streamId, int $fromVersion = 0): array {
        $stmt = $this->pdo->prepare(
            'SELECT * FROM events WHERE stream_id = ? AND version > ? ORDER BY version'
        );
        $stmt->execute([$streamId, $fromVersion]);
        return $stmt->fetchAll();
    }
}

?>

Documentation

Event Storming

Event storming is a workshop, aiming at discovering the domain for an application. It describes the business process with stickers of various colors, posted on a wide wall, by involving experts to share their knowledge.

Documentation

See Also

Event Streaming

Event streaming, also called stream processing, is a pattern where events are continuously published to an ordered, durable log, called a stream, and consumers read from that log at their own pace, independently of producers. Unlike message queues, where a message is consumed once and deleted, a stream is retained and can be replayed, and multiple consumer groups can read the same events independently.

The key properties of event streaming are: persistence where events are stored durably, ordering where events within a partition are ordered, and replayability where consumers can reset their offset and re-read events from the beginning or any point in time. These properties make event streaming suitable for event sourcing, real-time analytics, change data capture, and building multiple independent views from the same event log.

Apache Kafka is the most widely used event streaming platform. AWS Kinesis and Google Cloud Pub/Sub provide managed alternatives. Producers publish events via the rdkafka extension or high-level libraries; consumers run as long-lived workers using RoadRunner, Swoole, or ReactPHP.

<?php

    // Producer: publish an event to a Kafka topic
    $conf = new RdKafka\Conf();
    $conf->set('metadata.broker.list', 'kafka:9092');
    
    $producer = new RdKafka\Producer($conf);
    $topic    = $producer->newTopic('orders');
    
    $topic->produce(RD_KAFKA_PARTITION_UA, 0, json_encode([
        'event'     => 'OrderPlaced',
        'orderId'   => 42,
        'total'     => 9900,
        'timestamp' => time(),
    ]));
    
    $producer->flush(1000);
    
    // Consumer: read events independently, at own pace
    $conf->set('group.id', 'inventory-service');
    $conf->set('auto.offset.reset', 'earliest'); // replay from beginning if needed
    
    $consumer = new RdKafka\KafkaConsumer($conf);
    $consumer->subscribe(['orders']);
    
    while (true) {
        $message = $consumer->consume(1000);
        if ($message->err === RD_KAFKA_RESP_ERR_NO_ERROR) {
            $event = json_decode($message->payload, true);
            // process independently from the producer
        }
    }

?>

Documentation

See Also

Eventual Consistency

Eventual consistency is a data consistency model used in distributed systems where replicas of the same data are allowed to diverge temporarily, but are guaranteed to converge to the same value if no new updates are made.

It is a weaker guarantee than strong consistency, where all nodes see the same data at the same time, or ACID transactions, which guarantee immediate, atomic consistency. Eventual consistency trades immediate correctness for higher availability and partition tolerance: the AP side of the CAP theorem.

In practice, eventual consistency means a write to one node may not be immediately visible on another. A user updating their profile may see the old value for a few hundred milliseconds while the change propagates to read replicas.

In applications, eventual consistency arises when using: read replicas which write to primary and read from replica, caches which serve stale data after a write, event sourcing where projections lag behind the event store, or microservices communicating via events rather than synchronous API calls.

<?php

    // Common PHP scenario: write to primary, read from read replica
    // The replica may lag by milliseconds — eventual consistency
    
    $primary = new PDO($primaryDsn);
    $replica = new PDO($replicaDsn);
    
    $primary->exec('UPDATE users SET name = \'Alice\' WHERE id = 1');
    
    // Reading immediately from the replica may return the old name
    $row = $replica->query('SELECT name FROM users WHERE id = 1')->fetch();
    // $row['name'] could still be 'Bob' for a brief window
    
    // Mitigation: read-your-own-writes — read from primary just after a write
    // or use a sticky session to route reads to the same node for a period

?>

Documentation

See Also

Chaining Exceptions

Exception chaining, also called chaining exception, is the act of re-throwing a caught exception, with a new type, and with a reference to the previous exception.

To provide the previous exception to a new exception, use the third parameter of the Exception constructor. Also, always provide a third argument to custom exceptions.

The previous exception is available with the Exception::getPrevious() method of the Exception class.

<?php

class myException extends \Exception {
    function __construct(string $message, $code, \Throwable $exception) {
        parent::__construct($message, $code, $exception);
    }
}

try {
    doSomething();
} catch(\Exception $e) {
    // chaining exception
    throw new myException('doSomething failed', 0, $e);
}

?>

Documentation

See Also

Exception Handler

The exception handler is a default or custom function, which is called once an exception has exhausted all available try-catch blocks.

The execution stops once the handler has been called: as such, it is possible to log or display information related to debugging.

The exception handler is different from the try/catch block: the latter allows the execution to carry on, when the exception is processed.

<?php

    function exception_handler(Throwable $exception) {
        echo "Uncaught exception: " , $exception->getMessage(), "\n";
    }
    
    set_exception_handler('exception_handler');
    
    throw new Exception('Uncaught Exception');
    echo "Not Executed\n";

?>

Documentation

See Also

Exception

Exceptions are a mechanism for handling errors and exceptional situations in a more structured and controlled way compared to traditional error handling methods like using error codes or die() statements. Exceptions provide a way to separate the normal flow of code from error-handling code, making it easier to manage errors and maintain clean and readable code.

Exceptions are thrown at the point of detection of the issue, and processed somewhere else in the code, when they are caught by a try-catch statement. Ultimately, exceptions block the execution of the application when they are not caught.

<?php

    class Elephpant {
        final const HABITAT = 1;

        final function method() { }
    }

?>

Documentation

See Also

Excimer

Excimer is a low-overhead sampling profiler for PHP, developed by the Wikimedia Foundation. Unlike deterministic profilers such as Xdebug, which instrument every function call, Excimer periodically samples the call stack at a fixed interval, using a timer signal, which keeps overhead low enough to run in production.

Excimer can sample on wall-clock time or CPU time, which makes it useful for diagnosing both I/O-bound slowness, such as waiting on a database or a remote API, and CPU-bound slowness, such as heavy computation. Samples are collected into a log that can be aggregated into a flame graph or exported for further analysis.

Because sampling is cheap, Excimer is commonly left enabled at low sampling rates in production to catch real-world performance regressions that only appear under production load and traffic patterns, which synthetic benchmarks miss.

<?php

    // Sample the call stack every 100ms of wall-clock time.
    $profiler = new ExcimerProfiler();
    $profiler->setPeriod(0.1);
    $profiler->setEventType(EXCIMER_REAL);
    $profiler->start();

    // ... application code runs here ...

    $profiler->stop();

    $log = $profiler->getLog();
    foreach ($log as $event) {
        foreach ($event->getTrace() as $frame) {
            echo $frame['function'] . PHP_EOL;
        }
    }

?>

Documentation

See Also

exec

exec() is used to execute a command with the underlying operating system. It is the equivalent of shell_exec() and back-ticks.

exec() has specific arguments to collect both the result of the command, one line per element in an array, and the resulting code. This differs from shell_exec(), which only returns the result, and as a string.

<?php

$dir = exec('ls', $result);
print_r($result);

?>

Documentation

See Also

Execution Path

The execution path refers to the sequence in which the PHP interpreter processes and executes the code. By default, expressions are executed one after the other, and the execution path has many possible paths:

  • Code Entry Point, such as the called file, but also controllers, in mvc frameworks
  • Sequential Execution, where expressions are processed one after the other
  • Includes and Requires, which stop the execution in the current file and move to another file
  • Function and Method Calls, which stop the execution in the current file and move it to another part of the code
  • Control Structures, like goto, foreach, ifthen, which choose a path or another with the current file
  • Error Handling, with error triggers and exceptions, and unhandled issues
  • Exit and Die, or simply the end of the file.

Documentation

See Also

Execution Time

Execution time is a phase of PHP processing, where the source code is executed. It highly depends on the order of execution of the instructions.

At that time, PHP takes the commands one after the other, and execute them. It allocates memory for data, and definitions.

Execution time is related to compile time. Objects, constants when created with define(), function calls, generators, inclusion, exceptions are execution time elements.

On the other hand, classes, constants when created with const, functions, etc. are created at linting time.

<?php

    const HABITAT = 'a';
    function trumpet(int $a = HABITAT) {
        echo $a;
    }

    trumpet(1);  // 1
    trumpet();   // Error
    //Uncaught TypeError: trumpet(): Argument #1 ($a) must be of type int, string given,

?>

Documentation

See Also

Execution

Execution refers to the ability to run code or system commands dynamically at runtime. There is the execution of PHP code, and the execution of external code from within PHP.

Language-level code execution uses eval(), which parses and executes a PHP string as code. System-level execution delegates to the operating system shell via exec(), shell_exec(), system(), passthru(), popen(), or the backtick operator.

The execution of PHP code is based on the PHP engine, though it may also be achieved by other PHP runtimes, or be delegated to other engine via transpiling of the code.

The flow of execution may be hijacked by a code injection, which route the execution to arbitrary code. It is a security vulnerability.

<?php

    // DANGEROUS: user-controlled input passed to eval()
    $template = $_GET['tpl'];
    eval('echo ' . $template . ';');  // RCE risk

    // DANGEROUS: user input in a shell command
    $file = $_GET['file'];
    exec('ls ' . $file);              // command injection risk

    // SAFER: escape shell arguments
    $file = escapeshellarg($_GET['file']);
    exec('ls ' . $file);

?>

Documentation

See Also

execve()

execve() is the underlying Unix system call that replaces the currently running process’s program, code, data, heap and stack, with a new one. Unlike forking, no new process is created: the process keeps the same PID, but everything it was running is discarded and replaced.

pcntl_exec() is a thin wrapper around execve(). This makes it fundamentally different from exec() or shell_exec(), which spawn a separate child process and return control to the calling PHP script once it finishes. Once pcntl_exec() succeeds, the PHP script that called it stops existing: there is no code left afterwards to return to, unless the call itself fails.

pcntl_exec() is typically used to replace a PHP worker process with another program after preparation work, such as setting up file descriptors or dropping privileges, has been done in the process.

<?php

    // Everything below this call never runs if pcntl_exec() succeeds:
    // the PHP process is replaced in place by /usr/bin/php-fpm.
    pcntl_exec('/usr/bin/php-fpm', ['--nodaemonize'], ['ENV' => 'production']);

    // Only reached if execve() itself failed
    exit('exec failed');

?>

Documentation

See Also

Exhaustiveness

Exhaustiveness is the property of a pattern-matching or switch-like construct that guarantees every possible case has been handled, checked by the compiler or engine rather than left to the developer to remember. A construct is exhaustive over a type when it is impossible to reach the end of it without matching a branch.

PHP’s match is close but not exhaustive in this sense: it throws UnhandledMatchError at runtime if no arm applies, instead of refusing to compile a non-exhaustive match. That still closes an entire class of switch bugs, silent fallthrough and forgotten break, but the gap is only caught when that code path executes, not before.

True exhaustiveness needs a closed set of cases to check against, which is why it usually appears together with sum types or algebraic data types, such as enumerations with associated values: the compiler can list every case of the type and verify the match covers all of them, or point at exactly the one that is missing. Pattern matching proposals that add structural matching over types and shapes are a step toward this, but full exhaustiveness checking requires the closed, enumerable type that a sum type provides.

<?php

    enum Status { case Draft; case Published; case Archived; }

    // Not exhaustive: throws UnhandledMatchError if a new case is added later
    $label = match ($status) {
        Status::Draft => 'Draft',
        Status::Published => 'Live',
        // Status::Archived is missing
    };

?>

Documentation

See Also

EXIF (Exchangeable Image File Format)

EXIF is a standard for storing metadata in image files, particularly JPEG and TIFF. It embeds information such as camera settings, date and time, GPS coordinates, orientation, thumbnail images, and other technical details captured by cameras and smartphones.

PHP provides the exif extension, which offers functions to read and write EXIF data from image files. This is commonly used for:

  • Retrieving camera make and model
  • Reading image orientation for automatic rotation
  • Extracting GPS coordinates for geotagging
  • Accessing date/time the photo was taken
  • Reading thumbnail images embedded in EXIF data

The EXIF data is stored in the file header and does not affect image quality. It is a subset of the TIFF format and is defined by the JEIDA standard, the Japan Electronic Industry Development Association.

Common EXIF functions include exif_read_data(), exif_imagetype(), exif_thumbnail(), and exif_process_raw_data(). Note that EXIF data may contain sensitive information such as GPS location, which should be considered for privacy.

<?php

    // Reading EXIF data from an image
    $exif = exif_read_data('photo.jpg', 'COMPUTED', true);
    if ($exif !== false) {
        echo 'Camera: ' . $exif['Make'] . ' ' . $exif['Model'] . "\n";
        echo 'Date: ' . $exif['DateTimeOriginal'] . "\n";
        echo 'Width: ' . $exif['COMPUTED']['Width'] . "\n";
        echo 'Height: ' . $exif['COMPUTED']['Height'] . "\n";
    }

    // Check image type by EXIF data
    $type = exif_imagetype('photo.jpg');
    if ($type === IMAGETYPE_JPEG) {
        echo 'This is a JPEG image';
    }

?>

Documentation

See Also

Existence

Existence is the general concept of checking whether something is available before using it. PHP provides several dedicated functions and constructs for this, each targeting a different kind of entity.

isset() checks whether a variable exists and is not null. It is a language construct, not a function, so it does not trigger an error on undefined variables. It is commonly used to guard access to array keys or object properties before reading them.

defined() checks whether a constant has been defined, either with define() or const. It is the counterpart of isset() for constants, since constants are not variables and isset() cannot be used on them.

file_exists() checks whether a file or directory exists on the filesystem at a given path. It is used before reading, including, or operating on a file, to avoid errors on missing paths.

class_exists(), interface_exists(), and trait_exists() check whether a class, interface, or trait has been loaded or can be autoloaded. They are useful in conditional compatibility code, plugin systems, or when working with optional dependencies.

The underlying concept is the same across all these cases: verify that an entity is available in its respective scope before attempting to use it. Failing to check existence is a common source of warnings, errors, and undefined-behavior bugs.

<?php

    // Variable existence
    if (isset($config['timeout'])) {
        $timeout = $config['timeout'];
    }

    // Constant existence
    if (defined('APP_ENV')) {
        echo APP_ENV;
    }

    // File existence
    if (file_exists('/path/to/config.php')) {
        include '/path/to/config.php';
    }

    // Class existence
    if (class_exists(SomeOptionalLibrary::class)) {
        $obj = new SomeOptionalLibrary();
    }

?>

Documentation

See Also

Existential Type

An existential type expresses that there exists some concrete type satisfying a constraint, without naming that type at the call site. Where a universally quantified type says “for all T”, an existential type says “there exists a T”.

The distinction matters when a value is produced by a module or function that hides its concrete type behind an interface. A data structure typed as ∃T. (T, T -> String) contains a value of some unknown type T together with a function to convert it to a string. The consumer can call the conversion function but cannot inspect or name T itself: the type is sealed inside the abstraction.

In Haskell this is expressed with forall in data constructors, data ShowBox = forall a. Show a => SB a, effectively hiding the concrete type. In Scala, existential types appear as _ wildcards or through use-site variance. Rust approximates existentials with impl Trait in return position.

PHP does not support existential types. Interface types are the closest approximation: a function returning Countable hides the concrete class, but PHP interfaces cannot carry existentially quantified type parameters. Generics would be a prerequisite, as existential types are typically expressed as a bounded generic whose parameter is hidden from the caller.

<?php

    // PHP approximation: returning an interface hides the concrete type,
    // but PHP cannot express the type parameter that goes with it.
    interface Printable {
        public function print(): void;
    }

    // The caller knows only that something Printable was returned;
    // it cannot name or inspect the concrete type.
    function makePrintable(mixed $data): Printable {
        return new class($data) implements Printable {
            public function __construct(private readonly mixed $inner) {}
            public function print(): void { var_dump($this->inner); }
        };
    }

?>

Documentation

See Also

Exit

exit() and die() terminate the current execution.

exit() is a language construct, and since PHP 8.4, it is also a function too.

After the end of execution, the registered shutdown functions and destructors are executed. finally blocks are not executed.

They do not have access to the output stream php://output anymore, so echo doesn’t work; but it may still write in files or database, if the connection is still open.

exit() uses its argument to return its execution status. It is transmitted to the original caller of the application. When the argument is a string, it is displayed before ending the process.

<?php

    $total = 0;
    for($i = 0; $i < 10; ++$i) {
        $total += $i;
        
        if ($i == 5) {
            exit($total);
        }
    }

?>

Documentation

See Also

Explanation

In the context of static analysis and code review, an explanation is a natural-language description of why a piece of code is flagged, what rule it violates, and how to fix it.

Good explanations bridge the gap between a raw finding, with context data such as file, line, severity,… and actionable understanding. They include: the name and rationale of the rule, a concrete example of the problematic pattern, the recommended alternative, and links to documentation or further reading.

In a broader software context, explanation also refers to the practice of making code behavior transparent and understandable: through comments, documentation, naming conventions, and readable structure. Self-explanatory code minimizes the need for inline comments by making intent visible in the code itself.

AI-assisted code explanation is an emerging use case where a language model summarises what a function or class does, identifies its contract, and describes its edge cases.

Documentation

See Also

Explicit Boolean Comparison

The Explicit Boolean Comparison is the syntax convention that includes a literal value when using a boolean as a condition.

Explicit boolean comparison may be redundant, when the compared value is already a boolean. PHP also does an implicit cast to boolean before using variables in conditions.

On the other hand, type juggling may yield unexpected results, and lead to bugs.

<?php

if ($var === true) {} 

?>

Documentation

See Also

Explicit

A feature is explicit when its presence is represented in the source code.

For example, a default value for an argument is not explicit: it may be omitted, and still be used. It is called implicit.

If that same value is written in the calling code, even if the passed value is the same as the default value, it is now explicit, and may be read in the calling code.

<?php

    function trumpet($a = 1) {}

    // implicit call
    trumpet();

    // explicit calls
    trumpet(1);
    trumpet(3);

?>

Documentation

See Also

explode()

The explode() function is used to break an array into a list of elements, based on a separator.

explode() uses the first argument as the separator, and the second as the string.

explode() has an alias called split().

explode() creates an empty string when the separator is at the beginning or the end of the strings. It also build empty strings when the separator are next to each other.

The separator has to be a static string. For dynamic separators, there is the preg_split() function.

explode() has a third parameter to limit the number of read elements. It is useful to avoid spending too much resources, such as time or memory, working on the string, when a maximum number of expected elements is known, and the string is not.

<?php

    print_r(explode('&', '&a=3&b') );
    // ['', 'a=3', 'b']

?>

Documentation

See Also

Exponent

Exponent, or exponentiation, is the mathematical operation to raise a number to the power of another number.

There are two possibilities to use this operation: the ** operator, and the pow() native function.

<?php

    echo pow(-3, 2); // displays 9 
    
    echo 2 ** 3;    // displays 8

?>

Documentation

See Also

Exponential

The exponential is a mathematical function. It satisfies the expressions: exp($a + $b) = exp($a) * exp($b), and exp(0) === 1.

There is a special expm1() function, which calculates the exponential value of $x - 1. When $x is close to 0, this function provides more significant digits than using the expression exp($x) - 1.

Exponential calculations may also be led with the constant M_E and the operator ** or the function pow(), although there is a slight difference.

<?php

    $e = exp(1); // also known as the contant M_E
    
    var_dump(exp(2) === M_E ** 2); // false
    var_dump(exp(2) - M_E ** 2);   // float(8.881784197001252E-16)

?>

Documentation

See Also

expose_php

The expose_php directive displays the usage of PHP and its version in the headers of the webserver.

It is considered a security leak to leave this configuration on, as it gives potential attackers information on the available technologies, and potential vulnerabilities. It is recommended to leave it off.

expose_php has no impact on the code itself.

Documentation

See Also

Expression

In PHP, an expression is a combination of one or more variables, operators, constants, and functions that evaluates to a single value. Expressions can be simple or complex, depending on the operations involved.

<?php

// one generic expression
$a = A + cos($b);

?>

Documentation

See Also

Expressive Interface

An expressive interface, refers to an API design pattern that makes code more readable, intuitive, and natural to write. It emphasizes clarity and ease of use, often resembling natural language.

The goal is to make your code self-documenting and reduce the cognitive load on developers reading or writing it.

An expressive interface is not related to an interface: it may be implemented without them.

The notion of expressive interface is similar to the fluent interface.

<?php

    class script {
        function hello() {
            print 'Hello ';
            return $this;
        }
    
        function word() {
            print 'word.';
            return $this;
        }
    }
    
    $script = new Script();
    
    $script->hello()->world();

?>

Documentation

See Also

extends

extends is an operator of the class inheritance. It indicates that a class is built from another one, or an interface is built from another interface. As such, the properties, constants and methods of the parent class or interface are available to the newly created class, unless when they are marked with private visibility.

extends is optional.

extends is unique with a class: it is not possible to extend several classes at the same time.

extends may be multiple with interfaces.

extends has a different mechanism than implements: implements provide method signature but no implementation; extends provides both.

<?php

    class Elephpant {
        function trumpet() { echo 'Elephpant'; }
    }

    class Calf extends Elephpant { }

    // Both methods are possible
    (new Elephpant)->trumpet();
    (new Calf)->trumpet();

?>

Documentation

See Also

Extension Method

An extension method, as found in C#, Kotlin, and Swift, lets a developer add a method to a type without modifying that type’s source and without subclassing it: fun String.shout() = this.uppercase() + '!' adds a shout() method callable on every String, including strings from the standard library. The compiler resolves the call statically, based on the static type of the receiver, and injects it as if it were a real member.

Extension methods are typically used to attach domain-specific behavior to library or built-in types, or to gradually retrofit an interface’s default methods onto existing implementations.

PHP has no extension method mechanism. Methods can only be added to a class by editing its source, extending it, or mixing in a trait, all of which require access to the class declaration or the willingness to create a subclass; a built-in type such as string or a final third-party class cannot receive new methods at all. The common workaround is a free function or a static helper class, called as Str::shout($value) instead of $value->shout().

<?php

    // PHP has no way to add shout() to string itself.
    final class Str {
        public static function shout(string $s): string {
            return strtoupper($s) . '!';
        }
    }
    
    echo Str::shout('hello'); // HELLO!, not 'hello'->shout()

?>

Documentation

See Also

Extensions

Extensions are a custom way to add features to software. Extension is a very generic concept, with broad usage.

  • PHP extensions
  • Extensions, as a concept.

Documentation

See Also

extract()

extract() is a native PHP function, which creates arrays from an array containing variables and their values.

extract() has option to handle situations where the variables are already existing, and how those conflicts should be handled: by default, it overwrites the local variables.

Options are: EXTR_OVERWRITE, EXTR_SKIP, EXTR_PREFIX_SAME, EXTR_PREFIX_ALL, EXTR_PREFIX_INVALID, EXTR_IF_EXISTS, EXTR_PREFIX_IF_EXISTS, EXTR_REFS.

This function is the opposite of compact().

<?php

    $a = 0; // $a is getting overwritten
    $array = extract(['a' => 1, 'b' => 2]);
    
    echo $a + $b; // 2

?>

Documentation

See Also

Function-as-a-Service (FaaS)

Function-as-a-Service, or FaaS, is a serverless execution model where individual functions are deployed, invoked on demand, and billed per execution. The cloud provider manages all infrastructure: provisioning, scaling, and teardown.

Each function is stateless, short-lived, and triggered by an event, such as an HTTP request, a queue message, a scheduled cron, or an S3 upload. The provider scales instances automatically from zero to thousands.

PHP runs on FaaS platforms through runtime layers. The most common approach is Bref, a PHP Lambda layer for AWS Lambda that handles bootstrapping the PHP runtime, forwarding events, and returning responses. Similar support exists for Google Cloud Functions and Azure Functions.

The main drawback of FaaS for PHP is cold start latency: the first invocation after an idle period must initialise the container and PHP runtime before executing. Subsequent invocations reuse the warm container and are fast.

<?php

// AWS Lambda handler via Bref (https://bref.sh)
// File: index.php

use Bref\Context\Context;

return function (array $event, Context $context): string {
    $name = $event['name'] ?? 'world';
    return 'Hello, ' . $name . '!';
};

// template.yaml (SAM):
// Resources:
//   HelloFunction:
//     Type: AWS::Serverless::Function
//     Properties:
//       FunctionName: hello
//       Runtime: provided.al2
//       Layers:
//         - !Sub arn:aws:lambda::534081306603:layer:php-83:x
//       Handler: index.php

?>

Documentation

Facade

A facade provides a simplified interface to a complex library. The facade hides the complexity, and iron out some of the dirty details away from the user.

Facades tends to ease the initial understanding of the library. Later, it limits expert usage and introduce unexpected behavior in the code.

The Laravel framework is known for its intensive usage of facades.

Documentation

See Also

Factory

A factory is a design pattern used to create objects without exposing the instantiation logic, i.e., the new keyword, to the client code. Instead of the client knowing exactly which class to instantiate, it asks the factory to produce the object for it.

<?php

// LoggerFactory.php
class LoggerFactory
{
    // Logger is an interface
    public static function createLogger(string $type): Logger
    {
        switch (strtolower($type)) {
            case 'file':
                return new FileLogger();
            case 'database':
            case 'db':
                return new DatabaseLogger();
            default:
                throw new InvalidArgumentException("Unknown logger type:" . $type);
        }
    }
}

?>

Documentation

See Also

Faker

A faker is a tool that generates fake data, for testing purposes.

Using a faker happens in different situations:

  • Seeding Databases: populating a database with sample users, products, or orders to test how your application performs under realistic conditions
  • Testing: creating dummy data for unit and integration tests to ensure the code works correctly in more realistic circumstances
  • Prototyping: quickly generating placeholder content, like names and addresses, for a new feature demonstration
  • Anonymizing Data: safely replacing sensitive production data with fake but realistic-looking data for use in development or debugging.

Documentation

See Also

Fallback Function

A fallback function is a function that replaces a function if its definition is not available in the current namespace.

PHP has implemented a mechanism so that functions that are undefined in the current namespace, have a fallback in the global space. This is important for backward compatibility, and the native PHP versions.

<?php

    namespace A {
        // A\strtolower doesn't exist, 
        // it falls back on \strtolower(), in the global space
        echo strtolower('A');
    }

?>

Documentation

See Also

Fallback To Global

The fallback to global mechanism is a PHP feature, which search for functions and global constants, first in the current namespace, then in the global namespace, before failing.

This feature was introduced as a transition mechanism, when namespaces were introduced. Adding a namespace to a file does not make all the function and constants invalid, but rather still working. This does not apply to classes, interfaces, traits and enumeration, which have to be in the current namespace, or imported with the use expression.

The fallback mechanism applies to global constants and functions.

This mechanism is usually transparent to users. It introduces the possibility of a man in the middle attack: adding a local definition to a global function or constant will overwrite this function.

There is a penalty cost to use the fallback mechanism, as PHP has to search for the function locally, then globally, before finding it. Using the fully qualified name, or an import expression use speeds up the process.

<?php

    namespace {
        function forage() { echo __FUNCTION__;}
        function bathe() { echo __FUNCTION__;}
    }

    namespace A {
        use function bathe as graze;

        function trumpet() { echo __FUNCTION__;}
        function bathe() { echo __FUNCTION__;}

        trumpet(); // A\trumpet;
        forage(); // forage;
        bathe(); // A\bathe;
        \bathe(); // bathe
        graze(); // A\bathe;
    
        // this replaces the native PHP strtolower with another function, 
        // in the A namespace
        function strtolower($string) { return \strtoupper($string);}
        
        echo strtolower('aB');  // AB
        echo \strtolower('aB'); // ab
    }

?>

Documentation

See Also

Fallback

A fallback refers to a backup plan or default behavior that is executed when the primary operation fails, is unavailable, or doesn’t meet certain conditions. It ensures that the system or application can function, either by default, or if something unexpected happens.

  • Fallback to global is the mechanism that uses PHP native function, in the global namespace, when they are not found in the local namespace
  • Fallback constant to string was a mechanism to use the literal constant name instead of its value, when the constant was not defined. It is now removed
  • A default value is a fallback mechanism.
<?php

    namespace A;
    
    // function A\strtolower does not exists, so it uses \strtolower
    echo strtolower('ABC');

?>

Documentation

See Also

Switch Fallthrough

A fallthrough is the absence of break, or equivalent, at the end of a switch case. That way, the execution continues on the next case.

While this is an intended feature, and is useful to reduce code, it tends to surprise programmers, who expect the cases to always end.

<?php

    switch ($a) {
        case 1:
            $a = 2 * $a;
            // fallthrough here : the execution continues
            
        case 2:
            $a = $a + 1;
            break;
    }

?>

Documentation

See Also

False

false has two usages, as a PHP keyword: the opposite of true, as a boolean value and a special type for functions that may return a boolean, but not true.

<?php

function trumpet($a) : false|Elephpant {
    if ($a == 1) {
        return false;
    } else {
        return new Elephpant();
    }
}

?>

Documentation

See Also

Falsy

A falsy value is a value that evaluates to false, when cast to a boolean. It includes false, obviously, but also other values such as 0, '', the empty string, or [], the empty array.

The contrary of falsy is truthy.

There are some falsy values which are difficult to guess, as is illustrated below.

<?php

var_dump((bool) 0);       // false
var_dump((bool) '');      // false
var_dump((bool) '0');     // false
var_dump((bool) '00');    // true
var_dump((bool) []);      // false
var_dump((bool) [null]);  // true
var_dump((bool) null);    // false

?>

Documentation

See Also

Fast Artificial Neural Network (FANN)

FANN, for Fast Artificial Neural Network, is a PIE extension that wraps the FANN C library, a lightweight library for creating, training, and running multilayer feedforward artificial neural networks.

The extension exposes functions to build a network with a chosen number of layers and neurons, train it against a data set using algorithms such as backpropagation, and then run inference on new inputs. Networks can be saved to and loaded from disk, so a model can be trained once and reused across requests without retraining.

FANN predates the current generation of PHP machine-learning libraries, and its API is comparatively low-level: it does not provide dataset preprocessing, model selection, or GPU acceleration. It remains useful for small, fast, embeddable networks where pulling in a heavier stack such as TensorFlow via a bridge is unnecessary.

<?php

    // Create a network: 2 inputs, one hidden layer of 3 neurons, 1 output.
    $ann = fann_create_standard(3, 2, 3, 1);

    fann_set_activation_function_hidden($ann, FANN_SIGMOID_SYMMETRIC);
    fann_set_activation_function_output($ann, FANN_SIGMOID_SYMMETRIC);

    // Train on a data file of input/output pairs (FANN training file format).
    fann_train_on_file($ann, 'xor.data', 5000, 500, 0.0001);

    $output = fann_run($ann, [1, -1]);
    print_r($output);

    fann_destroy($ann);

?>

Documentation

See Also

FastCGI

FastCGI stands for Fast Common Gateway Interface. It is a protocol, built on top of CGI. Unlike CGI, FastCGI has persistent processes that can handle more than one request before being destroyed. It also implements multiplexing.

PHP may be built as a fast CGI, in the php-fpm daemon.

Documentation

See Also

Fat Controller

A fat controller, also called a thick controller, is an anti-pattern in MVC architecture where the controller class accumulates too much business logic, data transformation, and persistence concerns. Instead of orchestrating, it does the actual work.

Fat controllers are hard to test, as they require a full HTTP stack, hard to reuse, and grow without bound as features are added.

The remedy is to extract business logic into services, domain objects, or command/query handlers, leaving the controller with a single responsibility: receive the request, call one service, return the response.

<?php

    // Fat controller: antipattern
    class OrderController {
        public function store(Request $request): Response {
            $data = $request->all();
            if (empty($data['email'])) {
                throw new \InvalidArgumentException('Email required');
            }
            $user = User::where('email', $data['email'])->first();
            if (!$user) {
                $user = User::create(['email' => $data['email']]);
            }
            $order = new Order();
            $order->user_id = $user->id;
            $order->total   = array_sum(array_column($data['items'], 'price'));
            $order->save();
            Mail::to($user)->send(new OrderConfirmation($order));
            return response()->json($order, 201);
        }
    }
    
    // Thin controller: preferred
    class OrderController {
        public function store(Request $request, OrderService $service): Response {
            $order = $service->create($request->validated());
            return response()->json($order, 201);
        }
    }

?>

Documentation

See Also

Fat

Fat is an informal qualifier applied to a class, most commonly a controller or a model, that has grown too large in terms of responsibilities, methods, and lines of code.

A fat class violates the Single Responsibility Principle. It is harder to test, understand, and maintain. Common symptoms include: many unrelated methods, large amounts of private helper code, direct database access mixed with business logic, and deep dependencies on infrastructure.

The opposite is a thin class, which delegates most work to collaborators. The right balance depends on architecture: an MVC application typically favours thin controllers and rich domain models or services.

Related terms: fat controller, fat model, god class, big ball of mud.

Documentation

See Also

Fatal Error

Fatal error is a type of PHP error, which ends the execution of the application. Fatal errors may be caught before ending the execution with a catch clause on Error.

<?php

    try {
        1 + [];
    } catch (Error $e) {
        print A fatal error was caught.;
    }

?>

Documentation

See Also

Fault Isolation

Fault isolation, also called failure isolation, is the design property that limits the impact, or blast radius, of a failure to the component or service where it originates, preventing it from cascading to other parts of the system.

In a tightly coupled system , such as monolith, distributed monolith, a failure in one subsystem can bring down the entire application. Fault isolation ensures that the failure of a payment service, for example, does not prevent users from browsing or adding items to their cart.

Common patterns that implement fault isolation: the circuit breaker, that stops sending requests to a failing service, the bulkhead which limits the resources a single consumer can use, preventing it from exhausting shared pools, and timeouts, that prevents a slow downstream from blocking threads indefinitely.

Microservices architecture promotes fault isolation by deploying each service independently. However, it requires explicit design: synchronous call chains without timeouts or circuit breakers produce the opposite: a single slow service that blocks all callers.

Fault isolation is implemented via timeout configuration on HTTP clients, circuit breaker libraries, and queue-based decoupling of non-critical side-effects.

<?php

    // Circuit breaker with a library (e.g., Ganesha or php-circuit-breaker)
    $circuitBreaker = Ackintosh\Ganesha\Builder::withRateStrategy()
        ->timeWindow(30)
        ->failureRateThreshold(50)
        ->build();
    
    if ($circuitBreaker->isAvailable('payment-service')) {
        try {
            $result = $paymentClient->charge($order);
            $circuitBreaker->success('payment-service');
        } catch (Exception $e) {
            $circuitBreaker->failure('payment-service');
            // Degrade gracefully: queue for retry, show user a message
            $retryQueue->push(new RetryPayment($order->id));
        }
    } else {
        // Circuit is open: skip the call entirely, don't block the user
        $retryQueue->push(new RetryPayment($order->id));
    }

?>

Documentation

See Also

fclose()

fclose() is a PHP native function that closes an open file pointer, previously created with fopen(), fsockopen(), or similar functions. It returns true on success, false on failure.

Closing a stream releases the underlying resource, file descriptor, socket, back to the operating system. Forgetting to call fclose() leads to a resource leak: on long-running processes, such as CLI scripts, workers or daemons, this can exhaust the number of file descriptors available to the process.

In most short-lived web requests, PHP automatically closes any remaining open handles at the end of the script, but explicit fclose() calls remain good practice, and are mandatory as soon as many files are opened in a loop, or the process runs indefinitely.

<?php

    $fp = fopen('data.txt', 'r');
    if ($fp) {
        $content = fread($fp, filesize('data.txt'));
        fclose($fp);
        echo $content;
    }

?>

Documentation

See Also

Feature Detection

Feature detection is the practice of testing, at runtime, whether a specific capability is actually available before using it, instead of inferring availability indirectly from something like a version number or a User-Agent string. The check answers ‘can I do this?’ directly, which stays correct even when the underlying assumption behind a version-based guess breaks, such as a backported feature, a polyfill, or a client that lies about what it is.

Feature detection commonly means checking function_exists() before calling an optional function, extension_loaded() before relying on an extension such as intl or gd, class_exists() or interface_exists() before referencing an optional dependency, or defined() before using a constant that may not exist on every PHP version or build. It is what makes a polyfill possible in the first place: the polyfill itself is only defined once feature detection has established that the native implementation is missing.

The browser equivalent is testing for a JavaScript API’s existence directly, such as if ('fetch' in window), rather than parsing the User-Agent string to guess which browser and version is making the request. User-Agent sniffing is brittle because the string is freely spoofable and does not necessarily reflect what the client actually supports, whereas feature detection tests the real thing and degrades gracefully, typically by falling back to a polyfill or an alternate code path, when the feature turns out to be missing.

<?php

    // feature detection: function
    if (!function_exists('str_contains')) {
        function str_contains(string $haystack, string $needle): bool {
            return strpos($haystack, $needle) !== false;
        }
    }

    // feature detection: extension
    if (extension_loaded('intl')) {
        $fmt = new NumberFormatter('fr_FR', NumberFormatter::CURRENCY);
    } else {
        // fallback formatting without intl
    }

    // feature detection: optional class/dependency
    if (class_exists(\Redis::class)) {
        $cache = new RedisCache();
    } else {
        $cache = new ArrayCache();
    }

?>

Documentation

See Also

Feature Flag

A feature flag, also known as a feature toggle or feature switch, is a software development technique used to enable or disable certain features or functionalities in an application or system. Instead of deploying new features directly to all users, developers can use feature flags to control the visibility and activation of these features.

Feature flags are typically implemented as conditional statements in the codebase, allowing developers to selectively enable or disable features based on various criteria such as user roles, user segments, environment conditions, or A/B testing groups. This allows for gradual feature rollouts, experimentation, and controlled releases, which can help mitigate risks associated with introducing new features or changes to a system.

<?php

    // feature flag implemented via PHP directives
    if (ini_get('date_is_visible')) {
        echo date('r');
    }

?>

Documentation

See Also

Feature Testing

Feature testing validates that multiple components of a system work together correctly by simulating real user workflows, exercising the application through its public interface, via HTTP requests, console commands, or a browser, rather than calling internal classes directly.

In the test pyramid, feature tests sit above unit tests and below full end-to-end tests: they typically boot a real application kernel, hit routes or commands, and assert on the resulting response, database state, or emitted events, without necessarily driving a real browser.

PHP frameworks provide dedicated tooling for this style of testing: Laravel ships feature tests that extend Illuminate\Foundation\Testing\TestCase and can call routes via $this->get() or $this->post(); Symfony offers WebTestCase and Panther for browser-driven scenarios; Behat and Codeception let teams describe scenarios in Gherkin, with Given/When/Then, and run them against the real stack.

Documentation

See Also

Feature

A software feature is a specific functionality or capability that is designed and implemented within a software application to provide a specific benefit or serve a particular purpose. Features are the building blocks that make up the overall functionality of a software product, and they are what enable users to perform tasks, achieve goals, or solve problems using the software.

Software features can vary widely depending on the type of application and its intended use. For example, in a word processing software, features might include the ability to format text, insert images, create tables, and perform spell-checks. In a video editing software, features might include cutting, trimming, adding effects, and exporting videos in different formats. In a messaging app, features might include sending text messages, multimedia messages, and voice calls.

Developers prioritize and implement features based on user needs, market demand, and the overall vision for the software. As software evolves, new features may be added to enhance its functionality or to keep up with advancements in technology and user expectations. Additionally, user feedback and requests often play a role in determining which features get added or improved in future updates of the software.

Documentation

See Also

Foreign Function Interface (FFI)

Foreign Function Interface, also known as FFI allows loading external libraries, such as .DLL or .so, and access directly their function without writing a PHP extension.

<?php

    // Extracted from the PHP manual
    
    // create FFI object, loading libc and exporting function printf()
    $ffi = FFI::cdef(
        "int printf(const char *format, ...);", // this is a regular C declaration
        "libc.so.6");
    // call C's printf()
    $ffi->printf("Hello %s!\n", world);

?>

Documentation

See Also

fgetc()

fgetc() is a PHP native function that reads a single character from an open file pointer. It returns a string containing one byte, or false when the end of the file, EOF, is reached.

Key characteristics:

  • Reads exactly one byte per call, making it the slowest way to read a file, but the finest-grained
  • Returns false on EOF, which must be checked with === since "0" or an empty string are otherwise valid, falsy-looking results
  • Binary-safe, like the other stream functions

fgetc() is typically used to build custom character-by-character parsers, for instance for CSV-like formats with unusual quoting rules, or for reading protocols where the message boundary is not a newline. For line-based reading, fgets() is far more efficient; for reading arbitrary chunks, fread() is preferred.

<?php

    $fp = fopen('data.txt', 'r');
    if ($fp) {
        while (($char = fgetc($fp)) !== false) {
            echo $char;
        }
        fclose($fp);
    }

?>

Documentation

See Also

fgets()

fgets() is a PHP native function that reads a single line from an open file pointer, up to and including the next newline character, or until an optional length limit of bytes is reached. It returns the line as a string, or false when the end of file, EOF, is reached.

Key characteristics:

  • Stops at the first \n found, or after length - 1 bytes if a length is provided
  • The trailing newline is kept in the returned string, and often needs to be trimmed with rtrim() or trim()
  • Binary-safe

fgets() is the standard way to process a text file line by line, for instance log files or CSV files, without loading the whole file into memory, unlike file() or file_get_contents(). It is commonly combined with feof() to detect the end of the stream.

<?php

    $fp = fopen('access.log', 'r');
    if ($fp) {
        while (($line = fgets($fp)) !== false) {
            echo trim($line) . PHP_EOL;
        }
        fclose($fp);
    }

?>

Documentation

See Also

Fibers

Fibers are a low-level mechanism for lightweight concurrency, they allow to pause and resume blocks of code at specific points without blocking the rest of the application.

They were introduced in version 8.1 and provide cooperative multitasking, as opposed to preemptive multitasking like threads. This means the application controls exactly where execution yields and resumes.

<?php

    $fiber = new Fiber(function (): void {
       $value = Fiber::suspend('fiber');
       echo "Value used to resume fiber:", $value, PHP_EOL;
    });
    
    $value = $fiber->start();
    
    echo "Value from fiber suspending:", $value, PHP_EOL;
    
    $fiber->resume('test');

?>

Documentation

See Also

First In, First Out (FIFO)

First In, First Out is the principle of management of a queue. The first added element is the first one to be removed. This is exactly how a queue behaves: it is also the way a line at the cashier behaves.

The other management is LIFO: last in, first out.

Documentation

See Also

File Extension

File extensions are the suffixes at the end of file names that indicate the type or format of the file. They typically come after a period . in the file name.

File extensions help PHP recognize the file type and determine which program should be used to open it. They should not be used as a security feature, but rather as a hint of the content.

<?php

$files = glob("directory/*.ini");

foreach($files as $file) {
    // displays the file name, without the file extension
    print basename($file, '.ini').PHP_EOL;
}

?>

Documentation

See Also

File Mode

The file mode is the configuration of the pointer when accessing to the file.

In the example above, w+ indicates that the file is open for writing and reading, and place the pointer at the beginning of the file.

There are several valid modes: ‘r’, ‘r+’, ‘w’, ‘w+’, ‘a’, ‘a+’, ‘x’, ‘x+’, ‘c’, ‘c+’, ‘e’. Check docs for details about them.

<?php

    $fp = fopen($file, 'w+');

?>

Documentation

See Also

File

A file is a named collection of data or information that is stored and organized on a computer’s storage system. In computing, files are used to store various types of data, such as text, images, audio, video, programs, and more. Files can be created, accessed, modified, and deleted by computer programs and users.

Files are typically organized into a hierarchical structure called a file system, which helps to manage and organize them. Each file is identified by a unique name, which allows it to be located and accessed within the file system. Files can be stored on different types of storage media, including hard drives, solid-state drives, network storage, and removable storage devices such as USB drives.

A file consists of two main components: the file name and the file content. The file name is used to identify and refer to the file, while the file content contains the actual data stored within the file. The content can vary depending on the type of file, such as plain text, binary data, or specific file formats.

A file is a resource for recording data on a computer storage device, such as a hard drive or memory.

file:// is also the name of a wrapper, for stream.

<?php

    file_put_contents('file.txt', 'some text.');

?>

Documentation

See Also

file_get_contents()

file_get_contents() is a PHP native function, which reads all data from a file, in one call. The function requires the file name, or a valid URI, with its path of storage in the file system.

The function also includes options to handle concurrency with locks; to append data rather than overwrite them with FILE_APPEND, and a restriction to use file in the include_path configuration.

file_get_contents() returns a string, or false in case of error. The maximum size of the returned string may be limited by configuration.

file_get_contents() works with streams to reach network files. It also supports wrappers, to use various predefined and custom protocols, such as https, file, zip, etc.

<?php

    $json = file_get_contents('/path/to/config.json');

?>

Documentation

See Also

file_put_contents()

file_put_contents() is a PHP native function, which stores data in a file, in one call. The function requires only the file name, with its path of storage in the file system, and the actual data to store.

The function also include options to handle concurrency with locks; to append data rather than overwrite them with FILE_APPEND, and a restriction to use file in the include_path configuration.

file_put_contents() accepts about any type of data, to store them on a file, yet strings are the best fitted for that. Scalar types are converted to a string; arrays are imploded, with the empty string as separator, and no recursive processing, and objects are converted to string, when the magic method __toString() is available, otherwise, they are ignored.

<?php

    file_put_contents('/tmp/path/to/file.txt', 'Hello file');

?>

Documentation

See Also

File System

A file system is a method or structure used by operating systems to organize, store, and manage files and data on storage devices such as hard drives, solid-state drives, USB drives, and network-attached storage. It provides a logical and efficient way to store and retrieve data on these storage media.

<?php

    file_put_contents('file.txt', 'some text.');

?>

Documentation

See Also

FileSystemIterator

The FilesystemIterator class is part of the SPL Library and is used for iterating over the contents of a directory. It extends the DirectoryIterator class and provides additional features for working with file system entries.

<?php

    $it = new FilesystemIterator(dirname(__FILE__), FilesystemIterator::CURRENT_AS_FILEINFO);
    foreach ($it as $fileinfo) {
        echo $fileinfo->getFilename() . \n;
    }

?>

Documentation

See Also

filter

The filter extension is a built-in extension that provides an efficient way to filter, validate and sanitize data. Give it a string, and check that it satisfies a specific format.

filter works on incoming data, such as $_GET or $_POST, but also on free variables.

<?php

$data = [
    'age' => '123 years',
    'name'  => 'John Doe',
];

$filters = [
    'age'   => FILTER_VALIDATE_INT,
    'name'   => FILTER_SANITIZE_ENCODED,
];

print_r(filter_var_array($data, $filters));

?>

Documentation

See Also

Filter_var()

filter_var() filters a single variable with a specified filter, either validating its content or sanitizing it.

The first argument is the value to filter. The second argument is one of the FILTER_VALIDATE_* or FILTER_SANITIZE_* constants, such as FILTER_VALIDATE_EMAIL, FILTER_VALIDATE_INT or FILTER_SANITIZE_FULL_SPECIAL_CHARS, defaulting to FILTER_DEFAULT when omitted.

Validation filters return the filtered value, converted to the expected type, or false when the value does not pass validation. Since false is also a legitimate filtered value for some filters, it is recommended to compare the result with === rather than relying on truthiness. An optional third argument accepts flags and options, such as a regular expression for FILTER_VALIDATE_REGEXP.

<?php

    $email = 'user@example.com';
    
    if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
        print 'Invalid email address';
    } else {
        print 'Valid email address';
    }

?>

Documentation

See Also

Final Class Constants

Using the final option with class constants, the constant cannot be redefined by a child class. It is not possible to give it a new value or visibility.

It yields a fatal error: y::x cannot override final constant.

<?php

    class Elephpant {
        final public const HABITAT = 1;
        public const WEIGHT = 2;
    }

    class Calf extends Elephpant {
        // this is an error
        public const WEIGHT = 3;
    }

?>

Documentation

See Also

Final Keyword

The final keyword prevents child classes from overriding a method or a constant by prefixing the definition with final.

The final keyword cannot be used with the private keyword: a private method is not visible in the child classes, and can’t also be redefined.

<?php

    final class Elephpant {
        final const HABITAT = 1;

        final function method() { }
    }

?>

Documentation

See Also

Finally

Finally is the default clause of a try-catch expression. It is run after all the catch clauses have been called.

Finally is run every time after a try, with or without any catch clause. It is also run before the return expression, if any.

<?php

    try {
        doSomething();
    } catch (\Exception $e) {
        print "An exception was raised and caught";
    } finally {
        print "Finally\n";
    }

?>

Documentation

See Also

finfo

finfo is a native PHP class, part of the Fileinfo extension, that detects the MIME type and encoding of a file or a string buffer by inspecting its content, using the libmagic library, rather than trusting its filename or extension.

finfo is instantiated with a mode constant, such as FILEINFO_MIME_TYPE, and then queried with $finfo->file($path) or $finfo->buffer($content).

Since the value provided by $_FILES[...]['type'] is supplied by the client and cannot be trusted, finfo is the recommended way to validate the real type of an uploaded file before storing or processing it. It replaces the deprecated mime_content_type() function.

<?php

    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $mimeType = $finfo->file($_FILES['userfile']['tmp_name']);

    if ($mimeType !== 'image/png') {
        throw new RuntimeException('Only PNG files are allowed.');
    }

?>

Documentation

See Also

Fingerprint

A fingerprint is a compact, deterministic identifier derived by hashing a set of attributes that together describe something uniquely. The same inputs always produce the same fingerprint; different inputs produce a different one.

In the context of HTTP request idempotency, a request fingerprint is computed from the method, route, query string, payload, and content type. It is stored alongside the idempotency key so that retried requests carrying the same key but a different payload can be detected and rejected.

More broadly, fingerprinting is used for cache keying, change detection, file integrity checks, and browser device identification.

<?php

$fingerprint = hash('sha256', implode('|', [
    $request->method(),
    $request->path(),
    $request->getQueryString() ?? '',
    $request->getContent(),
    $request->header('Content-Type', ''),
]));

?>

Documentation

See Also

Finite State Machine (FSM)

A finite state machine, also called FSM, also called a finite automaton, plural automata, is a mathematical model used to design systems that can be in one of a finite number of states at any given time. The machine transitions between these states in response to inputs or events, following a set of rules.

Documentation

See Also

Fire-and-forget

Fire-and-forget is a pattern where a task is dispatched and the caller does not wait for its result, does not check for errors, and does not expect a return value. The caller continues execution immediately after dispatching.

Common uses include sending emails, dispatching jobs to a queue, logging, analytics events, and cache invalidation: any side-effect that should not delay the main response.

In synchronous code, fire-and-forget is often approximated by closing the HTTP response early, fastcgi_finish_request(), and continuing processing, or by pushing work onto a message queue, like Redis, RabbitMQ, SQS, etc. With fibers or async runtimes such as ReactPHP, AMPHP, Revolt, etc. true non-blocking dispatch becomes possible.

The risk of fire-and-forget is silent failure: if the dispatched task errors, the caller has no way to detect or recover from it. Robust implementations route failures to a dead-letter queue or structured log.

<?php

    // Approximated in sync PHP via fastcgi_finish_request()
    ob_start();
    echo 'Response sent to client.';
    $size = ob_get_length();
    header('Content-Length: ' . $size);
    header('Connection: close');
    ob_end_flush();
    flush();
    fastcgi_finish_request(); // client receives the response here
    
    // Work runs after the client is disconnected
    dispatch_slow_email($user);
    
    // With a queue (true fire-and-forget)
    $queue->push(new SendEmailJob($user));
    // caller does not wait — queue worker handles it asynchronously

?>

Documentation

See Also

Firewall

A firewall, in a web application, is a layer that inspects incoming requests and decides which ones are allowed to reach the application, before any business logic runs. The term covers two related but distinct things in the PHP ecosystem.

At the infrastructure level, a WAF, Web Application Firewall, sits in front of the application, at the network or reverse-proxy layer, filtering requests based on patterns: blocking SQL injection attempts, known bad IP ranges, or malformed requests, entirely outside of PHP.

At the application level, frameworks such as Symfony use firewall to name a configured authentication pipeline: each firewall matches a set of URL patterns and defines how users are identified, login form, API token, JWT, for the requests that fall under it. A request that fails to authenticate against its firewall is rejected before reaching any controller, exactly like a network firewall rejects a packet before it reaches a service.

Both meanings share the same idea: a firewall is a checkpoint that lets legitimate traffic through and stops the rest as early as possible, minimising the amount of code that has to defend itself against malicious input.

<?php

    // Application-level firewall: a minimal authentication gate in front of routes,
    // conceptually similar to Symfony's security firewalls.
    final class Firewall
    {
        /** @param array<string,string> $patterns URL pattern => required role */
        public function __construct(private array $patterns, private AuthChecker $auth) {}
    
        public function handle(string $path, ?string $token): void
        {
            foreach ($this->patterns as $pattern => $role) {
                if (!preg_match($pattern, $path)) {
                    continue; // this firewall segment doesn't cover the request
                }
    
                if (!$this->auth->isGranted($token, $role)) {
                    throw new UnauthorizedException("Access denied to $path");
                }
    
                return; // authenticated: request may proceed to the controller
            }
        }
    }
    
    $firewall = new Firewall(
        patterns: ['#^/admin#' => 'ROLE_ADMIN', '#^/api#' => 'ROLE_API'],
        auth: new AuthChecker(),
    );
    
    $firewall->handle('/admin/users', token: null); // rejected before reaching any controller

?>

Documentation

See Also

First Class Callable

First Class Callable Syntax is a new feature that creates a closure directly from a function, by using the triple dot operator as an argument.

First class callable may be used on functions, closures, arrow functions and methods and static methods.

The number of arguments is not important: it is the same as the actual definition of the underlying method, and will be checked at call time only.

Such closure may be created using any kind of function, such as native PHP function, or library methods.

<?php

    $a = trumpet(...);

    $function = strtolower(...);

    $closure = Elephpant::staticMethod(...);

?>

Documentation

See Also

First-Class Module

In OCaml and a few other ML-family languages, a module can itself be treated as an ordinary value: passed as a function argument, returned from a function, stored in a data structure, or chosen at runtime among several implementations of the same module signature, using a construct such as (module M : SIG). This lets an entire package of types and functions be selected or swapped dynamically, the way an object implementing an interface would be in an object-oriented language, but at the granularity of a whole module rather than a single instance.

This differs from ordinary module systems, where a module is only a static, compile-time unit of organization: something that import by name, but never hold, pass around, or compute with as a value.

PHP has no module construct at all, first-class or otherwise; a namespace is a compile-time naming device with no runtime representation and cannot be assigned to a variable, passed as an argument, or chosen dynamically. The closest PHP comes to swapping an entire package of related functionality at runtime is choosing between classes, typically through dependency injection or a factory that returns different objects implementing the same interface.

Documentation

See Also

Fixture

A fixture is a set of test data. They are used to set up the environment in a known state, so that to run the test in good conditions.

Fixtures typically populate a database, a filesystem, or an object graph with predictable values before a test runs, and are torn down afterward so that one test cannot leak state into the next. With PHPUnit, this is often done through setUp() and tearDown() methods, or through dedicated fixture files loaded per test case or test suite.

Good fixtures make tests deterministic and repeatable: the same input state produces the same result every time, regardless of the order in which tests run or what ran before them. Poorly managed fixtures, by contrast, are a common source of flaky tests, since hidden dependencies between tests can make outcomes depend on execution order.

Documentation

See Also

Flag

A flag is another name for an option. Often, flags are booleans: they are either on, or off.

Flags are often consecutive powers of 2, so they can be merged together by addition + or by logical or |, and passed as one.

Example of flags:

  • preg_match(), fourth argument: PREG_OFFSET_CAPTURE and PREG_UNMATCHED_AS_NULL;
  • json_decode(), fourth argument: JSON_BIGINT_AS_STRING, JSON_INVALID_UTF8_IGNORE, JSON_INVALID_UTF8_SUBSTITUTE, JSON_OBJECT_AS_ARRAY, JSON_THROW_ON_ERROR;
  • ArrayObject::setFlags(), first argument: ArrayObject::STD_PROP_LIST or ArrayObject::ARRAY_AS_PROPS.
<?php

    $string = 'adg';
    
    preg_match('/([abc])([def])/', $string, $r, PREG_OFFSET_CAPTURE);
    print_r($r);
    /**
    Array
(
    [0] => ad
    [1] => a
    [2] => d
)
*/
    
    preg_match('/([abc])([def])/', $string, $r, PREG_OFFSET_CAPTURE);
    print_r($r);
/**
Array
(
    [0] => Array
        (
            [0] => ad
            [1] => 0
        )

    [1] => Array
        (
            [0] => a
            [1] => 0
        )

    [2] => Array
        (
            [0] => d
            [1] => 1
        )

)
*/
?>

Documentation

See Also

Flame Graph

Flame graphs are a visualization tool used to understand where a program spends its time, especially useful for performance profiling.

They help quickly spot hot paths in code: functions or routines that consume the most CPU or other resources.

Documentation

See Also

Flexibility

Flexibility means that a piece of code can change the way it works, without changing the code that uses it.

The piece of code may be refactored, or changed in place, or it may also be duplicated with another method. Mocking, or the ability to emulate a simpler version of a class, is also a possible inner working change.

Abstraction, with interfaces, proxy classes or relay functions, are ways to introduce flexibility.

The opposite of flexibility is rigidity.

Documentation

See Also

Floating Point Numbers

Floating point numbers, also known as floats, doubles, or real numbers, can be specified using a decimal dot and a mantissa.

They may also use a number separator _: it may be placed anywhere between two digits, to help make the number more readable.

Floats used to be called real, though this was abandoned progressively, since PHP 7.0.

Floats are stored in binary, and most decimal fractions, such as 0.1, have no exact binary representation. This makes direct equality comparison a classic bug: 0.1 + 0.2 === 0.3 is false, since the actual stored value is 0.30000000000000004. To compare floats safely, check that the absolute difference is below a small tolerance, also known as an epsilon, rather than using == or ===.

<?php

    $a = 1.234; 
    $b = 1.2e3; 
    $c = 7E-10;
    $d = 1_234.567; // as of PHP 7.4.0

    var_dump(0.1 + 0.2 === 0.3); // false, classic bug
    var_dump(abs((0.1 + 0.2) - 0.3) < PHP_FLOAT_EPSILON); // true, safe comparison

?>

Documentation

See Also

Fluent Interface

A fluent interface, or fluid interface, is an object-oriented API whose design relies extensively on method chaining.

A fluent interface is not related to an interface: it may be implemented without them.

<?php

class script {
    function hello() {
        print 'Hello ';
        return $this;
    }

    function word() {
        print 'word.';
        return $this;
    }
}

$script = new Script();

$script->hello()->world();
// 

?>

Documentation

See Also

fnmatch()

fnmatch() is a native function for matching. it applies the shell wildcard patterns to a string, and returns if it matches or not.

Wildcards include:

  • * for anything
  • ? for zero or one character
  • [] for a range of characters
  • ! to negate characters in a bracket syntax
  • \ as the escape character

The search is case sensitive.

This function is useful to emulate a common system of search.

Simpler search tools include str_contains() and strpos(), and more complex include preg_match().

<?php

    $message = 'PHP rocks';
    if (fnmatch('*r[oi]cks', $message)) {
      echo 'But, of course...';
    }

?>

Documentation

See Also

Folklore

The PHP community’s folklore is all the non-language related creations, that serves as a link in the community.

  • ElePHPant
  • Double claw hammer
  • Wurst conference
  • PHP 6
  • Footgun
  • Vanilla
  • PHP is dead
  • …This is by no mean an exhaustive list.

Documentation

See Also

Footgun

A footgun is a feature or a piece of code that makes it easy to unintentionally shoot oneself in the foot: it works as documented, yet its default behavior, its naming, or its side effects are so counter-intuitive that developers routinely misuse it and cause bugs, security holes, or data loss.

Unlike a straightforward bug, a footgun is working as intended: the language or the library designer chose that behavior on purpose, often for historical or backward-compatibility reasons. The danger comes from the gap between what the code looks like it does, and what it actually does.

PHP has accumulated a fair number of footguns over the years, among them:

  • eval(), which executes arbitrary strings as PHP code, and opens the door to code injection when fed external data
  • The == comparison operator, whose type juggling once made 'abc' == 0 evaluate to true
  • extract(), which imports an entire array into the current symbol table, potentially overwriting existing variables
  • Variable variables $$name, which make static analysis and refactoring unreliable
  • The @ error suppression operator, which silences every error, warning, and notice of an expression, hiding real problems
  • unserialize() on untrusted data, which can trigger object injection through __wakeup() or __destruct()
  • Passing arguments by reference, which lets a function silently modify a variable in the caller’s scope
  • Loose typing in switch and in_array(), which relies on the same type juggling rules as ==
  • array_merge() versus the + operator on arrays, which handle numeric keys and duplicate keys very differently

Static analysis tools can flag most of these footguns automatically, before they misfire in production.

<?php

    // Footgun: type juggling with ==
    var_dump('abc' == 0); // true in version 7, false in version 8

    // Footgun: extract() overwriting existing variables
    $isAdmin = false;
    extract($_GET); // if $_GET['isAdmin'] = 1, $isAdmin becomes 1

    // Footgun: eval() on external data
    eval('$name = ' . $_GET['name'] . ';'); // arbitrary code execution

    // Footgun: @ hides the actual error
    $data = @json_decode($json); // fails silently, $data is null

?>

Documentation

See Also

fopen()

fopen() is a PHP native function which opens a file. It returns a file description, also called handle, that may be used with other PHP file functions to read and write data from and to the files.

fopen() may also be replaced by the SplFileObject class, which provides an OOP syntax alternative to access files.

<?php

    $fp = fopen('/tmp/test.txt', 'r');
    fwrite($fp, 'PHP rocks!');
    fclose($fp);

?>

Documentation

See Also

For

for() is a loop structure. It is configured with an initialization expression, an ending expression and an increment expression.

The for() loop executes the initialization expression first, and only once. Then it executes the block, the increment and the ending. When the ending is false, it exits the loop.

The initialization, ending and increment expression may all host several instructions: they have to be separated by comma, rather than semi colons.

Part of the block execution may be skipped by using the continue keyword.

<?php

    /*
    for(initialization; ending; increment) {
        block
    }
    */
    
    for($i = 0; $i < 10; ++$i) {
        print "$i\n";
    }
    
    for($i = 0, $j = 0; $i < 10; ++$i, $j += 2) {
        print "$i $j\n";  // 1 2, 2 4, 3 6....
    }

?>

Documentation

See Also

foreach()

foreach() is the most popular type of loop.

The foreach() loop uses all the elements of the source, and assign them to blind variables. By default, only the value is assigned; when using the $key => $value syntax, the key is also assigned. Then the block is executed with the assigned values.

The source may be an array, or an object with the Traversable interface: this includes iterators and generators, but also custom classes. Other types are forbidden.

Part of the block execution may be skipped by using the continue keyword.

The value may be a reference: then it actually references the original value, which then may be modified in the source. Do not forget to unset referenced variables after the loop, to avoid the dangling reference syndrome, when the last value is changed.

The value may be an array, collecting several values at the same time.

The value may be an list() construct: it sets several variables at the same time, to be used in the loop block. Any missing value yields a warning.

foreach() may also be replaced by array functions, such as array_map(), implode() or array_merge(), for specific operations. It is usually recommended to use native functions, when available.

<?php

    /*
    foreach($source as $key => $value) {
        // block
    }
    */
    
    foreach([11,12,13] as $id => $value) {
        print "$id => $value\n";
        // 0 => 11
        // 1 => 12
        // 2 => 13
    }
    
    //foreach([[21,22], [33, 34]] as list($a, $b)) {
    foreach([[21,22], [33, 34]] as [$a, $b]) {
        print "$a $b\n";
        // 21 22
        // 33 34
    }

?>

Documentation

See Also

Foreign Key (FK)

A foreign key, or FK, is a column, or set of columns, in a relational database table that references the primary key of another table. It establishes and enforces a link between the two tables, ensuring that the referencing value actually exists in the referenced table.

Foreign keys are the mechanism behind referential integrity: the database engine rejects an insert or update that would point to a non-existent row, and, depending on the ON DELETE/ON UPDATE clause, either blocks, cascades, or nullifies dependent rows when the referenced row is deleted or changed.

In applications, foreign keys are usually declared in migrations, through an ORM such as Doctrine or Eloquent, or directly in SQL DDL. Bulk imports, ETL jobs, and data migrations are common places where foreign key violations surface, when a referenced row was skipped, renamed, or failed to convert, so the constraint is exactly what would catch that class of bug, if it is enforced instead of being disabled for import speed.

<?php

    // Doctrine migration declaring a foreign key
    $table->addColumn('customer_id', 'integer');
    $table->addForeignKeyConstraint(
        'customer',
        ['customer_id'],
        ['id'],
        ['onDelete' => 'CASCADE']
    );

?>

Documentation

See Also

Form

A form is a web page component to collect and submit information.

The form submits the information using HTTP protocol, and the GET or POST method. It is generally processed by the browser.

The form defines variable, whose content is submitted to the PHP script. Those values are accessed with $_GET, $_POST, $_REQUEST.

Form is an HTML element, in a web page. As such, it may be created by PHP, when PHP produces HTML documents.

Documentation

See Also

Format

Format is a set of rules to structure a piece of text, and make it parsable by a specific engine. A piece of text may be in the format: then, it is usable as a command for another technology.

Formats have various shapes. Here are some examples of formats:

  • SQL Structure Query Language: SELECT column FROM table
  • Date and time: 2020-01-01
  • sprintf(), with %d 9
  • Regular expressions
  • YAML
  • INI
  • CSV
  • JSON

It is possible to define one’s custom format. Common formats have comprehensive specifications, such as how to build them, and assorted tools, to encode, decode, use, combine, etc.

<?php

    // displays 123 with 9 characters, and fills with dots any empty characters
    // ......123
    echo sprintf("%'.9d\n", 123);

?>

Documentation

See Also

Forum

A forum is a web application that allows users to hold structured discussions online.

A forum, also called a discussion board, is software where users can:

  • Create discussion topics
  • Post replies
  • Organize conversations into categories
  • Interact through comments, reactions, or private messages

It’s one of the earliest and most common types of PHP web applications.

The PHP ecosystem offers a lot of forums. Here is a non-exhaustive list:

  • phpBB
  • MyBB
  • Flarum
  • Simple Machines Forum
  • XenForo
  • PunBB
  • ElkArte.

Documentation

Forward Compatible

A forward compatible feature is a feature that will be available in future versions. In particular, it might be couple with a forward incompatible feature, which will be dropped, while the forward compatible feature will stay.

For example, PHP allows the increment of non-numeric strings. This feature might be deprecated, and could be removed in a future version, not defined at the time of writing. The functions str_increment() and str_decrement() were introduced in version 8.3. They can replace the current feature, and they will be available in the future versions, making them forward compatible.

<?php

    $a = 't';
    echo ++$a; //u
    
    $a = str_increment($a);
    echo $a; // v

?>

Documentation

See Also

Fossilized Methods

A method become fossilized when it is overwritten many times, creating a difficult update of the method signature, without impacting many parts of the code.

The easiest solution to this situation is to refrain from updating the signature anymore. At that point, the method is fossilized.

<?php

class Elephpant {
    function trumpet(Herd $a) : array {}
}

class AfricanElephpant extends Elephpant {
    function trumpet(Herd $a) : array {}
}

class AsianElephpant extends Elephpant {
    function trumpet(Herd $a) : array {}
}

// Updating this method means updating AsianElephpant, AfricanElephpant, Elephpant...
class Calf extends Elephpant {
    function trumpet(Herd $a) : array {}
}

?>

Documentation

See Also

FastCGI Process Manager (FPM)

FPM stands for FastCGI Process Manager. It is a PHP FastCGI implementation.

Instead of nesting PHP in the web server, php-fpm makes PHP a server by itself. The web server then delegates the work to the PHP server. The advantage is to lower the memory footprint of PHP and the web server, and the whole of them both. It helps with stability, by keeping the two processes separated.

Documentation

See Also

Framework

A framework is a library of code and practices that helps building PHP applications. Frameworks provide common features, such as forms, authentications, templating, database access and security.

Frameworks are often described as a platform: they stand as a layer above PHP, with its own conventions and behaviors. PHP is the language of the framework, and the language used to extend the framework.

Frameworks provide a set of tools and components to build applications, though they usually do not provide a comprehensive service out of the box: the framework must be used to build the application, usually in an original and creative way. For example, a framework may be used to build a forum or a CMS, while the opposite is rarely possible.

There are lots of frameworks written with PHP. In alphabetical order, here is a non exhaustive list:

  • Aura <https://auraphp.com/>_
  • Bolt CMS <https://boltcms.io/>_
  • Code Igniter <https://codeigniter.com/>_
  • CakePHP <https://cakephp.org/>_
  • Cappuccino <https://www.cappuccino.dev/>_
  • Drupal <https://www.drupal.org/>_
  • e107 <https://e107.org/>_
  • FuelPHP <https://fuelphp.com/>_
  • Gyroscope <https://www.gyro-php.org/>_
  • Hyperf <https://github.com/hyperf/hyperf>_
  • Ibexa <https://www.ibexa.co/>_
  • Joomla <https://www.joomla.org/>_
  • Koala <http://www.koala-framework.org/>_
  • Laminas <https://getlaminas.org/>_
  • Laravel <https://laravel.com/>_
  • Leafphp <https://leafphp.dev/>_
  • Light-php <https://github.com/bakeiro/Light-PHP.git>_
  • LightMVC <https://github.com/lightmvc/lightmvcskel.git>_
  • Lithium <https://li3.me/>_
  • Medoo <https://medoo.in/>_
  • Nette <https://nette.org/en/>_
  • October <https://octobercms.com/>_
  • Phalcon <https://phalcon.io/en-us>_
  • Prado <http://www.pradoframework.net/site/>_
  • Qcodo <https://github.com/qcodo/qcodo.git>_
  • redcatphp <https://github.com/redcatphp/redcatphp>_
  • Slim <https://www.slimframework.com/>_
  • Symfony <https://symfony.com/>_
  • Typo3 <https://typo3.org/>_
  • Ubiquity <https://github.com/phpMv/ubiquity>_
  • Wordpress <https://www.wordpress.org/>_
  • X <https://github.com/clue/framework-x.git>_
  • Yii <https://www.yiiframework.com/>_
  • Zend Framework <https://framework.zend.com/>_

This is not an exhaustive list.

Documentation

See Also

fread()

fread() is a PHP native function that reads up to length bytes from the file pointer referenced by stream. It is one of the fundamental file reading functions.

Key characteristics:

  • Returns a string of up to length bytes, or false on failure
  • Reads binary-safe data, making it suitable for both text and binary files
  • Stops reading when EOF, end of file, is reached or the specified length is reached
  • For character encodings like UTF-8, reading by byte length may split multi-byte characters; consider using fgetc() or fgets() for text files

fread() is typically used after fopen() and should be paired with fclose() to free resources. For reading entire files at once, file_get_contents() is more convenient. For line-by-line reading, fgets() is preferred.

<?php

    $fp = fopen('data.txt', 'r');
    if ($fp) {
        // Read first 100 bytes
        $content = fread($fp, 100);
        echo $content;

        // Read remaining content
        $remaining = fread($fp, filesize('data.txt') - 100);
        echo $remaining;

        fclose($fp);
    }

?>

Documentation

See Also

Free

Free, or libre when the freedom sense needs to be distinguished from gratis, in a software context has two distinct meanings that are often conflated:

  • Free as in freedom: the user has the right to run, study, modify, and redistribute the software. This is the definition used by the Free Software Foundation, FSF, and the GNU project. A free-as-in-freedom licence grants these four essential freedoms
  • Free as in gratis: the software has no monetary cost. This says nothing about the rights granted to the user
  • Free as in release memory: the action of releasing hold on a resource, such as memory, file handler, etc. PHP implicitly frees resources when leaving a context, or finishing execution

PHP itself is free in both senses: it has no cost and its source code is open and modifiable. However, PHP applications can be distributed under any licence, including proprietary ones.

The distinction matters when evaluating dependencies: a library that is free-of-charge but does not allow redistribution or modification is not free software. Open source licences generally grant both freedoms, though GPL is copyleft and imposes conditions on derived works.

Documentation

See Also

Front-end

Front-end refers to the software that runs on the client, and not on the servers. Javascript is a typical front-end language.

The complement to front-end is the backend.

Documentation

See Also

fseek()

fseek() is a native PHP function that sets the file position indicator for a file pointer.

It moves the file pointer to a specified position, allowing random access to file content. This is useful for reading or writing specific parts of a file without processing the entire file.

<?php

    $fp = fopen('/tmp/test.txt', 'r');
    
    // Skip first 10 bytes
    fseek($fp, 10);
    
    // Move to end of file
    fseek($fp, 0, SEEK_END);
    
    // Move back 5 bytes from current position
    fseek($fp, -5, SEEK_CUR);

?>

Documentation

See Also

  • fopen
  • [ftell](https://www.php.net/manual/en/function.ftell.php; seeAlso[rewind] = https://www.php.net/manual/en/function.rewind.php)

ftell()

ftell(), or file tell, is a PHP native function that returns the current position of the file pointer for an open file stream. The position is measured in bytes from the beginning of the file.

Key characteristics:

  • Returns the current position as an integer, or false on failure
  • The file pointer position advances as data is read or written
  • Useful for tracking progress through a file or for implementing file-based protocols
  • The position can be changed with fseek() and reset with rewind()

ftell() is commonly used in combination with fseek() to implement random access file operations, and with fread() to determine how much data has been read.

<?php

    $fp = fopen('data.txt', 'r');
    if ($fp) {
        echo 'Initial position: ' . ftell($fp) . "\n"; // 0

        fread($fp, 10);
        echo 'After reading 10 bytes: ' . ftell($fp) . "\n"; // 10

        fseek($fp, 0, SEEK_END);
        echo 'File size: ' . ftell($fp) . "\n";

        fclose($fp);
    }

?>

Documentation

See Also

File Transfer Protocol (FTP)

FTP stands for File Transfer Protocol. It is a protocol to transfer files between servers.

PHP supports FTP and FTPS, through the ext/ftp extension, the ext/curl extension and the internal wrappers.

<?php
    $ftp = ftp_connect($ftpAddress); 
    
    $upload = ftp_put($ftp, $destinationPath, $sourceFile, FTP_BINARY); 
    
    if (!$upload) { 
        echo "FTP upload has failed!";
    } else {
        echo "Uploaded $source_file to $ftp_server as $destination_file";
    }
    
    ftp_close($ftp);
?>

Documentation

See Also

File Transfer Protocol Secure (FTPS)

FTPS stands for File Transfer Protocol Secure. It is a protocol to transfer files between servers, over a secure connection.

PHP supports FTP and FTPS, through the ext/ftp extension, the ext/curl extension and the internal wrappers.

<?php
    $ftp = ftp_connect($ftpAddress); 
    
    $upload = ftp_put($ftp, $destinationPath, $sourceFile, FTP_BINARY); 
    
    if (!$upload) { 
        echo "FTPS upload has failed!";
    } else {
        echo "Uploaded $source_file to $ftp_server as $destination_file";
    }
    
    ftp_close($ftp);
?>

Documentation

See Also

Fully Qualified Name

A fully qualified name, or FQN, or a fully qualified class name, FQCN, is a unique identifier for the PHP name of a constant, class, trait, interface, enum or function. A fully qualified name includes its namespace name.

PHP names may be fully qualified, unqualified or relative.

Fully qualified names are usually considered hard to read, and are shortened by using the use import keyword.

<?php

    namespace Savanna {
        const HABITAT = 1;

        function trumpet() {
            // This is a local name: the namespace Savanna is optional.
            // The fully qualified name is \Savanna\HABITAT;
            echo HABITAT;

            // This is a fully qualified name
            echo \Savanna\HABITAT;
        }
    }

?>

Documentation

See Also

func_get_args()

func_get_args() is a native function that returns an array containing the function’s argument list.

It is often used to handle a variable number of arguments in a function, especially before the introduction of the variadic operator ... in version 5.6.

There are related functions: func_get_arg(), which returns a specific argument from the list, and func_num_args(), which returns the number of arguments passed to the function.

<?php

    function trumpet() {
        $numargs = func_num_args();
        echo "Number of arguments: $numargs\n";
        if ($numargs >= 2) {
            echo "Second argument is: " . func_get_arg(1) . "\n";
        }
        $arg_list = func_get_args();
        for ($i = 0; $i < $numargs; $i++) {
            echo "Argument $i is: " . $arg_list[$i] . "\n";
        }
    }
    
    trumpet(1, 2, 3);

?>

Documentation

See Also

Function Subscripting

Function subscripting is the ability to apply operators like ->, ?-> or [<index>] directly on the results of a method call.

Using types, it is possible to ensure the previous call returns a valid array or object. When left unchecked, the subscripting leads to warnings or fatal errors.

<?php

    // displays the third element of the response of 'callMethod', on object 'getObject';
    echo getObject()->callMethod()[3];

?>

Documentation

See Also

Functions

Functions are defined with a set of parameters, a body of code for processing, and a returned value, typed or not.

Methods are defined almost the same way, except for some more options and within the context of a class.

A function is said to be anonymous when it has no name. This is the case of the closures and the arrow functions.

<?php

    function trumpet($a, $b) {
        return $a - $b;
    }

?>

Documentation

See Also

Functional Programming (FP)

Functional Programming, FP for short, is a programming paradigm where programs are built by combining pure functions, avoiding shared state, and minimizing side effects. Instead of focusing on ‘how to do things’ step by step, FP focuses on ‘what to compute’ by composing functions.

PHP supports anonymous functions, closures, iterators and higher-order functions, needed for Functional programming.

Documentation

See Also

Functional Test

Functional tests are tests that verify that a feature of the application behaves as specified, by exercising it the way a user would, through its public interface, without checking the internal implementation.

Functional tests operate at a higher level than unit tests: instead of testing a single class or function in isolation, they drive a whole feature, such as submitting a form or calling an API endpoint, and assert on its observable output. They differ from acceptance tests in that they may run at any stage of development to validate that a feature works, rather than serving as the final, business-facing sign-off before release.

Functional tests are a form of black box testing, and are commonly written against a running application, a web page, or an HTTP API, using frameworks such as Codeception, Behat, or PHPUnit’s own functional test cases in Symfony and Laravel.

Documentation

See Also

Functor

A functor is a type that can be mapped over. It must implement a function, usually called map or fmap, that applies a function to the values inside the functor, without altering the functor’s structure.

Documentation

See Also

Future

A future is a programming construct representing a value that is not yet available but will be resolved at some point. It is closely related to promises: a future is the read-only view of an asynchronous result, while a promise is the write side that resolves or rejects that future.

In languages like Java, Scala, and Dart, futures and promises are distinct objects. With languages like PHP, the distinction is often blurred, and the terms are used interchangeably within async libraries like ReactPHP or Amp.

Futures enable non-blocking code by allowing a computation to proceed without waiting for a result that is not yet ready.

Documentation

See Also

Fuzzing

Fuzzing refers to an automated software testing technique where the application is fed random, unexpected, or malformed data to discover bugs, vulnerabilities, and unexpected behaviors.

Documentation

See Also

fwrite()

fwrite() is a PHP native function that writes a string to an open file pointer. It returns the number of bytes written, or false on failure. fputs() is a plain alias of fwrite().

Key characteristics:

  • Writing may stop before the end of the string if the stream refuses more data, so the return value should be checked against strlen() of the data for reliability
  • An optional length parameter caps the number of bytes written, even if the string is longer
  • Binary-safe, and works identically on files, pipes, and sockets

fwrite() requires the file pointer to have been opened in a writable mode, such as 'w', 'a', or 'r+', with fopen(). For writing an entire string at once without manually managing a handle, file_put_contents() is more convenient.

<?php

    $fp = fopen('/tmp/test.txt', 'w');
    if ($fp) {
        fwrite($fp, 'PHP rocks!');
        fclose($fp);
    }

?>

Documentation

See Also

Generalized Algebraic Data Type (GADT)

A Generalized Algebraic Data Type, GADT, is an extension of algebraic data types in which each constructor of the type can return a different, more specific instantiation of the type. This allows the type system to track which constructor was used and to refine the available operations accordingly.

The canonical example is a typed expression tree:

data Expr a where Lit :: Int -> Expr Int IsZero :: Expr Int -> Expr Bool If :: Expr Bool -> Expr a -> Expr a -> Expr a

A Lit produces an Expr Int, while IsZero produces an Expr Bool. An eval function typed eval :: Expr a -> a can then return an Int for Lit nodes and a Bool for IsZero nodes, with the type system proving that no ill-typed expression tree can be constructed.

GADT effectively let data constructors act as proofs. They are natively supported in Haskell, OCaml, and Scala via type refinement in pattern matches.

PHP supports none of the prerequisites for GADT: it has no algebraic data types, no generics, and no exhaustive pattern matching. Class hierarchies with instanceof dispatch approximate the structural separation of cases, but without the type refinement that makes GADT powerful. The return type of a method cannot vary based on which subclass was constructed.

Documentation

See Also

Garbage Collection

Garbage collection is a PHP mechanism that checks memory and frees it when it needs to store new values.

PHP allocates memory as it needs, when variables and objects are created in the code. Sometimes, those variables are destroyed, using explicit unset() calls, or implicitly, when leaving a method or destroying an object.

To speed up the process, PHP postpones memory cleaning until the end of the application, or when it reaches some internal threshold. Then, it reviews all the currently allocated variables, and when they are not used anymore, that is when the reference counter is down to 0, it removes them.

As garbage collection requires pausing the execution, PHP only runs it on-demand, via gc_collect_cycles() calls, or once every ten thousand objects to clear.

Garbage collection is needed to handle circular reference: objects that mutually reference each other, and which requires some processing to identify as dead data.

<?php

    // Explicit Garbage Collection 
    gc_collect_cycles();

    // implicit garbage collection
    // well,... difficult to illustrate, right?

?>

Documentation

See Also

Graphic Draw (GD)

GD is the name of a PHP extension that can manipulate several image formats, such as GIF, PNG, JPEG, WBMP, and XPM, and draw graphics.

The GD extension is a binding to the libgd graphics library. It provides functions to create images from scratch, or to load them from an existing file or a binary string, then draw shapes, lines, text, and apply filters, before outputting the result directly to the browser or saving it to disk. Typical uses include generating thumbnails, watermarking uploaded pictures, building CAPTCHAs, drawing charts, or producing dynamically generated images such as Open Graph previews.

GD ships as a bundled extension with PHP, but it must still be enabled, either at compile time with --with-gd, or by loading the gd.so / php_gd.dll shared extension in php.ini. Depending on how the underlying libgd was built, support for specific formats such as JPEG, WebP, or FreeType-based text rendering may or may not be available, which can be checked with gd_info().

GD is not the only image library available for PHP: the Imagick extension, a binding to ImageMagick, offers a richer feature set and support for more formats, at the cost of a heavier dependency. Because GD functions accept resource-like GdImage objects and can decode attacker-supplied files, careless use, for instance passing unchecked, remotely-provided data to imagecreatefromstring(), has historically been a source of security vulnerabilities.

<?php

    // Creating a PNG image with PHP 
    // Extract from the PHP documentation
    header("Content-type: image/png");
    $string = $_GET['text'];
    $im     = imagecreatefrompng(images/button1.png);
    $orange = imagecolorallocate($im, 220, 210, 60);
    $px     = (imagesx($im) - 7.5 * strlen($string)) / 2;
    imagestring($im, 3, $px, 9, $string, $orange);
    imagepng($im);

?>

Documentation

See Also

Gearman

Gearman is a PECL extension that provides a client for the Gearman job server, a system for distributing work across machines or processes. A client submits a job to the Gearman server, one or more workers register to handle jobs of that name, and the server dispatches each job to an available worker.

Jobs can be submitted synchronously, where the client blocks until a result comes back, or asynchronously, in the background, where the client fires the job and moves on. Gearman also supports splitting a large task into pieces that are farmed out to multiple workers and their results merged, and it can report progress back to the client for long-running jobs.

Gearman is commonly used to offload slow operations, such as image processing, sending email, or generating reports, out of the request/response cycle and onto a pool of background workers, which can be scaled independently of the web tier.

<?php

    // Worker process: registers a function and waits for jobs.
    $worker = new GearmanWorker();
    $worker->addServer();
    $worker->addFunction('resize_image', function (GearmanJob $job) {
        $path = $job->workload();
        // ... resize $path ...
        return 'done';
    });
    while ($worker->work()) {
    }

    // Client process: submits a job and waits for the result.
    $client = new GearmanClient();
    $client->addServer();
    $result = $client->doNormal('resize_image', '/uploads/photo.jpg');

?>

Documentation

See Also

Generative Engine Optimization (GEO)

Generative Engine Optimization, or GEO, is the practice of shaping content so that it is more likely to be retrieved, cited, and favorably summarized by generative AI systems, such as ChatGPT, Perplexity, Google Gemini, Claude, Copilot, etc, when they answer a user’s question. The term was formally introduced in a 2023 research paper by authors from Princeton, Georgia Tech, the Allen Institute for AI, and IIT Delhi, which proposed a benchmark and measured that tactics such as adding statistics, direct quotations, and citations to a source could increase its visibility inside generative answers by a large margin. GEO differs from traditional search engine optimization in its target and its metric: instead of optimizing for a ranking position in a list of blue links that a human will scan, GEO optimizes for being selected, quoted, or paraphrased as evidence inside a synthesized answer that the human may never click through from. Practical techniques include writing clear, self-contained passages that answer a specific question, structuring content with explicit facts and sources, maintaining crawlable and machine-readable pages, and publishing an llms.txt file to guide AI crawlers, much as robots.txt and sitemaps guide traditional search engines.

Documentation

See Also

Generator

generator has several distinct usages:

  • Yield generator: a function or method that uses yield, implicitly returning an instance of \Generator and implementing the Iterator interface without the boilerplate of writing one
  • Random number generator: an algorithm or function, such as rand(), mt_rand(), or the Random\Engine classes, that produces a sequence of numbers that appears random
  • Code generator: a tool or library that automates the creation of boilerplate PHP code from templates, configuration, or a schema

Absent further context, generator most often refers to the yield generator.

Documentation

Generics

Generics, sometimes called parametered polymorphism, or more precisely parametric polymorphism, are a style of types, where the type of a property, parameter or return is specified at the declaration level.

The generics syntax looks like: $users = new List<User>(); where List is a class that holds a list of items, and those items are of the type between brackets. Here, it is User.

Generics allows the creation of general classes, that can process several types of data. The actual application’s type is declared in the type itself. This is similar to configure an array to only handle one type of elements.

Generics have been submitted as RFC since 2016, and are currently not implemented, in the foreseeable future.

One implementation of generics is available, with transpiling: see mrsuh/php-generics.

Generics are generally considered to be not supported, although external tools provide this feature, such as static analysis. Generics are not supported at the engine level.

Documentation

See Also

GeoIP

GeoIP is the technique of resolving an IP address to an approximate geographic location, typically a country, region, or city, by looking it up in a database that maps IP address ranges to places, such as MaxMind’s GeoLite2 and GeoIP2 databases. PHP historically offered a dedicated geoip PECL extension for querying these lookups natively, but it has since been unbundled and is largely obsolete; modern PHP code instead uses a library such as geoip2/geoip2, which reads a local .mmdb database file, or calls a third-party HTTP API. Because the mapping is based on network allocation records rather than the device itself, GeoIP results are only approximate, accurate at the country level most of the time but often unreliable at the city level, and can be thrown off entirely by VPNs, proxies, or mobile carrier NAT. It is commonly used for content localization, geo-blocking, fraud scoring, and rough analytics, but should not be relied on where precise location is required.

<?php

    use GeoIp2\Database\Reader;
    
    $reader = new Reader('/path/to/GeoLite2-City.mmdb');
    $record = $reader->city('128.101.101.101');
    
    echo $record->country->isoCode;   // 'US'
    echo $record->city->name;         // 'Minneapolis'

?>

Documentation

See Also

Geolocation

Geolocation is the process of determining the real-world physical location of a device, a user, or a piece of content. On the web, a browser can report a device’s coordinates directly through the HTML5 Geolocation API, using GPS, Wi-Fi positioning, or cell-tower triangulation, and a PHP backend then simply receives and stores the latitude and longitude sent by client-side JavaScript. When no device-reported coordinates are available, an approximate location can instead be inferred server-side from the visitor’s IP address, a technique known as GeoIP. Typical uses in applications include localizing content and currency, restricting or redirecting access by country, pre-filling shipping addresses, powering store-locator features, and enriching analytics or fraud-detection signals with a rough location.

<?php

    // Coordinates sent by the browser's navigator.geolocation API as POST fields
    $latitude  = (float) ($_POST['latitude']  ?? 0);
    $longitude = (float) ($_POST['longitude'] ?? 0);
    
    if ($latitude !== 0.0 && $longitude !== 0.0) {
        echo "User is near {$latitude}, {$longitude}";
    }

?>

Documentation

See Also

get_browser()

get_browser() is a PHP native function that looks up the capabilities of a browser, based on its user agent string, and returns them as an object or an array.

get_browser() relies on the browscap directive in php.ini, which must point to a local copy of the browscap.ini database, an external file mapping user agent signatures to browser names, versions, and capabilities such as support for frames, cookies, or JavaScript. Without a configured browscap file, get_browser() emits a warning and returns false.

If the optional user_agent argument is omitted, PHP uses the value of $_SERVER['HTTP_USER_AGENT'] for the current request.

The browscap.ini approach is considered obsolete for new projects: it is difficult to keep up to date, degrades performance when the file is large, and has been superseded by client-side feature detection or the User-Agent Client Hints proposal.

<?php

    // Requires browscap = /path/to/browscap.ini in php.ini
    $browser = get_browser(null, true);

    echo $browser['browser'];        // e.g. 'Chrome'
    echo $browser['platform'];       // e.g. 'Linux'
    var_dump($browser['javascript']); // true

?>

Documentation

See Also

get_class()

get_class() is a PHP native function, that returns the name of the class of an object.

get_class() returns the full name of the class, including its namespace and original letter cases.

get_class() may be replaced by the magic method __CLASS__ when operating on $this. It may also be replaced with an object in other situation, such as fetching a static constant, or instantiating a new object.

<?php

namespace Zoo\Savanna;

class Elephpant {}

$trunk = new Elephpant;
print get_class(); //Zoo\Savanna\Elephpant

$herd = new $trunk;
print get_class(); //Zoo\Savanna\Elephpant

?>

Documentation

See Also

get_class_vars()

get_class_vars() is a PHP native function that returns the default properties of a class as an associative array.

Unlike get_object_vars(), which operates on an object instance, get_class_vars() takes a class name as a string and returns the default values of the class’s declared properties, including inherited ones.

Only properties accessible from the current scope are returned.

<?php

class Elephpant {
    public string $name = 'default';
    protected int $count = 0;
    private bool $active = true;
}

$vars = get_class_vars(Elephpant::class);
print_r($vars);
// Array ( [name] => default )  // only public properties visible in this scope

?>

Documentation

See Also

get_object_vars()

get_object_vars() is a PHP native function, which returns an array with the object properties as index, and their related respective values.

get_object_vars() does not return static properties, which are class level, and not object level.

get_object_vars() does not return uninitialized properties. It returns all existing properties, may they be specified in the class definition, or not. It returns the trait and the parent properties.

get_object_vars() respect visibility, so its result may differ depending on its calling location: private properties are only visible when get_object_vars() is called from within the class itself; protected may be visible when called from a child; otherwise, only public properties are returned.

Constants are not returned by that function.

get_object_vars() is very similar to the (array) cast operator. It is very different from the get_class_vars() method, which returns the properties as defined in the class, and including the static properties. It is also possible to use json_encode() followed by json_decode(), though some data might get lost in the translation process.

<?php

trait HasTusks {
    public $tuskLength = '3';
}

class Elephpant {
    use HasTusks;

    private int $age = 1;
    private int $weight = 2;
    public int $trunkLength = 3;
    public int $earSize = 4;
    public int $herdSize;

    static string $species = 'abc';

    function __construct() {
        unset($this->earSize);

        $this->waterIntake = 6;
    }
}

print_r(get_object_vars(new elephpant));

/**
Array
(
    [trunkLength] => 3
    [tuskLength] => 3
    [waterIntake] => 6
)
*/
?>

Documentation

See Also

getenv()

getenv() is a PHP native function that reads the value of an environment variable. Called with a name, it returns that variable’s value, or false if it is not set. Called with no argument, it returns an associative array of every currently available environment variable.

Unlike the $_ENV superglobal, whose content is collected once at the start of the script and depends on the variables_order directive, getenv() always queries the environment directly, so it reflects changes made during execution, for example with putenv().

When PHP runs under a SAPI such as FPM or FastCGI, getenv() returns the value set by the SAPI itself, even if putenv() was used to override it locally; passing true as the second, local_only, argument restricts the lookup to locally-set values.

<?php

    // read a single environment variable
    $home = getenv('HOME');

    // read every environment variable
    $env = getenv();

    putenv('MY_VARIABLE=42');
    echo getenv('MY_VARIABLE'); // 42

?>

Documentation

See Also

Class Getter Method

Getters are methods used to access the values of a property. Getters may include formatting, or not.

Getters are usually created with a setter method.

Getters are built on top of private properties: that way, the getter is the main way to reach the data.

Getters may be replaced by a property hook.

Getters generate a lot of boilerplate code, as they must be created for each property, and are often reduced to returning the property itself. This does not help performance either, as a call to a property is now replaced by a method call.

<?php

    class Elephpant {
        private $property;
        
        public function getProperty() {
            return $this->property;
        }
    }

?>

Documentation

See Also

gettext Extension

gettext is a library that provides features to translate messages for the users. It includes the famous gettext() function, and its alias _(), the underscore.

It is based on the locale system, and the .mo files.

<?php

    // example from the PHP manual: https://www.php.net/manual/en/function.gettext.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)";

?>

Documentation

See Also

gettype()

gettype() is a PHP native function that returns the type of a variable as a string. Possible return values are "boolean", "integer", "double", "string", "array", "object", "resource", "resource (closed)", "NULL", and "unknown type".

These return values are historical and do not match the type names used in type declarations, such as int, float, or bool: for that purpose, get_debug_type(), available since PHP 8.0, is recommended, as it returns the actual type name, including the class name for objects.

gettype() is mostly used for debugging or logging, rather than for type checking in conditional logic: dedicated functions like is_array(), is_string(), is_int(), is_bool() are faster and clearer for that purpose. Changing a variable’s type is done with settype(), the counterpart of gettype().

<?php

    echo gettype(42);        // integer
    echo gettype(3.14);      // double
    echo gettype('hello');   // string
    echo gettype([1, 2]);    // array
    echo gettype(null);      // NULL
    echo gettype(new stdClass()); // object

?>

Documentation

See Also

Ghost Object

A ghost object is a design pattern, catalogued by Martin Fowler as one of the four varieties of Lazy Load, where an object is created empty, without any of its real data, and silently loads its full state the first time one of its properties or methods is actually accessed.

Unlike a plain proxy, which typically wraps a separate real object behind a shared interface, a ghost object is an instance of the real class itself: it has the right type, passes instanceof checks, and can be passed around freely, but starts out hollow. Only when it is actually touched does it trigger the expensive work, a database query, a remote call, a heavy computation, to fill itself in.

Doctrine ORM has long generated ghost-like proxy classes for its entities to defer loading related objects until they are accessed. PHP 8.4 brought this pattern into the engine itself with native lazy-objects: ReflectionClass::newLazyGhost() creates a genuine instance of a class that stays uninitialized until first accessed, without any code generation or subclassing, making the ghost object pattern a language feature rather than a library trick.

<?php

    class Invoice
    {
        public function __construct(
            private int $id,
            private array $lines = [],
            private float $total = 0.0,
        ) {
            // Imagine this constructor also runs a heavy computation
            // or a database query to compute $lines and $total.
        }
    
        public function getTotal(): float
        {
            return $this->total;
        }
    }
    
    // Build a ghost: an Invoice instance that looks real, but has no data yet
    $initializer = static function (Invoice $ghost): void {
        // Runs only once, the first time the ghost is actually touched
        [$lines, $total] = loadInvoiceFromDatabase(42);
        $ghost->__construct(42, $lines, $total);
    };
    
    $reflector = new ReflectionClass(Invoice::class);
    $invoice = $reflector->newLazyGhost($initializer);
    
    // Nothing has been loaded yet: $invoice is still a hollow ghost
    echo $invoice->getTotal(); // first access: the initializer fires, filling in the real data

?>

Documentation

See Also

Graphics Interchange Format (GIF)

GIF, for Graphics Interchange Format, is a bitmap image format developed by CompuServe in 1987. It supports up to 256 colors per frame and uses lossless compression based on the LZW algorithm.

GIF is widely known for supporting animation through multiple frames stored in a single file.

The GD extension can create and manipulate GIF images using functions such as imagecreatefromgif(), imagegif(), and imagecreatetruecolor().

As with the rest of internet, nobody in the community has sorted out the pronunciation of this: it may be GIF or GIF.

<?php

    $image = imagecreatefromgif('input.gif');
    
    // Manipulate...
    
    imagegif($image, 'output.gif');
    imagedestroy($image);

?>

Documentation

See Also

Git Hook

Git hooks are scripts that Git executes automatically at specific points in the version-control workflow. They live in the .git/hooks/ directory of a repository and are triggered by operations such as committing, merging, pushing, or checking out.

Common hooks used in projects:

  • pre-commit runs before a commit is recorded. It is the standard place to invoke code-quality tools: static analysis or unit test suites to block commits that would introduce errors or style violations
  • commit-msg validates the commit message format, for example enforcing a conventional-commits pattern
  • pre-push runs before git push sends data to a remote. It is a last line of defence for running the full test suite
  • post-checkout and post-merge can automate composer install after switching branches or pulling changes

Because .git/hooks/ is not tracked by version control, teams share hook scripts through tools such as captainhook/captainhook, brainmaestro/composer-git-hooks, or husky, for JavaScript-adjacent stacks. These tools install hooks from a committed configuration file, ensuring every contributor runs the same checks.

#!/bin/sh
# .git/hooks/pre-commit
# Block commit if PHP syntax errors are found
git diff --cached --name-only --diff-filter=ACM | grep '\.php$' | while read file; do
    php -l "$file" || exit 1
done

Documentation

git

Git is a distributed version control system that is widely used for tracking changes in source code during software development. It was created by Linus Torvalds in 2005 and has since become one of the most popular and essential tools in the software development industry. Git allows multiple developers to collaborate on a project, manage different versions of code, and track changes over time.

Documentation

See Also

glob()

glob() is a function that finds pathnames matching a pattern.

The glob() function is not related to the global keyword.

The pattern syntax follows the rules used by the shell, not regular expressions: * matches any number of characters, ? matches a single character, and bracket expressions such as [a-z] match a range or set of characters. Optional flags let the caller include hidden files, sort results, or return only directories.

Because glob() reads the filesystem directly, its result depends on what is actually present on disk at the moment it is called, and it can be comparatively slow on directories with a very large number of entries. It also returns false on failure rather than throwing an exception, so callers should check the return value before iterating over it.

<?php

    foreach (glob("*.txt") as $filename) {
        echo "$filename size " . filesize($filename) . "\n";
    }   

?>

Documentation

See Also

Global Code

The global code is the code that doesn’t belong to any method or function. Since PHP has no main() method that is called upon execution, the global code in the first file called is used. It is responsible to make the first calls to objects and functions.

Global code is usually organised in a sequential manner. Once the bootstrapping, which create the first objects, install autoload, detect environment, is done, the global code calls one object and let it handle the request.

<?php

// This is the global code
trumpet();

function trumpet() {}

?>

Documentation

See Also

Global Space

The term global space refers to the global namespace \\\\ or the top-level scope in the PHP language. The global space is where global variables, functions, and global constants reside. When a variable, function, or constant is defined without specifying a namespace, it is stored in the global space.

It is recommended to avoid using the global space for any definition: they should be stored in a custom namespace. Then, they may be imported in other namespaces, with the use expression.

<?php

// This is the global space
namespace {
    // this function is defined in the global space
    function trumpet() {}
} 

?>

Documentation

See Also

Global State

Global state refers to data that is accessible from anywhere in the application, typically stored in global variables, superglobals, or static class properties.

Global state is often considered an anti-pattern because it makes code harder to test, debug, and reason about. It creates hidden dependencies between components.

Common sources of global state include:

  • $GLOBALS superglobal
  • Static class properties
  • Constants defined with define()
  • Files included with require/include
  • Environment variables.
<?php

    // Global state via static property
    class Config {
        public static array $settings = [];
    }
    
    // Global state via $GLOBALS
    $GLOBALS['db_host'] = 'localhost';

?>

Documentation

See Also

Global Variables

Global variables reside in the global scope, and may be imported in a local scope with the global keyword.

To become a global variable, a variable may use one of the following ways:

  • Be declared as such with the global keyword
  • Be created in the $GLOBALS variable, which is a global variable itself
  • Be created outside any function, method, closure
  • Be a super-global

Global variables provide a way to share data in different and remote scopes. They also provide a way for data to be modified by another part of the code, without warning.

<?php

    global $count;
    $count = 0;
    
    function counter() {
        global $count;
        
        // no return here
        ++$count;
    }
    
    counter(); 
    echo $count; // print 1
    counter(); 
    echo $count; // print 2

?>

Documentation

See Also

global Scope

The global scope is the top level scope. It is the scope when no function, or method scope is active. It is also the first scope when starting execution.

Variables from the global scope are accessible in other scopes by using the global keyword, or the $GLOBALS variable. Variables in the global scope are automatically added to the $GLOBALS variable; in local scopes, the global keyword has that effect too.

Some special variables are called superglobal: they are available in every scope.

The opposite of the global scope is the local scope.

<?php

    $trunk = 'A';

    function counter() {
        echo $GLOBALS['A'];

        global $trunk;

        echo $trunk;
    }
    
    counter();

?>

Documentation

See Also

Glue

Glue represents the piece of string that is used as separator between elements in a join() operation. Glue is also called a separator.

glue is the historical name of the first parameter of PHP’s implode() function, which is an alias for join(). It is the string inserted between every pair of consecutive elements of the array being turned into a single string. An empty glue, '', concatenates the elements without anything between them, while a glue such as ', ' produces a comma-separated list.

Before PHP 8.0, implode() also accepted its arguments in the reverse order, implode($array, $glue), for backward compatibility with very old PHP code; this reversed form was deprecated and later removed, so the glue must now always be passed first, or as the named argument separator in the array signature, implode(array $array, string $separator = ""). As of PHP 8.0, the parameter itself was actually renamed from glue to separator in the official documentation and function signature, even though the older name is still commonly used in tutorials and community discussions.

The reverse operation, splitting a string back into an array using a delimiter, is performed by explode(), which uses a parameter historically called separator as well, playing a symmetrical role to glue.

<?php

    print join(glue, [1, 2, 3]);

?>

Documentation

See Also

GNU Multiple Precision (GMP)

gmp is a PHP extension that stands for “GNU Multiple Precision”. It provides functionality to process mathematically arbitrary-length integers .

The gmp extension allows the basic calculations, like addition, multiplication,… some advanced math functions such as square roots, prime test, legendre symbol, GCD, etc.

<?php

    echo 'TRANSLIT : ', iconv("UTF-8", "ISO-8859-1//TRANSLIT", $text), PHP_EOL;
    // TRANSLIT : This is the Euro symbol 'EUR'.

?>

Documentation

See Also

God Object

A god object, or god class, is a term used in software development to describe a class or module that knows too much or does too much within a system. It typically refers to an object that has an excessive amount of responsibilities, making it overly complex and difficult to maintain. In other words, a god object violates the principles of encapsulation and high cohesion.

Documentation

See Also

Golf

Code golf is about creating the shortest code, in bytes, to solve a given problem, in a specific language or free of choice. Solutions are scored purely on character count; readability, style, and maintainability are deliberately ignored.

PHP golfers exploit language-specific shortcuts to shave bytes: the short echo tag <?=, omitting the closing ?> tag, the null coalescing and null coalescing assignment operators, ?? and ??=, instead of isset() checks, the ternary shorthand ?:, list()/[] destructuring instead of separate assignments, loose == comparisons, and string-to-number juggling such as writing "1e9" instead of 1000000000.

Community sites such as Code Golf Stack Exchange and Anarchy Golf host PHP-specific challenges, and submissions are usually scored with strlen() run on the minified source.

<?php

    // All spaces are removed to make the code compact
    $billionPlusOne=1+1e9; 

    // 1e9 is cast automatically to 1000000000 or 1_000_000_000, but takes less space to write

?>

Documentation

See Also

Goto

The goto operator is a language construct that allows to perform an unconditional jump in the flow of your code to a specified label.

goto one of the very controversial PHP features and has been the subject of much debate due to its potential to create spaghetti code and make code difficult to read and maintain.

Some legit uses of goto include breaking out of nested loops, implementing state machines, or in some cases for error handling. However, they are rare, and should only considered in last resort.

The target label must be within the same file and context, meaning that it is not possible to jump out of a function or method, nor to jump into one.

goto is case insensitive.

<?php
  
    goto stampede;
    echo 'Forage';

    stampede:
    echo 'Trumpet';

?>

Documentation

See Also

Gradual Type Checking

Gradual type checking is the progressive introduction of types in a code base. When a code base is not fully typed, it is in a state of gradual typing. Types are introduced, which leads to various levels of validation and verifications, and a better stability.

Gradual Type Checking ends when the code is all typed: arguments, return types, properties, constants. There might be some ambiguous situations, such as with variables, yields and use.

<?php

    // partially typed function
    function trumpet(int $i, $b) {
        // some code
    }

?>

Documentation

See Also

Gradual Typing

Gradual typing, or a gradual type system, is a type system that lets typed and untyped, or loosely typed, code coexist and interoperate, with the amount of checking growing incrementally rather than being all-or-nothing. A value can flow between a strictly typed region and a dynamically typed one, with the boundary checked at the point where the two meet.

PHP’s type system has grown this way release by release rather than arriving as a single design: class types in version 5.0, scalar types in version 7.0, union types, nullsafe operators, and DNF types since. Each addition is checked at runtime, so the language never had to make a single, all-at-once jump to a fully static system, and existing code keeps working as new, more precise, typed constructs become available around it. mixed, and the absence of a declared type, are what let a codebase stay only partially typed at any point along that path.

Proposals to add generics follow the same philosophy: rather than erased, compile-time-only type parameters, the direction under discussion starts with invariant type parameters that are actually checked at runtime on a narrow surface, such as interfaces, and can grow from there, keeping every new construct held to the same rule the rest of the type system already follows.

<?php

    function total(array $orders): mixed // mixed marks the boundary: untyped by choice
    {
        // ...
    }

    function totalTyped(array $orders): Money // strictly typed, checked at runtime
    {
        // ...
    }

?>

Documentation

See Also

Grammar

The grammar of a language is the formal set of rules that describes which sequences of tokens form valid statements and expressions. PHP’s grammar is defined in a Yacc/Bison file, in Zend/zend_language_parser.y of the engine source code, that is compiled into the parser used by the Zend Engine.

The grammar operates on tokens produced by the lexer/tokenizer, and is distinct from semantics: a piece of code may be grammatically valid, yet still fail at compile-time or run-time. For example, calling an undefined function.

Ambiguities or changes in the grammar are a common source of backward-incompatible changes between PHP versions, such as the reinterpretation of nested ternary operators or the introduction of new reserved keywords.

<?php

    // Grammatically valid, but each statement fails differently
    $a = ; // parse error: grammar violation, no expression after '='
    
    foo(); // grammar is fine, but 'foo' is undefined: a runtime error, not a grammar one

?>

Documentation

See Also

Graph Database

A graph database is a database server that organize data in a network, rather than as tables.

PHP is able to connect to many graph databases, including Neo4j, Gremlin servers, etc.

Graph databases are close to RDF triple stores, which store data as a triplet: origin, destination and link type.

Documentation

See Also

Graph

A graph is a data structure consisting of a set of nodes, also called vertices, and edges that connect pairs of nodes. Graphs can be directed or undirected, weighted or unweighted.

Graphs are used to model many real-world problems: social networks, dependency trees, network topology, and code analysis tools such as call graphs and control flow graphs.

PHP has no built-in graph data structure, but several libraries provide graph implementations and algorithms.

<?php

// Simple adjacency list representation
$graph = [
    'A' => ['B', 'C'],
    'B' => ['A', 'D'],
    'C' => ['A'],
    'D' => ['B'],
];

// Traverse neighbors of A
foreach ($graph['A'] as $neighbor) {
    echo $neighbor, PHP_EOL; // B, C
}

?>

Documentation

See Also

GraphQL

GraphQL, or the GraphQL API style, is a query language for APIs. It provides a way to describe data and operations, so that clients can freely build queries.

PHP has several packages to implement both the client and the server side of GraphQL.

Documentation

See Also

Greenfield

A greenfield project is a software development effort that starts from scratch, with no existing codebase, legacy constraints, or inherited technical debt. The term comes from civil engineering, where building on undeveloped land, aka a green field, imposes no constraints from prior construction.

Greenfield development offers maximum design freedom: the team chooses the architecture, language runtime, framework, data model, and tooling without having to preserve backward compatibility or work around previous decisions. This freedom also means that all foundational choices, such as dependency injection strategy, persistence layer, authentication model, error handling conventions, must be made explicitly and early.

Characteristics of greenfield PHP projects:

  • No legacy code to maintain: the team can adopt modern PHP features such as named arguments, fibers, readonly properties, union types, and current best practices from day one.
  • Framework choice is open: a framework, such as Laravel, Symfony, Slim, or a custom stack can be selected on merit rather than migration cost.
  • No migration risk: the database schema, API contracts, and deployment pipeline are defined for the target state, not constrained by an existing one.
  • Higher up-front design cost: decisions that a brownfield project has already made, even poorly, must be made here deliberately.

The opposite of greenfield is brownfield development: working inside or alongside an existing system, where the constraints of prior decisions shape every new choice.

Greenfield projects benefit from:

  • Composer and Packagist for dependency management from the start.
  • Strict type declarations declare(strict_types=1) enforced project-wide from the first file.
  • Modern tooling: static analysis, automated refactoring, testing, all configured before the first feature is written.
<?php

   // Greenfield entry point: strict types and modern conventions from file one.
   declare(strict_types=1);

   // Dependency injection container wired at bootstrap, no global state.
   $container = new \DI\Container();

   $app = $container->get(App::class);
   $app->run();

?>

Documentation

See Also

Green Thread

Green threads, also called goroutines in Go, virtual threads in Java 21+, or lightweight threads in Erlang/Haskell, are user-space threads managed entirely by the language runtime rather than the operating system kernel. The runtime multiplexes thousands or millions of them onto a small pool of OS threads, handles scheduling, stack growth, and context switching transparently, and makes blocking calls non-blocking without programmer intervention.

Key properties of native green threads:

  • Created with negligible overhead: a few kilobytes of stack, no syscall
  • Scheduled by the runtime, not the OS; the programmer spawns them freely without thinking about thread-pool sizing.
  • Blocking I/O is intercepted by the runtime and turned into a yield; other green threads run in the meantime.
  • No explicit await or suspend call is required at the call site: existing blocking code simply works.

Go goroutines are the canonical example: go fn() spawns a goroutine and returns immediately. The Go scheduler parks it when it blocks on I/O and resumes it when the I/O completes, across a fixed number of OS threads GOMAXPROCS.

PHP does not have native green threads. PHP’s default execution model is shared-nothing: each request runs in its own process or OS thread, managed by PHP-FPM or the web server, with no in-process concurrency between requests.

Available approximations, each with trade-offs:

  • Fibers, PHP 8.1: cooperative micro-threads within a single OS thread. Require explicit Fiber::suspend() / resume() call sites; the programmer must opt in at every yield point. Fibers do not run in parallel and do not intercept blocking I/O automatically.
  • Swoole / OpenSwoole / Swow: C extensions that replace PHP’s I/O layer and provide a coroutine scheduler. Within a Swoole coroutine server, blocking calls are transparently converted to non-blocking ones, closely approximating green-thread behaviour. However, this requires a persistent-process server model and is not part of the PHP standard distribution.
  • ReactPHP / AMPHP: pure-PHP event loops built on stream_select or libuv. They require explicit async/await, yield or async/await via Fibers, at every I/O boundary; there is no transparent interception.
  • parallel extension: true OS threads for CPU-bound work, with strict shared-state constraints: no shared objects.

None of these match the ergonomics of goroutines, where spawning a concurrent task is a single keyword and all existing synchronous I/O code continues to work unchanged.

<?php

    // PHP 8.1 Fibers: closest native approximation.
    // Unlike goroutines, suspension must be explicit and there is no parallelism.
    
    $fiber = new Fiber(function (): void {
        echo "Fiber started\n";
        $received = Fiber::suspend('first yield');  // explicit yield point required
        echo "Fiber resumed with: $received\n";
    });
    
    $yielded = $fiber->start();           // run until first suspend()
    echo "Main got: $yielded\n";         // 'first yield'
    $fiber->resume('hello');              // hand control back
    
    // Swoole coroutines (extension, not standard PHP) come closer
    // to transparent green threads:
    //
    // Co\run(function () {
    //     go(function () {
    //         // Co::sleep() suspends this coroutine transparently;
    //         // other coroutines run during the wait.
    //         Co::sleep(1);
    //         echo "task A done\n";
    //     });
    //     go(function () {
    //         Co::sleep(1);
    //         echo "task B done\n";
    //     });
    // });

?>

Documentation

See Also

Green

Green describes a build, a test run, or a pipeline stage that has passed: every assertion succeeded, nothing failed, nothing errored. The term comes from the traffic-light convention used by CI dashboards and test runners, where green means go and red means stop.

Green is best known from the red, green, refactor cycle of test-driven development: write a failing test in red, write the minimum code to make it pass to green, then improve the code without changing its behaviour, with refactor. A codebase is only safe to refactor once it is green, since the tests are what confirm that behaviour was preserved.

At the pipeline level, a green build means every stage, tests, static analysis, linting, deployment checks, succeeded, so the commit is considered safe to merge or deploy. A red build blocks merges in most CI setups until it turns green again. Keeping the main branch green is a common team discipline: nobody should merge on top of a known-broken build, since that hides new failures behind an old one.

Green is distinct from greenfield, a fresh project with no legacy constraints, and from a green thread, a lightweight, runtime-scheduled thread. All three share the same word but describe unrelated concepts.

<?php

    // PHPUnit: red before green
    final class CartTest extends \PHPUnit\Framework\TestCase
    {
        public function testEmptyCartTotalIsZero(): void
        {
            $cart = new Cart();
    
            // Red: Cart::total() does not exist yet.
            // Green: implement Cart::total() to return 0 for an empty cart.
            $this->assertSame(0, $cart->total());
        }
    }
    
    // Running the suite: exit code 0 means green.
    // vendor/bin/phpunit --colors=always
    // $ echo $?
    // 0

?>

Documentation

See Also

gRPC (Google Remote Procedure Call)

gRPC, short for Google Remote Procedure Call, is a high-performance framework for building APIs and connecting services: especially in microservices architectures.

It was originally developed by Google and is now an open-source project under the Cloud Native Computing Foundation.

Documentation

See Also

Habit

A habit, in the context of software development, is a coding practice that a developer applies automatically and repeatedly, without necessarily making a deliberate decision each time.

Habits can be beneficial: such as always validating input, writing tests first, or naming variables clearly; they may be harmful, such as suppressing errors with @, using magic numbers, or leaving dead code in place.

Good habits are the foundation of consistent code quality. They turn best practices into second nature. Bad habits are often the source of recurring issues in a codebase, since they are applied without reflection.

Static analysis tools are particularly effective at reporting bad habits: patterns that appear many times across a codebase, reflecting a systematic behaviour rather than a one-off mistake.

<?php

    // A bad habit: silencing errors instead of handling them
    $result = @file_get_contents('data.json');

    // A good habit: checking return values explicitly
    $result = file_get_contents('data.json');
    if ($result === false) {
        throw new RuntimeException('Could not read data.json');
    }

?>

Documentation

See Also

Handle

A handle represents a datastructure that has established a link with an independent resource. There are handles for files, for database connection, for http connections, etc.

The content of the handle is usually opaque: there is no need to know what is inside, except that this handle must be provided to every function call.

Handles are often build with the type resource, and they are evolving toward objects. The content is still opaque, but the objects carry the dataset between method calls.

<?php

    $handle = fopen("c:\folder\resource.txt", r);
    $string = fread($handle);
    fclose($handle);

?>

Documentation

See Also

PHP Handlers

PHP handlers are methods which are called to customize the processing of specific events. All those handlers have a default handler, which is used until a new one is configured.

Handlers are usually named by their setting function:

  • Errors
    • set_error_handler()
    • set_exception_handler()
  • Sessions
    • session_set_save_handler()
    • session_register_shutdown()
  • Execution
    • register_shutdown_function()
  • Ticks
    • register_tick_function()
  • Headers
    • header_register_callback()
  • Streams
    • stream_register_wrapper()
    • stream_wrapper_register()
    • stream_filter_register()
  • Autoload
    • spl_autoload_register()

PHP handlers may be functions, closures and arrow functions.

Registering a handler replaces the engine’s built-in behavior for that event with user-defined code, until the script ends or the handler is explicitly restored, for example with restore_error_handler(). This makes handlers a powerful hook for cross-cutting concerns such as centralized logging, custom error reporting, graceful cleanup on shutdown, or lazy class loading via spl_autoload_register().

Because a handler runs in place of PHP’s default behavior, a poorly written one can mask real problems: an error handler that swallows all errors without logging them, for instance, makes debugging much harder. Most handler-registering functions also accept an array to allow multiple handlers to be chained, or return the previously registered handler so it can be restored later.

Documentation

See Also

Hard Coded

Hard coded data in code happens when a value is set as a literal in the code, and can’t be changed through any directives or parameters.

Hard-code becomes a security problem, when the hard-coded value is a password or a hash of it. This secret is now readable in the code.

<?php 

// This is hard-coded
$age = 1;

// $weight has a default value, but may also be changed at execution time
function trumpet($weight = 2) {
    echo $weight;
}

 ?>

Documentation

See Also

Hardening

Hardening refers to raising the security level in the installation of PHP, and other related technologies. It means reviewing the default or installed configurations and set ups, to make them safer.

For example, by default, PHP displays its version number in the HTTP headers, with X-Powered-By. This may be hidden, so as not to disclose any information, by setting expose_php directive to off, or 0 in the php.ini file.

Documentation

See Also

Hash

# is character, used in various situations:

  • One line comment: # comments after the character
  • Separator in a URL, for the anchor: https://www.php.net/ChangeLog-8.php#8.5.3

A hash may also be a type of arrays.

<?php

    file_get_contents('https://www.php.net/ChangeLog-8.php#8.5.3');

    echo 1; # A single line comment

?>

Documentation

See Also

Hash Comparisons

Cryptographic hashes are usually represented by strings. As such, they are subjects to type juggling, and they should be compared with the identity operator, or a dedicated function.

<?php

$expected  = crypt('12345', '$2a$07$usesomesillystringforsalt$');
$correct   = crypt('12345', '$2a$07$usesomesillystringforsalt$');
$incorrect = crypt('apple', '$2a$07$usesomesillystringforsalt$');

var_dump(hash_equals($expected, $correct));
var_dump(hash_equals($expected, $incorrect));

var_dump($expected == $correct);
var_dump($expected == $incorrect);

var_dump($expected === $correct);
var_dump($expected === $incorrect);

?>

Documentation

See Also

Cryptographic Hash

A cryptographic hash is an algorithm which maps a string to a fixed sized string, with a method that is difficult or impossible to revert.

Some famous algorithms: MD5, SHA1, SHA256, HAVAL, Bcrypt.

Other algorithms include crc32(), though it is not considered a cryptography.

While the extension hash only process hashes, there are other extensions which offer these features: openssl, sodium and password hashing. Mhash and mcrypt are older PHP extensions, which are now discontinued.

<?php

    echo hash('ripemd160', 'The quick brown fox jumped over the lazy dog.');
    // produces ec457d0a974c48d5685a7efa03d137dc8bbde7e3

?>

Documentation

See Also

hash() Function

hash() is a PHP native function, that computes the hash of strings, with a wide range of algorithms, cryptographic or not.

It takes an algorithm name, such as md5, sha256, sha3-512, crc32, or ripemd160, and a string of data, and returns a hexadecimal digest by default, or raw binary output when the optional third argument is set to true. The list of algorithms available at runtime can be retrieved with hash_algos(), since it depends on how PHP was built.

hash() is meant for general-purpose hashing, such as checksums, cache keys, or data fingerprinting, and should not be used to store passwords: for that, PHP provides the dedicated password_hash() and password_verify() functions, which apply a slow, salted, adaptive algorithm designed to resist brute-force attacks. Fast general hashes like MD5 or SHA-1 are also considered cryptographically weak for security-sensitive purposes such as digital signatures.

<?php

    echo hash('ripemd160', 'The quick brown fox jumped over the lazy dog.');
    // produces ec457d0a974c48d5685a7efa03d137dc8bbde7e3

?>

Documentation

See Also

Hash Table Attack

A hash table attack, also known as HashDoS, hash-flooding attack, hash collision attack, or algorithmic complexity attack, is a denial of service technique that exploits the worst-case behavior of a hash table. When many keys are crafted to collide on the same bucket, insertions degrade from the expected average O(1) to O(n) per operation, turning a cheap request into a CPU-bound one that can stall the whole server with a small amount of traffic.

The attack was disclosed in 2011 as a cross-language vulnerability: PHP, and most other web platforms of the time, parsed incoming POST data into an array keyed by parameter name, using a hash function with a fixed, predictable seed. An attacker could precompute thousands of string keys that all hash to the same bucket, and submit them as a single request body, forcing the engine to spend seconds or minutes rebuilding that one array.

PHP mitigated the attack on two fronts: the Zend Engine’s HashTable now randomizes its hash seed per process, so collisions can no longer be precomputed offline, and the max_input_vars ini directive caps the number of input variables accepted in a single request, bounding the damage even if collisions occur.

<?php

    // A crafted request body with thousands of colliding keys
    // forces PHP to rebuild $_POST's underlying hash table repeatedly,
    // each insertion degrading toward O(n) instead of O(1).
    // max_input_vars limits how many such keys are accepted at all.

    foreach ($_POST as $key => $value) {
        // even an empty loop body pays the cost of building $_POST
    }

?>

Documentation

See Also

Hash Table

A hash table is a data structure that stores key-value pairs, and uses a hash function to compute an index, called a bucket, from the key, so that a value can be inserted, looked up, or deleted in average constant time O(1), regardless of the size of the table. It is one of the most used data structures in computing, backing associative arrays, sets, caches, and database indexes alike.

Collisions, two keys hashing to the same bucket, are unavoidable once the table grows, and are resolved either through chaining, where each bucket holds a small list, or through open addressing, which probes for the next free slot. A hash table’s performance degrades if the hash function distributes keys poorly, or if the table is not resized as it fills up.

Every PHP array is, internally, an ordered hash table: the Zend Engine’s HashTable C structure maps both integer and string keys to a bucket, while a separate doubly linked list preserves insertion order. This is why PHP arrays iterate in a deterministic, insertion order, unlike hash tables in many other languages.

<?php

    // PHP's associative array is a hash table
    $ages = [];
    $ages['Alice'] = 30; // 'Alice' is hashed to find its bucket
    $ages['Bob']   = 25;

    echo $ages['Alice']; // O(1) average lookup

?>

Documentation

See Also

Hash

Hash has several meanings:

  • PHP extension
  • PHP function
  • A general computer science concept, that transforms data into another value
  • A general computer science concept, that turns a string into another fixed-sized string, in a way that is difficult to revert. It is also called a digest.
  • A synonym for arrays with arbitrary keys, also known as a hashmap, map or associative array
  • A character to start a one line comment: #

Hash allows direct or incremental processing of arbitrary length messages using a variety of hashing algorithms.

While the extension hash only processes hashes, there are other extensions which offer these features: openssl, sodium and password hashing. Mhash and mcrypt are older PHP extensions, which are now discontinued.

<?php

    echo hash('ripemd160', 'The quick brown fox jumped over the lazy dog.');
    // produces ec457d0a974c48d5685a7efa03d137dc8bbde7e3
    
    // a conversion table is a hash
    $c = 2;
    $dictionary = [1 => 'a', 2 => 'b', 3 => 'c'];
    echo $dictionary[$c]; 
    
    // This is a hashmap, or also called a hash
    $hashMap = ['name' => 'Henry', 
                'family' => 'Troyat', 
                'age' => 33,
                ];
    
?>

Documentation

See Also

hash_equals()

hash_equals() is a built-in PHP function that compares two strings in constant time, regardless of where they differ.

It is specifically designed to prevent timing attacks: a regular == or === comparison short-circuits as soon as it finds a differing byte, leaking information about the compared value through the response time. hash_equals() always takes the same amount of time, making it safe for security-sensitive comparisons such as comparing password hashes, HMAC signatures, CSRF tokens, or API keys.

The function returns true if both strings are equal, false otherwise. If the two arguments are not strings, a TypeError is raised.

A common mistake is to compare hashes with ===, which is semantically correct but vulnerable to timing attacks. hash_equals() should be used whenever the compared value could be guessed by an attacker through repeated requests.

<?php

    $expected = hash_hmac('sha256', $message, $secret);
    $received = $_POST['signature'];

    // Vulnerable: === leaks timing information
    if ($expected === $received) {
        // ...
    }

    // Safe: constant-time comparison
    if (hash_equals($expected, $received)) {
        // ...
    }

?>

Documentation

See Also

Hashing

Hashing is the process of running data through a hash function, to produce a fixed-size value called a hash, or digest.

A good hash function is fast, deterministic, and spreads its output evenly, so that different inputs rarely produce the same hash, an event called a collision.

Hashing serves several distinct purposes applications:

  • Integrity checks and checksums, with fast algorithms like crc32 or md5, to detect accidental corruption.
  • Lookup structures, where hashing a key gives its position in a hash table, the internal structure behind PHP arrays.
  • Password storage, with slow, salted algorithms designed to resist brute-force attacks, such as bcrypt or argon2, via the password_hash() function.
  • Cryptographic fingerprints, with algorithms like the SHA family, to sign or verify data.

Hashing is one-way: a hash cannot be reversed to recover the original data. This distinguishes it from encryption, which is meant to be decrypted with a key.

<?php

    // fast, non-cryptographic hashing, for a lookup or checksum
    echo hash('crc32b', 'The quick brown fox jumped over the lazy dog.');

    // cryptographic hashing, for a fingerprint
    echo hash('sha256', 'The quick brown fox jumped over the lazy dog.');

    // slow, salted hashing, for password storage
    echo password_hash('correct horse battery staple', PASSWORD_BCRYPT);

?>

Documentation

See Also

Haystack

Haystack is a classic name, used to designate a dataset where something will be searched in. For example, with the functions strstr(), strpos(), strrchr(), array_search(), mb_strstr(), Grapheme::stristr(), etc.

This name refers to the expression ‘to search for a needle in a haystack’: when something is difficult to find in a large stack. In this context, the haystack is usually the data that is searched, while the needle is the thing that is searched for.

Traditionally, the haystack is the first argument, and the needle the second one. With named parameters, the ‘haystack’ name made its way in the PHP syntax.

<?php

    var_dump(strpos(haystack: 'abc', needle: 'b'));

?>

Documentation

See Also

Headers

Headers are HTTP response data sent to the client before any body output. PHP provides several built-in functions to manage them.

The native function header() sends a raw HTTP header. headers_sent() checks whether headers have already been sent. headers_list() returns the list of headers ready to be sent. header_remove() removes a previously set header.

Headers must be sent before any output, HTML, whitespace, or echo. Sending output before calling header() triggers a PHP warning.

<?php

header('Content-Type: application/json');
header('X-Custom-Header: value');

if (headers_sent($file, $line)) {
    echo "Headers already sent in $file on line $line";
}

echo json_encode(['status' => 'ok']);

?>

Documentation

See Also

Headless

A headless website, also known as a headless CMS, Content Management System, or decoupled website, is a web architecture where the frontend and backend are decoupled or separated from each other. In this setup, the frontend, the head or user interface, and the backend, the body or content management system, operate independently and communicate through APIs, Application Programming Interfaces.

Traditionally, websites are built using a monolithic architecture, where the frontend and backend are tightly integrated. The backend typically handles both content management and presentation logic, rendering HTML pages that are sent to the user’s browser.

In contrast, a headless website is designed with a clear separation of concerns.

Documentation

See Also

Heredocs

Heredoc is a string syntax, similar to nowdoc, with internal variable interpolation. They behave like double quoted strings.

The Heredocs syntax uses an arbitrary delimiter. The same delimiter will mark the end of the string.

Heredocs are convenient for large amount of text, that has to be hardcoded. Smaller string will be better suited with double quotes, while even longer text should be processed with a templating system.

It is possible to indent the text in a nowdocs string: to avoid this indentation to be passed at execution time, the final delimiter may be indented too. Its indentation will be removed from the parsed text.

<?php

$heredoc = <<<DELIM
This is a long text.

$variable will not be replaced, and the text stays intact.

DELIM;

$heredoc = <<<DELIM
    This is an indented text.
    DELIM;

?>

Documentation

See Also

Heuristics

Heuristics are practical, experience-based techniques or problem-solving approaches that are not guaranteed to be perfect or optimal, but are good enough for reaching an immediate, short-term goal or solution. They are essentially rules of thumb: simple, efficient strategies that help people make decisions quickly, especially in complex or uncertain situations.

  • Efficiency: heuristics allow for faster decision-making than exhaustive methods.
  • Simplicity: heuristics are often easy to understand and apply.
  • Approximation: heuristics provide solutions that are good enough rather than perfect.
  • Experience-based: heuristics rely on past experience, intuition, or common sense.

Documentation

See Also

Hexadecimal Integer

Hexadecimal integers are integers with an hexadecimal representation. Their value is the same, yet their are written in a different way than the common decimal.

Hexadecimal has native support with the 0x123 format. There is also support for hexadecimal characters, inside double-quote strings, with the \xhh syntax.

There are functions to convert from and to hexadecimal format: hexdec(), dechex() and base_convert(), from ten to sixteen, and then, with an arbitrary base, up to 36.

PHP also has special syntax for binary and octal numbers.

<?php

    $twenty    = 0x14;
    $twentyToo = 20;
    
    $i = "\x69"; // i is the 105 ASCII code
    $i = 'i';

?>

Documentation

See Also

Hexagonal Architecture

Hexagonal architecture, also known as Ports and Adapters architecture or the Onion architecture, is a software architectural pattern that promotes the separation of concerns and emphasizes modularity and flexibility. It was introduced by Alistair Cockburn in 2005 as a way to address the challenges of building maintainable and testable software systems.

In hexagonal architecture, the core principle is the isolation of the application’s business logic from external dependencies such as databases, frameworks, user interfaces, and external services. The architecture consists of three main components:

  • Core/Application Layer: this layer represents the business logic or the application’s core functionality. It encapsulates the use cases and domain models that define the behavior of the system. The core does not depend on any specific technologies or external systems.
  • Ports and Adapters: this layer acts as a boundary between the application and its external dependencies. It consists of two types of components:
  • Ports: these are interfaces or contracts that define the interaction between the core/application layer and the external systems. They provide a way for the core to communicate its needs and receive data or trigger actions.
  • Adapters: these are the implementations of the ports, connecting the core with the external systems. Adapters translate the core’s requests into a format that external systems can understand and vice versa. They handle the technical details of communication, such as data persistence, network protocols, or user interface rendering.
  • External Systems: this layer includes databases, frameworks, user interfaces, messaging systems, or any other external dependencies. The core does not have direct knowledge of these systems. Instead, it communicates through the defined ports and relies on the adapters to interact with them.

The hexagonal architecture promotes loose coupling, which makes the system more maintainable, testable, and adaptable to changes. It allows for easier swapping of external dependencies or modifying user interfaces without affecting the core business logic. The separation of concerns and clear boundaries between layers also make the system easier to understand and reason about.

Documentation

See Also

hg

HG is another name for Mercurial, which is a distributed version control system, DVCS, similar to Git. Mercurial is designed to help developers manage and track changes to source code and other files, like Subversion and Git. It is often used for collaborative software development and version control of various types of digital assets.

Documentation

See Also

Hidden State

Hidden state is state that exists in a program and influences its behavior but is not visible or accessible from the current scope.

Hidden state arises from: static properties of classes, as they persist for the lifetime of the request, modified anywhere; static variables; singleton instances; readonly properties; buffered output ob_start(); the internal pointer of arrays; file handles; extension-level state, e.g., the last regex error from preg_last_error(); and objects passed by reference that are mutated inside functions.

Hidden state is a common source of hard-to-reproduce bugs: the same function called twice with identical arguments may produce different results because some invisible state changed between the two calls. It also makes code difficult to test in isolation.

Unlike implicit state, which is about undeclared inputs, hidden state refers specifically to state that is not visible from the calling context.

<?php

    class Counter {
        private static int $count = 0; // hidden state: shared across all instances
    
        public static function increment(): void {
            self::$count++;
        }
    
        public static function get(): int {
            return self::$count;
        }
    }
    
    Counter::increment();
    // Somewhere else in the codebase...
    Counter::increment();
    
    echo Counter::get(); // 2 — but caller may not know it was called twice

?>

Documentation

See Also

Higher-Kinded Type

A higher-kinded type, or HKT, is a type that abstracts over type constructors rather than over concrete types. Where a generic type parameter T ranges over types like int or string, a higher-kinded parameter F ranges over types that themselves take a type argument, such as List, Maybe, or Promise.

The canonical example is the Functor typeclass in Haskell: fmap :: (a -> b) -> f a -> f b. Here f is a higher-kinded variable: it stands for any one-argument type constructor. This allows writing a single abstraction that works uniformly over List a, Maybe a, IO a, and any other functor, without knowing the concrete constructor in advance.

Higher-kinded types are what make purely functional abstractions like Functor, Monad, Applicative, and Foldable expressible without code duplication. Languages that support them natively include Haskell, Scala, PureScript, and Rust, partially through associated types.

PHP does not support higher-kinded types. PHP lacks native generics entirely, which is a prerequisite. Even PHPStan and Psalm @template annotations cover first-order generics only; they cannot abstract over parameterized type constructors. Functional PHP libraries such as marcosh/lamphpda approximate monadic abstractions at runtime using conventions, but without static type-level verification.

Documentation

See Also

HMAC

HMAC, short for Hash-based Message Authentication Code, is a mechanism for message authentication using cryptographic hash functions. It combines a secret key with the message to produce a fixed-size digest, providing both data integrity and authenticity.

HMAC is defined in RFC 2104 and is widely used in API authentication, JWT signatures, and webhook verification.

HMAC is computed with hash_hmac(), which accepts a hashing algorithm, the message, and a secret key.

<?php

    $key     = 'secret-key';
    $message = 'important data';
    
    $hmac = hash_hmac('sha256', $message, $key);
    
    echo $hmac; // 64-character hexadecimal string

?>

Documentation

See Also

Hoisting

Hoisting is a language feature where declarations are automatically moved to the top of their scope before code execution. It is notably a JavaScript feature and not a PHP feature.

PHP does not support hoisting for variables: a variable must be assigned before it is read, or it will be undefined.

PHP functions are pre-compiled and can be called before their textual declaration in the same file, which may look like hoisting but is actually the result of PHP’s two-pass compilation model.

PHP classes are not hoisted either: a class must be declared, autoloaded, before it is instantiated.

<?php

    // This works: functions are pre-compiled
    greet();
    
    function greet() { echo 'Hello'; }
    
    // This does NOT work: variables are not hoisted
    echo $message; // Undefined variable
    
    $message = 'Hello';

?>

Documentation

See Also

Homoiconicity

Homoiconicity is a property of a programming language in which code and data share the same representation. A homoiconic language can treat its own programs as data structures that may be inspected, transformed, and generated at runtime using the language itself. Lisp is the canonical example. Lisp programs are lists, and lists are native Lisp data.

PHP is not homoiconic in the classical sense: the source code is text, not a native PHP data structure. However, PHP provides several mechanisms that approximate homoiconic behaviour:

  • token_get_all(): tokenises a PHP source string into an array of token arrays, exposing the lexical structure of code as PHP data.
  • eval(): executes an arbitrary PHP string as code, allowing dynamically constructed programs to run.
  • The Reflection API, with ReflectionClass, ReflectionFunction, etc.: introspects the live structure of classes and functions at runtime.
  • The ast extension: parses PHP source into an abstract syntax tree represented as native ast\Node objects, enabling full read access to code structure.
  • nikic/php-parser, a userland library: provides a complete AST with read and write access, making it possible to parse, modify, and regenerate PHP code from PHP itself.

These tools are the foundation of static analysers, code generators, template engines, and macro-like systems built into PHP.

<?php

   // Tokenise PHP source as a PHP array
   $tokens = token_get_all('<?php echo 42; ?>');
   foreach ($tokens as $token) {
       if (is_array($token)) {
           echo token_name($token[0]) . ': ' . $token[1] . "\n";
       }
   }

   // Reflect on a function's structure at runtime
   $ref = new ReflectionFunction('array_map');
   echo $ref->getName() . ' accepts ' . $ref->getNumberOfParameters() . " parameters\n";

   // Build and execute code from data
   $op = '+';
   $result = eval("return 6 {$op} 7;");
   echo $result; // 13

?>

Documentation

See Also

Honey Pot

A honeypot is a spam-prevention technique used in forms. It’s a hidden field or trap designed to catch automated bots while remaining invisible to human users.

Documentation

See Also

Hook

A hook, sometimes called a callback hook, is a mechanism that allows custom code to be inserted at a predefined point in a process, framework, or system. Rather than modifying existing code directly, hooks let external logic react to or alter behaviour at extension points.

Hooks appear in several distinct forms during development:

  • Property hooks: they are the get and set accessors, attached directly to a class property, replacing the need for explicit getter and setter methods.
  • Webhooks: they are HTTP callbacks where a remote server pushes event notifications to a registered URL. The receiving application exposes an endpoint and reacts to the incoming payload.
  • Git hooks: they are shell scripts that Git executes automatically at specific points in the version-control workflow, such as before a commit or after a push. They are widely used to enforce code-quality checks in projects.

In plugin and framework architectures, hooks are often called filters or actions in WordPress, events in Symfony and Laravel, or simply listeners.

Documentation

See Also

Horizontal Scaling

Horizontal scaling, also called scaling out or scale-out, means adding more instances of an application or service to distribute the workload across multiple machines, rather than increasing the resources of a single machine.

Horizontal scaling typically involves running multiple PHP-FPM processes or application containers behind a load balancer. Because HTTP is stateless, PHP applications can often be scaled horizontally with relatively little effort, provided that shared state, such as sessions, caches, uploaded files, is externalised to shared services such as Redis, a centralised database, or an object-storage service.

Key considerations for horizontal scaling include: stateless application design, centralised session storage, distributed caching, shared file storage, and database connection pooling.

Horizontal scaling contrasts with vertical scaling, which adds physical resources to existing machines.

<?php

    // Externalising session storage to Redis for horizontal scalability
    ini_set('session.save_handler', 'redis');
    ini_set('session.save_path', 'tcp://redis:6379');

    session_start();
    $_SESSION['user_id'] = 42;

?>

Documentation

See Also

Hosting

Hosting is a server that stores the application code, and is accessible to an audience for usage. It means storing your scripts and applications on a remote server, which is managed and maintained by a host. It aims to provide the user with all the tools to set up the perfect environment for code development.

Documentation

See Also

Hot Cache

A hot cache holds the subset of data that is currently accessed often enough to stay in fast storage, close to the application: in memory, in an in-process cache, or in the first tier of a multi-level cache. Data that stops being requested gradually turns cold, see cold-cache, and is eventually evicted to make room for hotter entries.

The most common technique for keeping a cache hot is the LRU, Least Recently Used, eviction policy: every access moves an item to the hottest end of an ordering, and whenever the cache reaches its capacity, the item at the coldest end is discarded. Other eviction policies exist, such as LFU, Least Frequently Used, or plain TTL-based expiry, but LRU remains the default in most cache implementations, including Redis, APCu, and Symfony’s cache adapters.

A cache is hot right after a period of steady traffic, when the most relevant data is already loaded and hit rates are high. It runs cold right after a restart, a deployment, or a flush, forcing requests to fall back to the slower source of truth until the cache warms back up, see cache-warming.

<?php

    class LruCache
    {
        private array $items = []; // ordered by recency: oldest (coldest) first
    
        public function __construct(private int $capacity) {}
    
        public function get(string $key): mixed
        {
            if (!array_key_exists($key, $this->items)) {
                return null; // miss: this key isn't hot, or was never cached
            }
    
            $value = $this->items[$key];
            unset($this->items[$key]);
            $this->items[$key] = $value; // re-insert last: now the hottest entry
    
            return $value;
        }
    
        public function set(string $key, mixed $value): void
        {
            unset($this->items[$key]);
            $this->items[$key] = $value;
    
            if (count($this->items) > $this->capacity) {
                $coldestKey = array_key_first($this->items);
                unset($this->items[$coldestKey]); // evict the least-recently-used entry
            }
        }
    }
    
    $cache = new LruCache(capacity: 2);
    $cache->set('user:1', 'Alice');
    $cache->set('user:2', 'Bob');
    $cache->get('user:1');           // touched: now the hottest entry
    $cache->set('user:3', 'Carol');  // capacity exceeded: evicts 'user:2', the coldest entry

?>

Documentation

See Also

hrtime()

hrtime() is a native PHP function and an PIE extension. As a function, hrtime() returns the high precision time of the system.

HRT represents an acronym of High Resolution Time.

The time is of high precision, but counted from an arbitrary point of time: the value of this function is in calculating differences between two hrtime() calls, rather than the obtained value.

hrtime() is a modern replacement for microtime().

<?php

    $timeStart = hrtime(true);
    
    // Sleep some time
    usleep(100);
    
    $timeEnd = hrtime(true);
    $time = $timeEnd - $timeStart;
    
    echo "Slept for $time micro-seconds\n";
    
?>

Documentation

See Also

.htaccess

The .htaccess file is a configuration file used in web servers that support the Apache HTTP Server software. It allows the configuration of various aspects of how your web server operates and how it serves web content. The name htaccess stands for hypertext access, and the file is often referred to as an htaccess file.

Documentation

See Also

HTML Entities

HTML entities are a way to write special characters. For example, the superior and inferior characters have a special meaning in HTML. To be able to display them correctly, it is recommended to use the following writing: &gt; and &lt;.

This protection is extended to many characters. They have a numerical entity, such as &38; and a literal entity, such as &amp;, for the ampersand.

Such entities are typical of HTML. They are different in different languages.

PHP uses htmlentities() and html_entities_decode() to convert those characters from and to their entities.

HTML entities are useful in the HTML code, but they are confusing in a text file, which has no special entity.

Documentation

See Also

HTML Entity

HTML entities are special character sequences, that represents a single character. Such representation is not needed for simple characters, such as the Latin alphabet. On the other hand, they are needed for unusual characters, in particular when the encoding cannot be guaranteed to support it.

They are also needed to display characters, which have a special meaning, such as double quote ", or the greater > and lesser signs <.

HTML entities makes the source code longer, and harder to read.

HTML entities may have a letter representation, while they always have a numeric representation. For example, the ampersand may be written \&amp; and \&#38;.

PHP has functions to decode and encode: htmlentities() and htmlentities_decode(), htmlspecialchars() and htmlspecialchars_decode(). The get_html_translation_table() provides the full list of supported entities.

<?php

echo htmlentities('&'); // &amp;

print htmlentities_decode('&lt;A&gt;'); // <A>

?>

Documentation

See Also

HyperText Markup Language (HTML)

HyperText Markup Language, or HTML is the standard language used to create and structure content on the web.

HTML defines the structure of the page. It is completed by CSS, for styling, and Javascript, for behavior.

<?php

    // PHP outputing HTML code
    echo '<p>'. nl2br('Hello,
world').'</p>';

?>

Documentation

See Also

html_entity_decode

html_entity_decode() is a built-in PHP function that converts HTML entities back to their corresponding characters. It is the inverse of htmlentities().

It is used when HTML-encoded content must be processed as plain text, for example before storing in a database, sending in an email, or comparing strings.

A common security mistake is calling html_entity_decode() on user-supplied input and then outputting the result in HTML, which can reintroduce XSS vulnerabilities that were previously neutralized. The decode step should only happen when the output context is not HTML.

The flags parameter controls which quotes are decoded: ENT_QUOTES decodes both double and single quotes. The encoding parameter should be set explicitly to avoid unexpected behavior with multi-byte encodings.

<?php

    $html = '&lt;b&gt;Hello &amp; welcome&lt;/b&gt;';

    // Converts entities back to characters
    echo html_entity_decode($html, ENT_QUOTES, 'UTF-8');
    // Output: <b>Hello & welcome</b>

    // Dangerous: decoding then re-outputting in HTML context re-opens XSS
    $userInput = '&lt;script&gt;alert(1)&lt;/script&gt;';
    echo html_entity_decode($userInput); // outputs <script>alert(1)</script>

    // Inverse: htmlentities encodes all applicable characters
    $plain = '<b>Café & Co</b>';
    echo htmlentities($plain, ENT_QUOTES, 'UTF-8');

?>

Documentation

See Also

html_errors

When html_errors is enabled, the error message includes HTML tags, to be included in HTML pages.

The error message includes links to the official documentation.

By default, this directive is activated.

Documentation

See Also

htmlentities()

htmlentities() is a native PHP function which converts special characters in a string to their equivalent in HTML.

htmlentities() takes the string to be encoded, as an argument. It also accepts an argument $encoding to specify what the original encoding of the string is, in particular when it is not utf-8, which is the default configuration.

There are options to control which characters shall be encoded: for example, single and double quotes may be converted or not, with ENT_QUOTES and ENT_NOQUOTES, respectively.

Finally, $double_encode makes htmlentities() skip encoding a second time any entities already set in the string.

The opposite of htmlentities() is html_entity_decode().

<?php

    $str = "A 'quote' is <b>bold</b>";
    
    echo htmlentities($str);
    echo "\n\n";
    echo htmlentities($str, ENT_COMPAT);

?>

Documentation

See Also

HTMLPurifier

HTMLPurifier is a standards-compliant PHP library that filters user-submitted HTML against a whitelist of allowed tags and attributes, so that the result is safe to store and display.

Unlike a blunt tool such as strip_tags(), or a fully-escaping function such as htmlspecialchars(), HTMLPurifier actually parses the markup, so legitimate formatting, such as bold text, paragraphs, or links, survives, while dangerous constructs, such as <script> tags, inline event handler attributes like onclick, and javascript: URLs, are stripped out. It also repairs malformed HTML so the output is well-formed.

HTMLPurifier is typically used once, when untrusted rich-text content, such as a comment or a WYSIWYG editor submission, is first accepted, so that the sanitized version, not the raw input, is the one stored and later re-displayed.

<?php

    require_once 'HTMLPurifier.auto.php';

    $config = HTMLPurifier_Config::createDefault();
    $purifier = new HTMLPurifier($config);

    $dirty = '<p>Hello <script>alert(1)</script><b>world</b></p>';
    $clean = $purifier->purify($dirty);
    // '<p>Hello <b>world</b></p>'

?>

Documentation

See Also

htmlspecialchars

htmlspecialchars() is a built-in PHP function that converts special characters to their HTML entity equivalents.

It is commonly used to prevent Cross-Site Scripting, XSS, attacks when outputting user-supplied data in HTML. The characters it converts include &, ", ', < and >.

The flags parameter controls which quotes are converted: ENT_QUOTES converts both double and single quotes, which is recommended when outputting values in HTML attributes. Omitting quote handling is a classic source of XSS vulnerabilities.

htmlspecialchars() has an inverse function called htmlspecialchars_decode(), and a more exhaustive variant called htmlentities(), which converts all applicable characters.

<?php

    $userInput = '<script>alert("XSS")</script>';

    // Safe output: converts < > " & to HTML entities
    echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');

    // Dangerous: missing ENT_QUOTES leaves single quotes unescaped
    echo htmlspecialchars($userInput, ENT_COMPAT, 'UTF-8');

    // Reverse the conversion
    $html = '&lt;b&gt;Hello&lt;/b&gt;';
    echo htmlspecialchars_decode($html, ENT_QUOTES);

?>

Documentation

See Also

HTTP/3

HTTP/3 is the third major version of the HTTP protocol. Unlike HTTP/1.1 and HTTP/2, which run over TCP, HTTP/3 runs over QUIC, a transport protocol built on top of UDP.

By moving to QUIC, HTTP/3 removes the TCP-level head-of-line blocking that still affects HTTP/2: a lost packet only stalls the stream it belongs to, not every request multiplexed on the connection. HTTP/3 also inherits QUIC’s built-in TLS 1.3 encryption, 0-RTT connection resumption, and connection migration, which is a connection can survive a client switching networks. Header compression is handled by QPACK, an adaptation of HTTP/2’s HPACK designed to tolerate QUIC’s out-of-order stream delivery.

PHP does not natively supports HTTP/3; it depends on a QUIC-capable extension or client library, and on the underlying TLS stack, with OpenSSL 3.5+, exposing the QUIC APIs the extension needs.

Documentation

See Also

HTTP Code

HTTP status codes are three-digit numeric codes that are returned by web servers to indicate the outcome of a client’s request to a server. These codes are a part of the HTTP standard and provide information about the status of the request and the server’s response. HTTP status codes are grouped into different ranges, each with a specific meaning.

Here are some of the most common HTTP status codes and their general meanings:

1xx Informational:

100 Continue: the server has received the request headers and the client should proceed to send the request body.
101 Switching Protocols: the server is switching protocols according to the client's request.
102 Processing: the server has received the request and is processing it, but no response is available yet.
103 Early Hints: this status code is used to return some response headers before final HTTP message.

2xx Successful:

200 OK: the request was successful, and the server has returned the requested resource.
201 Created: the request was successful, and a new resource was created as a result.
202 Accepted: the request has been accepted for processing, but the processing has not been completed. 
202 Non-Authoritative Information: the server is a transforming proxy, such as a Web accelerator, that received a 200 OK from its origin, but is returning a modified version of the origin's response. 
204 No Content: the server has successfully processed the request, but there is no content to send in the response.

3xx Redirection:

301 Moved Permanently: the requested resource has been permanently moved to a new location.
302 Found: the requested resource has been temporarily moved to a different location.
303 See Other: the requested resource has been temporarily moved to a different location.
304 Not Modified: the client's cached version of the resource is still valid; no content is returned.

4xx Client Error:

400 Bad Request: the request from the client was malformed or invalid.
401 Unauthorized: authentication is required, and the client needs to provide valid credentials.
402 Payment Required: reserved for future use. 
403 Forbidden: the client does not have permission to access the requested resource.
404 Not Found: the requested resource was not found on the server.
405 Method Not Allowed: a request method is not supported for the requested resource.

5xx Server Error:

500 Internal Server Error: the server encountered an error while processing the request.
501 Not Implemented: the server either does not recognize the request method, or it lacks the ability to fulfil the request.
502 Bad Gateway: the server, while acting as a gateway or proxy, received an invalid response from an upstream server.
503 Service Unavailable: the server is currently unable to handle the request due to temporary overloading or maintenance of the server.
504 Gateway Timeout: the server, while acting as a gateway or proxy, did not receive a timely response from an upstream server.
505 HTTP Version Not Supported: the server does not support the HTTP version used in the request.

Documentation

See Also

HTTP Encoding

URL encoding, also known as percent-encoding, is a mechanism used to convert characters into a format that can be transmitted over the Internet. URLs can only contain a limited set of characters, consisting mainly of alphanumeric characters along with a few special characters such as hyphens, underscores, periods, and tilde ~.

When a URL contains characters outside this set, such as spaces or non-alphanumeric characters like ampersands, question marks, or slashes, URL encoding is used to represent those characters in a safe and compatible format.

URL encoding works by replacing each non-alphanumeric character with a percent sign % followed by two hexadecimal digits that represent the ASCII or Unicode code of the character. For example:

  • Space ' ' is encoded as %20.
  • Ampersand & is encoded as %26.
  • Question mark ? is encoded as %3F.
  • Slash / is encoded as %2F.

URL encoding ensures that URLs remain valid and functional across different systems and protocols. It is commonly used in web browsers, HTTP requests, and other internet-related technologies to transmit data safely and reliably. Most programming languages provide built-in functions or libraries to perform URL encoding and decoding operations.

PHP provides urlencode() and urldecode() to handle coding and decoding this format.

<?php

    $text = "This is the Euro symbol €.";
    
    // builds a valid URL 
    $url = 'https://www.example.com/'.urlencode($text);
    
    // https://www.example.com/This+is+the+Euro+symbol+%27%E2%82%AC%27.

?>

Documentation

See Also

HTTP Headers

HTTP headers are extra information, exchanged between the server and the client, to configure further the network transaction.

They are separated from the content, which usually represents the HTML page, or the binary code of the image, archive.

HTTP headers have a name, and a value. They are made of ASCII text, and separated by a colon :

HTTP headers are the same with HTTPS.

HTTP headers are handled by the following functions: headers_sent(), headers_list(), header(), header_remove(), header_register_callback().

<?php

    function trumpet($a, $b) {
        return $a - $b;
    }

?>

Documentation

See Also

HTTP Request Headers

HTTP request headers are sent by the client to the server at the start of an HTTP request. They carry metadata about the client, the requested resource, and the desired response format.

Request headers are available in the $_SERVER superglobal with the HTTP_ prefix, e.g., $_SERVER['HTTP_ACCEPT'], or through getallheaders() for the full list.

Common request headers include Accept, Authorization, Content-Type, User-Agent, and Cookie.

<?php

// Read a specific request header
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown';

// Read all request headers
$requestHeaders = getallheaders();

foreach ($requestHeaders as $name => $value) {
    echo "$name: $value", PHP_EOL;
}

?>

Documentation

See Also

HTTP Method

An HTTP method, also called an HTTP verb, defines the intended action of an HTTP request. The most common methods are GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS.

Methods differ in their safety and idempotency guarantees. A method is safe if it does not modify server state, such as GET, HEAD, OPTIONS. A method is idempotent if repeating it produces the same result as a single call GET, HEAD, PUT, DELETE. POST and PATCH are neither safe nor guaranteed idempotent by the specification, which is why APIs that use them for state-changing operations often implement explicit idempotency mechanisms such as idempotency keys.

The request method is available via $_SERVER['REQUEST_METHOD'] or through framework helpers.

<?php

    $method = $_SERVER['REQUEST_METHOD']; // GET, POST, PUT, PATCH, DELETE ...

?>

Documentation

See Also

Hyper Text Transfer Protocol (HTTP)

The Hypertext Transfer Protocol, or http, is an application layer protocol in the Internet protocol.

It is also a wrapper for network communication, allowing it to be used directly with functions such as file_get_contents().

HTTP is related to HTTPS, the secure version of HTTP.

Documentation

See Also

http_build_query()

The http_build_query() native function is used to generate a URL-encoded query string from an associative array or an object. This is commonly used to build query strings for HTTP GET requests or for use in URLs.

http_build_query() converts automatically backed enumerations to their type value, integer or string, when they are used as values in the array. This is a PHP 8.4 feature.

http_build_query() provides arguments to deal with numeric keys, a prefix may be added, with custom separators and encoding type.

The reverse function for http_build_query() is parse_str(), which converts a query string into an array.

<?php

    enum A: int {
        case A = 1;
    }
    
    print http_build_query(['x' => A::A, 'b' => 3]);
    //    x=1&b=3

?>

Documentation

See Also

Hyper Text Transfer Protocol Secure (HTTPS)

Hypertext Transfer Protocol Secure, or HTTPS, is an extension of the Hypertext Transfer Protocol, HTTP. It is used for secure communication over a computer network, and is widely used on the Internet.

<?php

    headers('https://www.exakat.io/');

?>

Documentation

See Also

Hydratation

To hydrate is to fill an object with data coming from an unstructured format, before using it. This happens when reading data from a database, a dataset, or from the incoming superglobals.

Hydration is quite repetitive, as the source data must be mapped to the corresponding property. Validation may also play a part in that operation.

Documentation

See Also

Hygienic Macro

A hygienic macro system is one in which macro expansions cannot accidentally capture or shadow variables from the calling scope. In a non-hygienic macro system, such as C preprocessor macros, a macro that introduces a temporary variable risks clashing with a variable of the same name in the code that invokes it. Hygienic macros, pioneered in Scheme’s syntax-rules and later adopted by Rust’s macro_rules!, solve this by tracking the lexical scope of every identifier introduced by the macro, renaming variables as needed during expansion so that caller and macro identifiers remain isolated.

Other languages with hygienic or near-hygienic macro systems include Racket, Elixir with defmacro with quoted ASTs, Julia with @macro with hygiene by default, and Nim and its macro statements.

PHP has no macro system of any kind, hygienic or otherwise. PHP source code is parsed and executed directly; there is no macro-expansion phase. The closest available mechanisms are:

  • eval(): executes a string as PHP code, but operates at runtime on already-parsed text; no variable hygiene is guaranteed.
  • Token-level preprocessing: tools such as yay, a PHP macro preprocessor, run before the PHP parser and perform textual or token-level substitutions, but provide no hygiene guarantees.
  • nikic/php-parser: allows full AST rewriting via a userland visitor, enabling macro-like transformations with explicit scope tracking that the author must implement manually.
  • Functions passed by reference: the most common PHP idiom for swap-style macros is a plain function with & parameters, which requires an explicit call rather than inline expansion.
<?php

    // PHP has no inline macros. Functions are the closest alternative,
    // but they carry call overhead and cannot expand inline in the caller's scope.

    // A swap macro in Rust would expand inline with no variable-capture risk:
    //   let (x, y) = (y, x);   // generated hygienically by the macro
    //
    // In PHP the only option is a function with reference parameters:
    function swap(mixed &$a, mixed &$b): void {
        [$a, $b] = [$b, $a];
    }

    $trunk = 1;
    $tusk = 2;
    swap($trunk, $tusk);
    echo "$trunk $tusk"; // 2 1

    // Token-level macro preprocessing (yay library, run before PHP parses the file):
    //   macro {swap(·a, ·b)} >> {[·a, ·b] = [·b, ·a];}
    // This expands textually: no hygiene: a local variable named $a in the macro
    // definition could collide with a caller variable also named $a.

?>

Documentation

See Also

hypot()

hypot() is a PHP native function, that computes the length of the hypotenuse on a right triangle, given the length of the two other sides.

hypot() is the same as calculating sqrt(pow($a, 2) + pow($b, 2)) or sqrt($a ** 2 + $b ** 2). It is also the length of a segment from the origin to a point of coordinates ($a, $b).

<?php

    $x = 3;
    $y = 4;
    var_dump(hypot($x, $y));

?>

Documentation

See Also

IaaS

IaaS, Infrastructure as a Service, is a cloud-computing model in which a provider supplies virtualized computing resources, such as servers, storage, and networking, over the internet, on demand and billed by usage.

Unlike PaaS or SaaS, IaaS gives the consumer control over the operating system, runtime, and application stack. The provider manages physical hardware and hypervisors; the consumer manages everything above.

PHP applications hosted on IaaS run on virtual machines or bare-metal instances managed by the team. Common IaaS providers include AWS EC2, Google Compute Engine, and Azure Virtual Machines. Automation tools such as Ansible, Terraform, or Chef are typically used to provision and configure the PHP runtime, web server, and database on top of the raw infrastructure.

<?php

    // Interacting with IaaS resources via an SDK — AWS example
    use Aws\Ec2\Ec2Client;

    $client = new Ec2Client([
        'region'  => 'eu-west-1',
        'version' => 'latest',
    ]);

    // List running instances
    $result = $client->describeInstances([
        'Filters' => [['Name' => 'instance-state-name', 'Values' => ['running']]],
    ]);

    foreach ($result['Reservations'] as $reservation) {
        foreach ($reservation['Instances'] as $instance) {
            echo $instance['InstanceId'] . PHP_EOL;
        }
    }

?>

Documentation

Infrastructure as Code (IaC)

Infrastructure as Code, aka IaC, is the practice of managing and provisioning infrastructure through machine-readable configuration files rather than manual processes or interactive configuration tools.

Tools such as Terraform, Ansible, Pulumi, and AWS CloudFormation are commonly used for IaC. PHP applications deployed with IaC benefit from reproducible, version-controlled environments.

PHP developers typically use IaC to define server configurations, container orchestration, and cloud resource provisioning for their applications.

Documentation

See Also

Iconv

iconv is a PHP extension that stands for Internationalized CONVersion. It provides functionality to convert strings between different character encodings, making it useful for dealing with multilingual and internationalized applications.

The iconv extension allows to convert strings from one character encoding to another, and it also supports transliteration and character set detection. This is particularly important when dealing with data that may come from different sources with various character encodings.

iconv is both a PHP function, a PHP extension and an independent library for character encoding conversion, also known as libiconv.

<?php

  echo 'TRANSLIT : ', iconv("UTF-8", "ISO-8859-1//TRANSLIT", $text), PHP_EOL;
  // TRANSLIT : This is the Euro symbol 'EUR'.

?>

Documentation

See Also

Integrated Environment of Development (IDE)

An IDE is a development tools which thrive to gather all needed tools in one place to allow for a full development experience.

  • Syntax Highlighting
  • Code Completion
  • Snippets & Templates
  • Refactoring Tools
  • Multiple Cursors/Selections
  • Static Code Analysis
  • Debugging
  • PHPDoc Support
  • Framework Awareness
  • Project Navigation
  • Version Control
  • Database Tools
  • Composer & Dependency Management
  • Remote Development
  • Linters & Formatters
  • Code Review Tools
  • Testing Support
  • Performance Profiling
  • Plugin Ecosystem
  • Custom Themes & Keymaps
  • Multi-Language Support

IDE are often compared to editor, which focus on reactivity and a more limited set of features, and AI editors, where the AI handles management of the complementary tools.

Documentation

Idempotent

Idempotent is said of an operation, which always yields the same result after the first call. In other words, repeating the operation does not produce a different result beyond the initial application.

This is the case of strtolower() and strtoupper(): once the string has been made lower case, resp. upper case, calling the same function again on the string will not change the result.

In distributed systems and HTTP APIs, idempotency is enforced through an idempotency key: a unique identifier, typically a UUID, supplied by the client with each request. The server stores the outcome of the first request under that key and returns the cached result for any subsequent request carrying the same key, preventing duplicate side-effects such as double payments or duplicate record creation.

<?php

    $string = aBC;
    
    $string1 = strtolower($string); // abc
    $string2 = strtolower($string2); // abc
    $string3 = strtolower($string3); // abc
    $string4 = strtolower($string4); // abc
    // ... 

?>

Documentation

See Also

Identical Operator

Identical is the state of two variables, which contain the same data, with the same type. It is the same as equality, without the type-juggling.

Identical operators are ===, !==. The match() command also uses identical comparisons.

<?php

    var_dump(0 == "0000"); // true
    var_dump(0 === "0");   // false
    var_dump(0 === 0);     // true
    
?>

Documentation

See Also

Identification

Identification refers to the process of recognizing who the user is, usually by having them provide a unique identifier.

Identification is closely related, but distinct from authentication, which is the proof that the identified user is who he claims to be.

Documentation

See Also

Identifier

An identifier is simply a name used to identify a function, class, enum, interface, trait, method, constant, or class constant.

Identifiers are subject to certain rules, depending on their usage: for example, xor may be used as a name for a method, but not for a global constant.

Identifiers are mentioned in syntax errors, where a string is used while the parser expected another kind of token.

Identifiers are relative to the current namespace. They may be created by creating one of the supporting structure, such as function, global constant… Their features are related to absolute names, such as \A, and relative names, such as B\C, not shown here.

In the illustration, A is an identifier for a global constant: it is valid. B should most probably be a variable, and yields an error.

<?php

    // A is a valid identifier
    foreach(A as $b) {}

?>

Documentation

See Also

Identity Comparison

The identity comparison === compares two values, using their respective types, and then, their value. Both must be identical to pass.

There is also the !== operator, for distinct values: either the type, or the value.

<?php

var_dump(1 === 1);    // true

var_dump(1 === true); // false
var_dump(1 == true);  // true

?>

Documentation

See Also

Identity

Identity has several related but distinct meanings:

  • Identity comparison: a stricter way to compare two things, that includes types and avoid type-juggling. The other comparison is equality.
  • Identity function: the function that returns its only argument, without any modification. It is a base for null pattern, and is useful when a callable is required, but should be a no operation
  • Object identity: two variables refer to the same object in memory. This is tested with the === operator on objects, or with spl_object_id(). Two objects may be equal in value but not identical in identity
  • User identity: the set of attributes that uniquely identify a user or entity in a system: username, email, unique ID. Identity is established by identification and verified by authentication
  • Domain identity: in Domain-Driven Design, an entity is defined by its identity rather than its attributes. Two User objects with the same $id are the same entity even if other properties differ, while two Money value objects with the same amount are equal without having an identity

PHP applications manage identity through unique IDs, session tokens, and authentication tokens such as JWT.

<?php

    $a = new stdClass();
    $b = $a;        // same identity
    $c = clone $a;  // different identity, same values
    
    var_dump($a === $b); // true  — same identity
    var_dump($a === $c); // false — different identity
    
    echo spl_object_id($a); // unique integer ID for $a

?>

Documentation

See Also

Idiomatic

Idiomatic code follows the conventions and constructs that are natural to a specific language, rather than code that merely compiles or runs correctly. Idiomatic PHP favors the features and patterns that the language and its ecosystem consider normal, readable and maintainable, over literal translations of patterns from other languages.

Writing idiomatic PHP means picking the tool the language actually offers for a given problem: a foreach loop instead of manual index bookkeeping, ?? instead of isset() ternaries, typed properties instead of ad-hoc docblocks. Non-idiomatic code often signals that the author is more familiar with another language, or that the codebase has not kept up with the evolution of PHP.

A short list of idiomatic PHP features:

  • foreach to iterate arrays and Traversable, rather than indexed for loops;
  • Null coalescing operator ?? and null coalescing assignment ??=, rather than isset() combined with a ternary;
  • Nullsafe operator ?-> to chain calls on a possibly null object;
  • Arrow functions fn() => ... for short closures that capture the outer scope implicitly;
  • Spread operator ... to unpack arrays into arguments, and variadic parameters to collect them;
  • Named arguments to make call sites self-documenting and to skip optional parameters;
  • Typed properties, constructor property promotion and readonly properties, rather than untyped properties documented only in a docblock;
  • Enums, rather than class constants used to emulate a closed set of values;
  • Match expressions, rather than switch with fallthrough or repeated break;
  • Interfaces and first-class callable syntax, rather than string or array callables;
  • Exceptions for error handling, rather than mixed return values or error codes;
  • PSR autoloading and Composer, rather than manual require/include chains.

What counts as idiomatic changes with each PHP version: a construct that was idiomatic in version 5 may be superseded once a more direct language feature is introduced.

<?php

    // Not idiomatic: manual index, isset()+ternary, switch with breaks
    for ($i = 0; $i < count($users); $i++) {
        $user = $users[$i];
        $name = isset($user['name']) ? $user['name'] : 'Anonymous';

        switch ($user['role']) {
            case 'admin':
                $label = 'Administrator';
                break;
            case 'editor':
                $label = 'Editor';
                break;
            default:
                $label = 'Guest';
        }
    }

    // Idiomatic PHP: foreach, ??, match
    foreach ($users as $user) {
        $name = $user['name'] ?? 'Anonymous';

        $label = match ($user['role']) {
            'admin'  => 'Administrator',
            'editor' => 'Editor',
            default  => 'Guest',
        };
    }

?>

Documentation

See Also

Insecure Direct Object Reference (IDOR)

An Insecure Direct Object Reference, or IDOR, is a vulnerability where an application exposes a direct reference to an internal object, such as a database id, a filename, or a primary key, and lets a user access that object without checking whether they are actually authorized to do so.

IDOR is typically exploited by tampering with an identifier in a URL, form field, or API payload, and substituting it with another value: if the application trusts the identifier without an authorization check, the attacker reaches data or actions that belong to someone else.

Mitigations include enforcing an authorization check on every request that references an object, and using indirect, unpredictable references, such as UUID or per-user mapping tables, instead of sequential ids.

<?php

    // IDOR: any authenticated user may fetch any invoice, just by changing the id
    $id = $_GET['invoice_id'];
    $invoice = $db->query("SELECT * FROM invoices WHERE id = $id");

    // Mitigation: also verify ownership of the requested object
    $invoice = $db->query("SELECT * FROM invoices WHERE id = $id AND user_id = " . $currentUser->id);

?>

Documentation

See Also

If Then Else

A if-then-else command branches the execution based on a condition. When the condition is true, the first branch, called then is executed. When the condition is false, the second branch, called else, is executed.

If-then structures may be chained with the elseif keyword. The else branch is then a new if-then structure, with a second condition.

<?php

    $number = rand(0, 10);
    
    if ($number % 2 === 0) {
        print "$number is even\n";
    } else {
        print "$number is odd\n";
    }

?>

Documentation

See Also

Iffectation

An iffectation is both an assignation and a condition at the same time.

Whether an assignation should be used as a condition is debated. It makes the code less readable, as the assignation is hidden in the if condition.

It also saves some extra lines of code, when the condition applies to something that will immediately be used.

<?php

if ($trunk = trumpet()) { }

// same, without the iffectation
$trunk = trumpet();
if ($trunk) { }


?>

Documentation

See Also

Ignored Catch

catch does not check that the caught exception exists: it simply checks that the raised exception match the class name, its parent or its interface. When a typo happens in the class name or the class does not exists, the clause fails every time.

<?php

    try {
        callSomeMethod();
    } catch (\UndefinedException $e) {
        die('This never happens');
    } catch (\Exception) {
        // process the error here
    }

?>

Documentation

Image Injection

Image injection is a class of attack where malicious content is embedded inside a file that is presented or processed as an image. The attack exploits the fact that parsers and browsers use different heuristics to determine a file’s type, and that image processing libraries sometimes execute embedded code.

Common image injection scenarios include:

  • Polyglot files: a file that is simultaneously a valid image and a valid script, written in HTML, PHP, SVG, etc. When such a file is saved with a .jpg extension and later served or included, the server or browser may execute the embedded payload
  • SVG injection: SVG files are XML and may contain <script> elements. Displaying attacker-supplied SVG inline triggers cross-site scripting
  • Metadata injection: EXIF data embedded in a JPEG can contain PHP code that is executed if the application passes the raw file to eval() or include()

Mitigation strategies include:

  • Re-encoding uploaded images with GD or Imagick to strip embedded payloads
  • Validating MIME type server-side with getimagesize() or finfo
  • Storing uploads outside the document root and serving through a controller
  • Disabling SVG upload or sanitising SVG content.
<?php

    // Re-encoding strips EXIF and any embedded code
    function sanitizeImage(string $path): bool {
        $info = getimagesize($path);
        if ($info === false) {
            return false;
        }
    
        [$width, $height, $type] = $info;
    
        $src = match ($type) {
            IMAGETYPE_JPEG => imagecreatefromjpeg($path),
            IMAGETYPE_PNG  => imagecreatefrompng($path),
            IMAGETYPE_GIF  => imagecreatefromgif($path),
            default        => false,
        };
    
        if ($src === false) {
            return false;
        }
    
        imagejpeg($src, $path, 90);
        imagedestroy($src);
    
        return true;
    }

?>

Documentation

See Also

Image

Images may be different things:

  • A visual representation. PHP has several extensions to handle images: imagick, gd
  • A Docker image: a pre-packaged snapshot of an application and everything it needs to run.

Documentation

See Also

imagick

imagick is the native PHP extension to create and modify images using the ImageMagick library.

imagick is also known by the name Image Magick. It is able to convert between various formats, to edit, combine and optimize images.

<?php

    $imagick = new Imagick($imagePath);
    
    $imagick->resizeImage($width, $height, Imagick::FILTER_TRIANGLE , 0);
    
    $width = $imagick->getImageWidth();
    $height = $imagick->getImageHeight();
    
    $newWidth = $width / 2;
    $newHeight = $height / 2;
    
    // crop image to half the middle of the image
    $imagick->cropimage(
        $newWidth,
        $newHeight,
        ($width - $newWidth) / 2,
        ($height - $newHeight) / 2
    );
    
    // resize the picture to bigger size (4 times)
    $imagick->scaleimage(
        $imagick->getImageWidth() * 4,
        $imagick->getImageHeight() * 4
    );
    
    // write the image to disk
    $imagick->writeImage($imagePath.'.2');

?>

Documentation

See Also

ImagickException

The ImagickException exception is thrown when an error happens while processing an Imagick operation. Any of the Imagick functions may throw that exception.

<?php

    try {
        $imagick->gammaImage($correction, \Imagick::CHANNEL_ALL);
    } catch (\ImagickException $e) {
        throw new RuntimeException('Failed to apply gamma correction to the image');
    }

?>

Documentation

See Also

ImagickPixelException

ImagickPixelException is an exception class that is used to handle exceptions related to problems with ImagickPixel objects.

ImagickPixelException happens when using invalid color specification.

ImagickPixelException is related to the Imagick extension.

<?php

    try {
        // valid creation
        new ImagickPixel("LightCoral");
        
        // invalid creation
        new ImagickPixel("LightCorral");
    } catch (ImagickPixelException $e) {
        log("Error while creating a pixel");
    }

?>

Documentation

See Also

IMAP

IMAP, for Internet Message Access Protocol, is a PHP extension that provides functions to connect to mail servers over IMAP, POP3, and NNTP, list and search mailboxes, fetch message headers and bodies, and manage flags such as read, deleted, or flagged.

The extension is built on the c-client library. A connection is opened with imap_open() against a mailbox specification that includes the server, port, and protocol, for example {imap.example.com:993/imap/ssl}INBOX. Once connected, functions such as imap_search(), imap_fetchbody(), and imap_headerinfo() are used to read mail, while imap_mail_move() and imap_delete() manage messages.

The IMAP extension has been removed from the PHP core distribution as of PHP 8.4 and moved to PECL, reflecting both its declining use, most projects now talk to mail providers over an HTTP API, and the fact that the underlying c-client library is largely unmaintained. Projects that still need IMAP access on PHP 8.4+ must install the PECL package explicitly or switch to a pure-PHP IMAP client library.

<?php

    $mailbox = '{imap.example.com:993/imap/ssl}INBOX';
    $inbox = imap_open($mailbox, 'user@example.com', 'password');

    $emails = imap_search($inbox, 'UNSEEN');
    if ($emails) {
        foreach ($emails as $id) {
            $header = imap_headerinfo($inbox, $id);
            echo $header->subject . PHP_EOL;
        }
    }

    imap_close($inbox);

?>

Documentation

See Also

Immutable

An immutable object, exhibiting immutability, is an object that can’t be changed. It may be created, read and cloned. On the other hand, a mutable object may change when one of its method is called, even if this is not visible from the outside.

Immutable objects are thread-safe.

Immutable objects often return a clone version of themselves, after modification.

<?php

    class Elephpant {
        private $age = 0;

        function inc() : self {
            $return = clone $this;
            $return->age +=1;

            return $return;
        }
    }

    $elephpant = new elephpant();
    $olderElephpant = $elephpant->inc();

    // $elephpant and $olderElephpant are two distinct objects

?>

Documentation

See Also

Imperative Programming

Declarative programming is the programming style where each step is described to the program, which then, executes them one after the other.

This approach favors the control on the execution: it is easy to check the steps, and enforce that each step is done when expected.

Imperative programming does not leave room for optimisation, as the step order is controlled externally. Everything has to be written as expected, leading to extra labor.

Documentation

See Also

Implementation-Defined Behavior

Implementation-defined behavior is behavior that the language specification leaves to the engine to decide, on the condition that the engine picks one consistent option and documents it. Unlike undefined behavior, the result is always predictable once the specific engine and its documentation are known.

Examples include the size of an int, 32 or 64 bits, depending on the platform, the precision of float operations, and the exact wording of engine-generated error messages.

<?php

    // implementation-defined: the size of PHP_INT_MAX depends on the platform
    var_dump(PHP_INT_MAX); // int(9223372036854775807) on a 64-bit build
                           // int(2147483647) on a 32-bit build

?>

Documentation

See Also

implements

implements is a keyword, dedicated to classes. It specify which interfaces a class implements.

Implemented interfaces may be tested with types, instanceof, and is_a().

The list of implemented interfaces is accessible with the class_implements() function.

<?php

    interface Trumpeter {
        function trumpet() ;
    }

    // empty interface
    interface Migratory { }

    class Elephpant implements Trumpeter, Migratory {
        private $property;

        public function trumpet() {
            return 1;
        }
    }

?>

Documentation

See Also

Implicit State

Implicit state is state that a function or method relies on without declaring it as a parameter or return value. It exists outside the explicit flow of data through the code.

Implicit state includes: global variables, e.g. $GLOBALS, superglobals like $_SESSION, $_GET, static class properties modified as side effects, the current error state, locale settings, timezone, and active database connections.

Implicit state makes code harder to test: they require careful setup of global state or a clean and reset operation before each test, they are harder to reason about as behavior depends on invisible context, and are prone to subtle bugs when state leaks between different parts of the application or across requests.

Prefer explicit state: pass values as parameters and return new state as return values.

<?php

    // Implicit state: function behavior depends on global timezone setting
    date_default_timezone_set('UTC');
    echo date('H:i'); // depends on global timezone, not a parameter
    
    // Explicit alternative: pass timezone explicitly
    echo (new DateTimeImmutable('now', new DateTimeZone('UTC')))->format('H:i');

?>

Documentation

See Also

Implicit

A feature is implicit when it is available, yet not explicitly visible.

For example, objects are passed by reference to functions: any change applied to that object, inside the function, is also available in the calling context.

Until PHP 8.4, it was possible to assign null as a default value to any typed parameter: null was implicitly an accepted type for that value.

The contrary to implicit is explicit. This notion shares similarities with hidden features and collateral features.

<?php

function trumpet($object) {
    $object->age = 1;
}

$object = new stdClass();
trumpet($object);
echo $object->age;

?>

Documentation

See Also

implode()

The implode() function is used to join elements of an array into a glue, placed between each element.

implode() uses the first argument as the separator, and the second as the array. In older versions of PHP, this order could be reversed, but it recommended to avoid using it, as that feature was removed.

implode() has an alias called join().

implode() converts the elements of the array to string before merging them in a string. In particular, objects are converted to string with the magic-method, and sub-arrays are converted to Array, with a warning. Backed enumerations are not usable with that function.

implode() is faster to concatenate multiple strings than accumulating the concatenations in a single string. This happens because there is less need to allocate memory piecemeal.

<?php

declare(strict_types=1);

class Elephpant {
    function __toString() {
        return 'c';
    }
}

$elephpant = new Elephpant();
echo implode('a', ['a', 'b', new Elephpant()]);

?>

Documentation

See Also

Import

Imports are elements of a different namespaces, brought into the current one. They rely on the use expression, usually at the beginning of the file.

Once a class, interface, trait, enum, function or constant has been imported, it is available in the current namespace. It may also use another name, also called alias.

Import is sometimes mistaken with inclusion, which bring in code.

<?php

    namespace A;
    
    // import classes
    use B\C; 
    use D\E as F; 
    // import function
    use function A\foo; 
    // import constants
    use const A\D;
    
    // call an imported function with an imported constant
    foo(D); 

?>

Documentation

See Also

Impure Function

An impure function is a function that has at least one of the following characteristics:

  • Non-deterministic: for the same input, an impure function may return different output. For example, date() and random_string() return different values for each call, by definition.
  • Create side-effect: an impure function modify a state: a global variable, a row in a table, a lock, a file or data. This may affect any subsequent call to this function, leading to the previous characteristic.

A function that is not impure is a pure function.

This notion applies to functions, methods, native and custom functions, closures and arrow functions.

<?php

    echo random_string(0, 10);
    
    // an impure function: 
    // the static variable is a state that changes over time
    function trumpet() {
        static $age = 0;

        return $age++;
    }

?>

Documentation

See Also

in_array()

in_array() function checks if a value exists in an array. It is important to use the third parameter ‘strict’ to true to ensure type safety and avoid unexpected behavior due to PHP’s loose comparison rules.

A surprising pitfall is misplaced parentheses, which can lead to valid but incorrect logic: if (in_array($a, $b) == $c) vs if (in_array($a, $b == $c)).

<?php

    $array = [1, 2, '3', 4];
    
    // Loose comparison (default): returns true
    var_dump(in_array(3, $array)); 
    
    // Strict comparison: returns false
    var_dump(in_array(3, $array, true));
    
    // Misplaced parenthesis pitfall
    $a = 1;
    $b = [1, 2, 3];
    $c = true;
    
    // Correct usage
    if (in_array($a, $b) === $c) {
        echo 'Found';
    }
    
    // Potentially incorrect but valid syntax
    if (in_array($a, $b === $c)) {
        echo 'Valid PHP, but unlikely what was intended';
    }

?>

Documentation

See Also

include

Inclusion, often represented by the include keyword and more rarely by require, is the process to read an external file, and evaluate with the current application for execution. It may define new structures, and execute code.

Inclusion relies on four language structures: include, require, include_once, require_once.

Inclusion is often only used in autoload() functions: the code is included class per class, upon request. Besides the include 'vendor/autoload.php';, there might be another inclusion for functions and global constant, which must be included manually.

Inclusion runs easily into the already defined error: this happens when the same file is included twice, and it defines a structure, such as function, constant, class, etc. At the second inclusion, the structure is already defined, and cannot be included again. This is why there is the include_once command, which skips the inclusion if it already happened. This error was later reduced by using autoload, which is only called when a class, interface, trait or enumeration is used.

vars.php
<?php

    $color = 'green';
    $fruit = 'apple';

?>

test.php
<?php

    echo "A $color $fruit"; // A
    
    include 'vars.php';
    
    echo "A $color $fruit"; // A green apple

?>

Documentation

See Also

include_path

The include_path directive sets the directories where the file functions look for files to read or write files.

File functions may be require(), include(), fopen(), file(), readfile(), file_get_contents().

include_path default to ., the current directory. It may list several directories, using :: as a separator.

Documentation

See Also

Inclusion Hell

Inclusion hell is the tangled state a codebase reaches when include, require, and their _once variants are scattered across many files as the only way to make a class or function available, instead of being loaded through a single, predictable mechanism. Because each file may itself include others, the actual set of files loaded for a given request becomes a deep, hard-to-trace chain: knowing whether a given class is already defined at a given point in the code requires mentally following every inclusion that happened before it, rather than looking it up in one place.

The usual symptoms are a Fatal error: Cannot redeclare when the same file is pulled in twice through a plain include instead of include_once, includes written with relative paths that break the moment the including file is moved or included from a different working directory, circular inclusion where file A includes file B which includes file A again, and a change to one file’s include list unpredictably breaking a feature defined in an unrelated folder.

Inclusion hell was common in codebases before class autoloading and Composer’s PSR-4 autoloader became standard practice. Autoloading replaces the whole chain of manual includes with a single hook, invoked only when a class is actually used, and a naming convention that maps a class name directly to its file, removing the need to reason about inclusion order at all.

<?php

    // header.php
    require 'db.php';
    require 'auth.php';

    // auth.php
    require 'db.php';  // already loaded by header.php: without _once, this
                        // redeclares every function and class in db.php

    // Fatal error: Cannot redeclare connectToDatabase()

?>

Documentation

See Also

Incoming Data

Incoming data are data submitted to PHP by the user. They may come in different ways: GET, POST, cookies or files; and, by extension, $_REQUEST.

Incoming data should always be checked before usage. Their value may have been modified by the author of the source, and carry some malicious payload.

The encoding of the incoming data is controlled with the default_charset directive.

By extension, incoming data may be used to refer to every source of data that is not PHP itself: files, databases, API, etc. Then, they should be treated the same way, with checks on format and value before usage.

<?php

    if ($_GET['x'] === '1') {
        print "You provided a one digit. Thanks!";
    } else {
        print "No processable data was provided";
    }

?>

Documentation

See Also

Inconsistent

Inconsistent is a trait of written code, where different conventions or styles are used at the same time. Inconsistent source code is more difficult to understand and often leads to misunderstanding.

One way to fight inconsistency is to make the consistent rule explicit, and to use tools that both enforce and teach them to developers.

Code may run correctly without being consistent.

<?php

    $first_name = 'PHP';
    $lastName = 'Elephpant';

?>

Documentation

See Also

Increment

Increment refers to the process of increasing or adding a small amount to a value, or simply one unit.

Increment usually refers to the pre-increment and post-increment operators. Increment applies to numbers, both decimal and integers. It also applies to strings, though the feature has been moved to functions. Increment works on booleans: it always produces 1 first, then, since it was turned into an integer, it goes on with numbers.

<?php

    $a = 1;
    
    echo ++$a; // pre plus plus : displays 1, and $a ends with 2
    
    echo $a++; // post plus plus 
    
    echo $a += 1; // increment 

?>

Documentation

See Also

Indentation

Indentation, or indenting, is a convention governing the layout of blocks of code to convey program structure.

For example, the body of code in a function should be indented one unit to the right, vis-a-vis the function keyword.

Indentation may be done with spaces: 2, 3, 4 or 5 spaces, or horizontal tabulations.

Indentation is part of the syntax of the heredoc strings.

<?php

function headers() : never {
    // expected indentation
    headers('Location: https://www.exakat.io/');

// badly indented block
die();
}

?>

Documentation

See Also

Index For Arrays

A index, also called a key, is the identifier of an specific element in an array. They may automatically generated, by simply omitting them at creation time.

PHP index may be integers or strings only. Other data types generate an error or a type conversion. For example, floats are turned into integer. integer-shaped strings will also be turned into integer.

PHP index start at 0. They may be automatically assigned by appending a new value with the [] operator: then, they use the greatest available index + 1.

<?php

    $array = ['a', 'b', 'c'];

    echo $array[0];

?>

Documentation

See Also

Index For SQL

In SQL, an index is a database object that improves the performance of data retrieval operations on database tables. It is a data structure that provides a quick lookup mechanism for finding specific data within a table.

An index is created on one or more columns of a table and contains a sorted copy of the data in those columns, along with a pointer to the original data. This allows the database engine to locate and retrieve the required data more efficiently, reducing the need for scanning the entire table.

The most common index structure is the B-tree, the balanced tree: a sorted tree where each leaf page holds a range of key values and a pointer to the corresponding data. B-tree indexes support range queries and ordering efficiently.

A clustered index, or clustered primary key, determines the physical storage order of rows on disk. In InnoDB-MySQL, the primary key is always a clustered index, meaning rows are stored in primary key order. This has an important consequence for identifier choice: randomly generated primary keys such as UUIDv4 scatter inserts across the entire index, causing frequent page splits and increased I/O. Time-ordered identifiers such as UUIDv7 or ULID always append to the rightmost leaf page, avoiding this problem.

Indexes provide the following benefits:

  • Improved query performance: by creating an index on frequently queried columns, the database engine can quickly locate the relevant data, resulting in faster query execution times.
  • Efficient data retrieval: indexes allow the database to perform index-based seeks or scans instead of full table scans, which can significantly reduce the amount of disk I/O and improve overall system performance.
  • Sorting and ordering: indexes can be used to sort the data in a specific order, which is helpful when retrieving data in a specific sequence, such as ascending or descending order.
  • Constraint enforcement: indexes can be used to enforce unique constraints and primary key constraints on a table, ensuring data integrity and preventing duplicate or NULL values.

However, indexes also have some considerations:

  • Overhead: indexes consume disk space and require additional processing time for index maintenance during data modifications. So, creating too many indexes or indexes on frequently updated columns can impact performance.
  • Maintenance: indexes need to be maintained as the underlying data changes. This includes updating the index when data is inserted, modified, or deleted, which can impact overall system performance.
  • Choosing the right columns: it’s important to carefully choose the columns to index based on the specific queries and usage patterns of the database. Indexing every column is not always necessary or beneficial.
<?php

    $array = ['a', 'b', 'c'];
    
    echo $array[0];

?>

Documentation

See Also

Index

An index, plural indices, may be several things:

  • An identifier in an array
  • A optimized datastructure for a database, SQL or key-value store
  • A optimized datastructure for fast search operations

An indexed array is an array whose index are integers. This distinguish them from the associative arrays, whose keys are strings.

Documentation

See Also

Indexed Array

An indexed array is an array whose keys are only integers. The keys may be explicit or implicit.

An array with a string index is an associative array.

<?php

$associative = [10 => 'a', 'b'];

echo $associative[10]; // a
echo $associative[0]; // b

?>

Documentation

See Also

Indirect Reference Map

An indirect reference map, or indirect object reference, is a technique that replaces a direct, guessable reference to an internal object, such as a sequential database id, with an unpredictable substitute, such as a UUID or a random per-session token. The application keeps an internal mapping between the substitute value and the real object, and translates one into the other on each request.

Indirect reference maps mitigate id enumeration and reduce the surface for IDOR: an attacker who cannot guess or increment a valid reference cannot casually reach another user’s object by tampering with the value.

An indirect reference map is not, by itself, an authorization check. A random identifier only makes an object harder to guess; it does not verify that the requesting user is entitled to access it. It should be combined with an explicit ownership or permission check on every request, not used as a substitute for one.

<?php

    // Direct reference: sequential id is guessable and exposes enumeration
    // GET /invoice?id=1042
    $invoice = $db->find('invoices', $_GET['id']);

    // Indirect reference: unguessable UUID mapped back to the real id
    // GET /invoice?ref=e194da7f-3d74-48e9-ac49-4c72e1b02eeb
    $id = $referenceMap->resolve($_GET['ref']);
    $invoice = $db->find('invoices', $id);

    // Still required: an explicit ownership check, regardless of the reference used
    if ($invoice->userId !== $currentUser->id) {
        throw new UnauthorizedException();
    }

?>

Documentation

See Also

Inequality

Inequalities are the mathematical comparison of values, with the >, >=, < and <= operators.

Unlike the equality operators, they do not have a strict version, which takes into account the type of the values. Hence, the compared values are always adapted to each other’s type.

<?php

// displays false
var_dump("3" > 3);

// displays true
var_dump(4 >= 0)

?>

Documentation

See Also

INF

Infinite is a PHP constant, called INF. It is also possible to generate such a value, with calls to math functions such as log(0) or 1e308 * 2.

While the infinite is a float, it is possible to test a number with is_infinite().

<?php

$infinite = 1e308 * 2;

var_dump(is_infinite($infinite)); // true 

var_dump(INF === $infinite);      // true 

echo str_repeat('1', 1000) + 0;  // INF

?>

Documentation

See Also

Infinite Loop

An infinite loop never ends, unless an external event make it break out of itself.

Infinite loops are usually un wanted, and should be avoided. They happen when an exit condition is forgotten, omitted or tests a stationary aspect of the loop. That way, the loop keeps repeating.

PHP prevents infinite loop automatically, by enforcing the max_execution_time or memory_limit error.

Infinite loop are also a base structure in event loops: the code waits for an event by repeating itself, with a time moderation to avoid wasting too much energy. As such, it is a feature.

Such loops are related to polling, which is a process where a resource is checked on a regular basis for udpates. They may be replaced by hooks or streams.

<?php

    // infinite loop while
    while(true) { }
    
    // infinite loop while
    do { } while(1);
    
    for(;;) {} 

?>

Documentation

See Also

Infinite

Infinite means that an operation is repeated and will never stop being repeated.

Infinite is characteristics of loops, generators, recursive functions and streams. Infinite structures may be a bug or a feature, depending on the usage. For example, the event loop is usually an infinite loop, until one of the event triggers a jump out of the loop.

Infinite is also a PHP constant: INF.

INF is cast to string as 'INF', to integer as 0, to boolean as true, and to float as 'INF'.

<?php

// infinite loops
while(true) { }

for(;;) {} 

// infinite generator 
function integers() {
    $i = 0;
    while(true) {
        yield $i++;
    }
}

// infinite Fibbonacci sequence
function recursive ($a = 1, $b = 1) {
    $a2 = $b;
    $b2 = $a + $b;
    print $b2.PHP_EOL;
    recursive($a2, $b2);
}

?>

Documentation

See Also

InfiniteIterator

The InfiniteIterator allows one to infinitely iterate over an iterator without having to manually rewind the iterator upon reaching its end.

Infinite iterator works with other iterators. The loop may be broken, as usual, with a break keyword.

<?php

$versions = [1, 2, 3, 4, 5, 7, 8];

$infinite = new InfiniteIterator(new ArrayIterator($versions));
foreach ($infinite as $value) {
    print "$value\n";
}

?>

Documentation

See Also

Inflector

An inflector processes strings to adapt them for various situations, such as singular/plural, or for uppercase/lowercase.

Typical inflector operations include pluralizing and singularizing nouns, browsers to browser, converting between naming conventions such as camelCase, snake_case, and kebab-case, deriving class or table names from words classify(), tableize(), and producing ordinal forms 1st, 2nd. Because English pluralization has many irregular forms such as child/children, mouse/mice, inflectors rely on ordered rule tables and exception lists rather than a single suffix rule.

In the PHP ecosystem, doctrine/inflector is the most widely used standalone implementation and is also embedded inside Doctrine ORM for generating table and column names from entity and property names; Symfony’s symfony/string component ships its own Inflector service; Laravel’s Illuminate\Support\Str::plural()/singular() helpers perform the equivalent inflection; and CakePHP bundles inflection rules in its utility package for generating model and route names.

<?php

    // example using doctrine/inflector
    
    $inflector = InflectorFactory::create()->build();
    echo $inflector->singularize('browsers'); // browser

?>

Documentation

See Also

Inheritance

Inheritance is a mechanism where a class is build from another class, and form a hierarchy of classes that share a set of attributes and methods.

<?php

class elephpant {
    public function trumpet() {
        echo "I am trumpet!\n";
    }
}

class calf extends elephpant {
    public function stampede() {
        echo "I am stampede!\n";
    }
}

$calf = new Calf();
$calf->stampede(); // calling the stampede method, defined only with calf
$calf->trumpet(); // calling the trumpet method, defined in elephpant, and inherited in calf

?>

Documentation

See Also

Inherited Variable

An inherited variable is a variable that was passed to a closure via the use clause in the closure definition.

The variable is said ‘inherited’, as it is extracted from the context at definition time, and not passed as parameter, at call time.

Contrary to parameters, inherited variable cannot be typed.

<?php

$inherited = 'yes';

$closure = function() use ($inherited) {
    return $inherited;
};

trumpet($closure);

function trumpet($closure) {
    $inherited = 'no'; // This is local to the trumpet function

    echo $closure(); // display yes
}

?>

Documentation

See Also

INI

The INI format is a simple, human-readable file format used for configuration settings. It consists of key-value pairs grouped into sections.

It is natively supported by PHP, and used internally for the php.ini file.

It is related to the TOML format.

<?php

    parse_ini_file('/path/to/php.ini');
    
    parse_ini_string(<<<INI
    ; This is a comment
    # Another comment
    
    [database]
    host = localhost
    username = root
    password = secret
    port = 3306
    INI);

?>

Documentation

See Also

ini_set()

ini_set() is a PHP native function which can change PHP directive, during execution. This is useful to make a specific limit different, depending on the part of the application which runs. It might also be a security problem, when directives are used to protect the system, and are lifted with this function. However, some directives cannot be changed by this function, such as disable_classes for example.

The impact of ini_set() only applies to the current request. It will be reset to its default value with the next request.

The complement to this function is ini_get(), which collect the value of a directive without changing it; and ini_restore(), which reset the directives to their initial value.

<?php

    print ini_get('memory_limit'); // for example 128M

    ini_set('memory_limit', '1024M'); // now, 1 Gb

?>

Documentation

See Also

Initialisation

Initialisation is the process to unconditionally give a value to a variable, or any container, before its usage.

Initialisation has a dedicated syntax for properties, parameters and static variables. There is no dedicated syntax for variable initialisation: they are created when needed, with a default value of NULL. They also emits a warning in that case.

Initialisation ensures that a variable is hold a sane value before any usage. This makes it important for security purposes too.

<?php

function trumpet($i = 0) {
    static $var = 3;

    // implicit initialisation with null, which is later cast to 0.
    $trunk += 2;
}
?>

Documentation

See Also

Injection

Injection is the usage of a resource, such as data, object or services, that is provided to the method, by the caller.

There are good injections, such as the dependency injection.

There are bad injections: all the security ones. SQL injection, PHP code injection, LDAP injection, CRLF injection, CSV injection, XML injection, etc. Those attempt to change reroute the execution of the method to gain access to unprotected resources.

Documentation

See Also

Inline Assembly

Inline assembly is a language feature, found in C, C++, and Rust, that lets raw processor assembly instructions be embedded directly inside otherwise ordinary source code, such as GCC’s asm("...") blocks or Rust’s asm! macro. It gives direct control over specific CPU instructions, registers, and hardware features, such as SIMD intrinsics, atomic operations not otherwise exposed by the language, or a device driver’s memory-mapped I/O, that the compiler’s own code generation does not expose any other way.

Because it bypasses the compiler’s usual code generation and type checking for the enclosed instructions, inline assembly is inherently unsafe and non-portable across processor architectures, and is reserved for narrow, performance- or hardware-critical sections.

PHP has no inline assembly, and none is possible: source code is compiled to Zend opcodes and interpreted by the Zend Engine, it is never compiled down to native machine code that a programmer could interleave instructions with. Reaching hardware-level or CPU-instruction-level functionality from PHP requires writing a C extension, or a compiled library invoked through FFI.

Documentation

See Also

Inlining

Inlining is the process to bring a dependency inside the current code, so as to remove that dependency.

For example, replacing a constant by its value, as a literal, means that the code works without depending on the external definition.

On the other hand, such external structure may also have its own life cycle, which is not reflected anymore. It also may hurt readability.

<?php

    const A = 1;
    
    echo A; // dependent code
    
    echo 1; // 

?>

Documentation

See Also

Insecure Deserialization

Insecure deserialization, also called PHP object injection, is a vulnerability that occurs when untrusted data is deserialized without sufficient validation, allowing an attacker to manipulate the serialized object to execute arbitrary code.

The most common vector is the native unserialize() function. When user-controlled data is passed to unserialize(), an attacker can craft a malicious serialized payload that instantiates arbitrary classes available in the application’s scope. By targeting classes that implement magic methods such as __wakeup(), __destruct(), or __toString(), the attacker can chain method calls, known as a Property Oriented Programming chain, to achieve remote code execution.

OWASP lists insecure deserialization as one of the Top 10 web application security risks.

Mitigations include: never deserializing untrusted data with native unserialize(); using safer formats such as JSON; using the allowed_classes option to whitelist permitted classes; and using HMAC signatures to authenticate serialized payloads.

<?php

    // VULNERABLE: passing user input directly to unserialize()
    $data = $_GET['data'];
    $obj  = unserialize($data); // Dangerous!
    
    // SAFER: use JSON for untrusted data
    $obj = json_decode($_GET['data']);
    
    // SAFER: restrict allowed classes when unserialize is necessary
    $obj = unserialize($data, ['allowed_classes' => [MyValueObject::class]]);

?>

Documentation

See Also

Installation

Installation covers two distinct things that share a name but happen at different layers.

PHP installation is the process of getting the PHP runtime itself onto a machine so that any PHP script can be executed at all. Depending on the platform and the intended use, this can mean installing a prebuilt package through an operating system’s package manager, such as apt on Debian and Ubuntu, dnf on Fedora, or Homebrew on macOS; downloading official prebuilt binaries for Windows; running an all-in-one local development stack such as XAMPP, MAMP, or WAMP that bundles PHP with a web server and a database; pulling an official php Docker image for containerized environments; or compiling PHP from source with ./configure, make, and make install for full control over which extensions and build flags are enabled. It is typically followed by configuring php.ini to enable the required extensions and set runtime directives, and verified by running php -v from the command line or checking the output of phpinfo() through a web server. Multiple PHP versions can coexist on the same machine using version managers or separate installation prefixes, which is common when maintaining several projects with different version requirements. This step is done once per machine, or once per PHP version on that machine.

PHP application installation, by contrast, assumes the runtime already exists and instead sets up one particular application or library written with PHP so that it becomes usable. For a library, this usually means composer install, which reads composer.json and downloads the declared dependencies into vendor/. For a full application such as WordPress, Drupal, or a bespoke project, it typically also involves creating a configuration file, initializing a database schema, and setting file and directory permissions, often walked through by a first-run install wizard in the browser or a documented sequence of console commands. Application installation is repeated for every project and every environment, and is a separate concern from deploy, which is about publishing an already-installed application to a live server.

Documentation

instance

An instance is an object of a class. The class provides the definitions of the behavior of that object, while the object holds the specific data, that makes it unique and distinguishable.

The creation of an instance, called instantiation, or to instantiate, is done with the new keyword.

<?php

    class Elephpant {
        private int $property;

        function __construct(int $arg) {
            $this->propety = $arg;
        }
    }

    $object = new Elephpant(2);

?>

Documentation

See Also

instanceof

instanceof is used to determine whether a PHP variable is an instantiated object of a certain class. It is related to the function is_a().

instanceof has a higher precedence than ! operator, so it is applied before the latter. In case of confusion, use parenthesis.

instanceof does not check that the checked class exists: it just checks that the provided object match the class name. If a typo happens in the class name or the class does not exists, the operator fails every time.

<?php

    if ($user instanceof Administrator) {
        $user->admin();
    }
    
    // If The user is not of class User...
    if ( !$user instanceof User ) {
    //if ( !($user instanceof User) ) {
        $user->admin();
    }
    
    var_dump($user instanceof UndefinedClass); // false

?>

Documentation

See Also

Insteadof

The insteadof operator is used in the context of trait composition and resolving conflicts between methods or properties of multiple traits that are being used in a class.

When a class uses multiple traits that have methods or properties with the same name, naming conflicts can arise. The insteadof operator helps to resolve these conflicts by specifying which trait’s implementation should be used in the class. It is often paired with as to give the excluded implementation a method alias, so it can still be reached under another name.

<?php

    // Example from the PHP documentation
    trait A {
        public function smallTalk() {
            echo 'a';
        }
        public function bigTalk() {
            echo 'A';
        }
    }
    
    trait B {
        public function smallTalk() {
            echo 'b';
        }
        public function bigTalk() {
            echo 'B';
        }
    }
    
    class Talker {
        use A, B {
            B::smallTalk insteadof A;
            A::bigTalk insteadof B;
        }
    }

?>

Documentation

See Also

Instruction

The term instruction most commonly refers to a PHP language statement, such as an assignment, a function call, or a control structure.

In programming, an instruction is a single operation that tells the processor or runtime to perform a specific task. At the CPU level, instructions are binary commands executed directly by the hardware. In higher-level languages like PHP, a statement or expression corresponds to one or more machine instructions after compilation or interpretation.

<?php

// PHP instructions (statements)
$trunk = 42;           // assignment
echo $trunk;           // output
if ($trunk > 0) { }   // control structure
trumpet($trunk);           // function call

?>

Documentation

See Also

intdiv()

intdiv() is a PHP native function, that computes the integer division between two integer. The integer division of a by b express the number a as a function of b, such as a = k * b + c.

intdiv() returns the k value, which is the quotient. It is an integer. The remainder, c is accessible with the modulo operator %. There is no operator equivalent to intdiv().

The integer division is a special case of the division, which works on decimal numbers.

<?php

$a = 15;

$b = 6;

$k = intdiv($a, $b); // 2 
$c = $a % $b; // 3

echo $k * $b + $c;

?>

Documentation

See Also

integer

An integer, or int is a number of the set ℤ = {..., -2, -1, 0, 1, 2, ...}. It is limited by PHP_INT_MIN, the lower bound, and PHP_INT_MAX, the upper bound.

Integers have several syntaxes: they may be written in binary, octal, decimal, hexadecimal and with _ as a separator.

<?php

    $a = 1234;       // decimal number
    $a = 0123;       // octal number (equivalent to 83 decimal)
    $a = 0o123;      // octal number (as of PHP 8.1.0)
    $a = 0x1A;       // hexadecimal number (equivalent to 26 decimal)
    $a = 0b11111111; // binary number (equivalent to 255 decimal)
    $a = 1_234_567;  // decimal number (as of PHP 7.4.0)

?>

Documentation

See Also

Integration Test

Integration tests are tests that verify how multiple components or packages work together, as opposed to unit tests, where test are dedicated to one component.

The most important with integration testing is to test realistic scenarios: actual HTTP requests, real database writes, real service interactions, so as to cover the bugs that only appear when everything is wired together.

Integration testing relies on mock objects, to simulate external, autonomous or hard to generate situations.

Documentation

See Also

Interface

Object interfaces allow to create code which specifies which methods a class must implement, without having to define how these methods are implemented.

Interfaces may have methods signatures, without a body, constants. Since version 8.4, they may also have properties, as long as the property is public, and the hooks are abstract, or without body.

<?php

    // Declare the interface 'Template'
    interface Template
    {
        public const A = 1;

        public string $p {
            get;
        }

        public function setVariable($name, $var);
        public function getHtml($template);
    }
    
    // Implement the interface
    class WorkingTemplate implements Template
    {
        private $vars = [];
      
        public string $p {
            get => 2;
        }

        public function setVariable($name, $var)
        {
            $this->vars[$name] = $var;
        }
      
        public function getHtml($template)
        {
            foreach($this->vars as $name => $value) {
                $template = str_replace('{' . $name . '}', $value, $template);
            }
     
            return $template;
        }
    }

?>

Documentation

See Also

Internals

In PHP, internals refers to everything under the hood of the language itself, not the code written with PHP.

Internals are the features written in C, C++ language and compiled with the engine; the Zend engine itself. It also refers to the contributors working on the core of PHP, as they are member of the internal mailing list.

Documentation

See Also

Internationalization

Internationalization, often discussed alongside localization or localisation, is the process of making the human interface of a program available in a local language.

PHP includes some internationalization capabilities, via the locale, for dates or money format, or with the ext/intl extension.

Most of the interface translations for an application are done with specific components, such as Symfony/translation. Translation of interface messages is part of this concept.

Internationalization is also called i18n, aka i, 18 letters and n. This is shorter to write. This word may be written with a z or an s, depending on the flavor of English being used.

<?php
/* Configure le script en hollandais */
setlocale(LC_ALL, 'nl_NL');

/* Affiche : vrijdag 22 december 1978 */
echo strftime('%A %e %B %Y', mktime(0, 0, 0, 12, 22, 1978));

?>

Documentation

See Also

Internet

The internet is a global network of interconnected computers and devices that communicate using shared protocols.

It’s billions of devices, phones, servers, laptops, routers, etc. all linked together so they can send data to each other, anywhere in the world.

Documentation

See Also

Interoperability

Interoperability, sometimes misspelled interoperatibility, is the ability of distinct software components or systems to exchange information and work together effectively, without special adaptation effort.

In the PHP ecosystem, interoperability is promoted by PHP-FIG, the PHP Framework Interop Group, through PSR standards, which define common interfaces for loggers, the PSR-3, HTTP messages, the PSR-7, dependency injection containers, the PSR-11, caches, the PSR-6 and PSR-16, event dispatchers, the PSR-14, and HTTP handlers, the PSR-15.

Designing against interfaces rather than concrete implementations enables components from different libraries and frameworks to be composed freely. This is the foundation of the modern PHP package ecosystem.

Interoperability also extends beyond the PHP ecosystem itself: PHP natively handles many exchange formats, such as JSON, XML, YAML, CSV, and Protocol Buffers, which lets it talk to services and applications written in any other language. A PHP application can consume a JSON API served by a Node.js backend, exchange Protobuf messages with a Go microservice over gRPC, or parse a CSV export produced by a legacy system, without either side knowing what language the other is written in. The FFI extension pushes this further, allowing PHP to call C libraries directly, in process.

<?php

    use Psr\Log\LoggerInterface;
    
    // Any PSR-3 compliant logger may be injected
    function process(LoggerInterface $logger): void {
        $logger->info('Processing started');
    }

?>

Documentation

See Also

Interpolation

Interpolation is the PHP feature that automatically replaces variables and public properties by their value in double-quoted strings and Heredoc syntax.

<?php

    $string = "world";
    
    echo "Hello $string"; 
    // displays Hello world

?>

Documentation

See Also

Interpreted

An interpreted language is a programming language in which the source code is executed line by line by another program called an interpreter, rather than being converted directly into machine code by a compiler.

An interpreted language has no compile phase, and runs immediately. It gives it a shorter cycle to update the code and test it.

On the other hand, compiled languages take more time to review the code at compile time, and also add an optimisation phase: in the end, the result is often smaller and faster.

PHP is known to be an interpreted language. This is not strictly the case, as PHP make keep the code compiled in bytecode, or use JIT to compile the frequent code faster.

There are also tools to compile PHP directly to binary code for compiled execution.

Documentation

See Also

Intersection Type

Intersection types, also called intersectional types, is a specification syntax where several types act together as a single type. The individual types are separated with the & operator.

The value typed with an intersection type must satisfy all the types at the same time.

Intersection types only accept class and interface types: scalars, int, string, bool, etc., null, false, true, and void are not allowed, as a single value cannot simultaneously be of two scalar types. Redundant types are also rejected: A&A is not valid.

Intersection types work well with polymorphism: an object that implements multiple interfaces satisfies an intersection type naturally.

PHP 8.2 introduced Disjunctive Normal Form, aka DNF, types, which combine intersection and union types, such as (A&B)|null.

<?php

    class Elephpant {
        // Property is of type Tusk, Ivory and Trunk at the same time.
        // Two of them have to be interfaces.
        private Tusk & Ivory & Trunk $property;
    }

?>

Documentation

See Also

Internationalization Functions

The internationalization extension performs operations with locales. For example, it formats dates according to country and language configurations. The operations include, and are not limited to, formatting, transliteration, encoding conversion, calendar operations, » UCA-conformant collation, locating text boundaries and working with locale identifiers, timezones and graphemes.

This extension is closely linked to the ICU library.

<?php
$us = new NumberFormatter('en_US', NumberFormatter::DECIMAL);
echo $us->format(1234567).PHP_EOL;
//1,234,567

$zh = new NumberFormatter('zh_ZH', NumberFormatter::DECIMAL);
echo $zh->format(1234567).PHP_EOL;
//1,234,567

$fr = new NumberFormatter('fr_FR', NumberFormatter::DECIMAL);
echo $fr->format(1234567).PHP_EOL;
//1 234 567

?>

Documentation

See Also

Introspection

Introspection is the ability to examine the properties and behavior of objects, classes, and functions at runtime. It allows code to discover and inspect its own structure.

PHP provides many native introspection functions: get_class(), get_object_vars(), get_class_vars(), get_class_methods(), method_exists(), property_exists(), function_exists(), is_a(), instanceof, and others.

For deeper introspection, the Reflection API provides programmatic access to class hierarchies, method signatures, parameter types, and attributes.

<?php

    class Dog {
        public string $name = 'Rex';
        public function bark(): void {}
    }
    
    $dog = new Dog();
    
    var_dump(get_class($dog));             // string(3) "Dog" 
    var_dump(get_object_vars($dog));       // Array ( [name] => Rex )
    var_dump(get_class_methods($dog));     // Array ( [0] => bark )
    var_dump(method_exists($dog, 'bark')); // bool(true)

?>

Documentation

See Also

InvalidArgumentException

InvalidArgumentException is an Exception thrown when an argument is not of the expected type. It is a LogicException, and it may be thrown when using SPL classes.

<?php

    function trumpet(string $a) {}

    // OK
    trumpet("abc");

    // KO : invalid argument
    trumpet(12);

?>

Documentation

See Also

Type Invariant

A type invariant is a data container whose type can’t change between a parent class and a child class. This is the case of properties.

The child type must be a subtype of the parent type and the parent type must be a subtype of the child type. This implies that the types are equal.

Invariance is the third type of variance, with contravariance and covariance.

<?php

class p {
    protected string $p;
}

class q extends p {
    // same a above
    protected string $p;
}

?>

Documentation

See Also

Code Inventory

A code inventory is the collection of all elements of the same type, for categorized review.

For example, variable names, error messages, namespaces, regexes are all interesting inventories.

Inventories work best when the code practice is scattered: exceptions and regexes are usually created where and when needed, and are rarely considered as a common asset. That leads to repetition and deformations.

Documentation

See Also

Invoke

It is possible to invoke an object, that means calling a function built with the object as the function name.

Invocation is based on the __invoke magic method.

Being invokable, or invocable, means that an object may be used as a function name.

<?php

class elephpant {
    function __invoke($a) {
        echo 'I am '.$a;
    }
}

$elephpant = new elephpant;
$elephpant('elephpant'); // I am elephpant

?>

Documentation

See Also

Internet of Things (IoT)

IoT, the Internet of Things, also called connected devices, refers to the network of physical devices, such as sensors, actuators, vehicles, appliances, industrial machines, etc., embedded with electronics and connectivity that enable them to collect and exchange data.

IoT systems generate continuous, high-volume event streams from many devices simultaneously. This data must be ingested, stored, processed, and acted upon in near real time. The backend architecture typically involves an MQTT or HTTP ingestion layer, a message queue or event stream, a time-series database, and a processing layer for anomaly detection, aggregation, and alerting.

PHP is not commonly used for IoT device firmware, which is typically C, Rust, or MicroPython, but it plays a role in IoT backend services: REST or MQTT APIs that receive device data, dashboards and reporting tools, and administrative interfaces for device management. Laravel, Symfony, and Slim are used for these backend roles.

IoT is an initialism, not a strict numeronym, but is often listed alongside numeronyms like i18n and k8s in software engineering contexts.

<?php

// PHP MQTT consumer: receive sensor readings from IoT devices
// Requires a MQTT client library (e.g., php-mqtt/client)

use PhpMqtt\Client\MqttClient;

$mqtt = new MqttClient('mqtt-broker.internal', 1883, 'php-backend');
$mqtt->connect();

$mqtt->subscribe('sensors/temperature/#', function (string $topic, string $message) {
    $data     = json_decode($message, true);
    $deviceId = basename($topic);

    // Store in time-series DB (InfluxDB example)
    $this->influx->writePoint('temperature', [
        'device' => $deviceId,
        'value'  => $data['value'],
    ]);

    if ($data['value'] > 80.0) {
        $this->alerting->trigger('High temperature on ' . $deviceId . ': ' . $data['value'] . '°C');
    }
}, 0);

$mqtt->loop();

?>

Documentation

See Also

Internet Protocol (IP)

IP often refers to Internet Protocol, which is a set of rules governing the format of data sent over the internet or other networks. IP addresses are unique numerical labels assigned to each device connected to a network, allowing them to communicate with each other.

PHP usually handles IP addresses as strings. It also has dedicated functions to manage them, in particular converting IPs to integer, with ip2long(), or solving them with DNS, with gethostbyaddr().

PHP also provides IP in its configuration, such as $_SERVER['SERVER_ADDR'], which is the IP of the current webserver.

IP also stands for intellectual property.

<?php

    echo $_SERVER['SERVER_ADDR']; 

?>

Documentation

See Also

is_a()

is_a() is a PHP native function, that checks if an object is of a specific class.

Usually, is_a() is better replaced by instanceof, which is a PHP operator. The function might be needed to create a closure, though.

<?php

    $object = (object) ['a' => 1];

    var_dump(is_a($object, stdClass::class));

?>

Documentation

See Also

is_array()

is_array() is a PHP native function that checks whether a variable is of type array. It returns true if the value is an array, false otherwise.

This function is essential for type checking and validation before performing array operations. It is commonly used in:

  • Input validation to ensure expected data structures
  • Conditional logic before array manipulation functions
  • Type-safe function implementations
  • Preventing errors when working with mixed-type data

is_array() distinguishes arrays from other PHP data types, including objects, even if those objects implement ArrayAccess or IteratorAggregate interfaces. For checking whether a value is traversable or can be used in a foreach loop, consider is_iterable() instead.

<?php

    $data = [1, 2, 3];
    echo is_array($data) ? 'Array' : 'Not an array'; // Array

    $string = 'hello';
    echo is_array($string) ? 'Array' : 'Not an array'; // Not an array

    // Validation before array operations
    $input = json_decode('[1, 2, 3]', true);
    if (is_array($input)) {
        $result = array_map(fn($n) => $n * 2, $input);
        print_r($result);
    }

?>

Documentation

See Also

is_bool()

is_bool() is a PHP native function that checks whether a variable is of type bool. It returns true only for the literal values true and false.

is_bool() distinguishes true booleans from values that are merely truthy or falsy, such as 0, '', null, or 1, none of which are booleans themselves even though they may evaluate as such in a boolean context. This distinction matters when a function or API explicitly needs to know that a boolean, rather than any falsy or truthy value, was received.

It is commonly used in input validation, for instance when reading configuration values, decoded JSON, or user input, where the caller must confirm that a strict boolean was provided rather than a string like "true" or an integer like 1.

<?php

    var_dump(is_bool(true));   // true
    var_dump(is_bool(false));  // true
    var_dump(is_bool(1));      // false
    var_dump(is_bool('true')); // false

    $config = json_decode('{"debug": true}', true);
    if (is_bool($config['debug'])) {
        echo 'Debug mode: ' . ($config['debug'] ? 'on' : 'off');
    }

?>

Documentation

See Also

is_float()

is_float() is a PHP native function that checks whether a variable is of type float. It returns true if the value is a float, false otherwise. is_double() and is_real() are aliases of is_float().

is_float() returns false for integers, even a whole-number value like 4, and for numeric strings such as "4.0": only the actual internal float type qualifies. Because floats use binary representation, comparing them for exact equality is unreliable, so is_float() is generally used to branch on type before further processing, rather than as a stand-in for a numeric range check like is_numeric().

It is commonly used when validating decoded JSON or configuration values, where distinguishing a float from an integer or a numeric string affects how the value should be formatted or compared.

<?php

    var_dump(is_float(4.0));   // true
    var_dump(is_float(4));     // false
    var_dump(is_float('4.0')); // false

    $price = json_decode('19.99');
    if (is_float($price)) {
        echo number_format($price, 2);
    }

?>

Documentation

See Also

is_int()

is_int() is a PHP native function that checks whether a variable is of type int. It returns true if the value is an integer, false otherwise. is_integer() and is_long() are aliases of is_int().

is_int() returns false for numeric strings, such as "42", and for floats, even when they hold a whole number like 4.0: only the actual internal int type qualifies. This makes is_int() stricter than a numeric check like is_numeric(), which also accepts numeric strings and floats.

It is commonly used to validate array keys, loop counters, or values decoded from external sources, such as JSON, where the distinction between an integer and a numeric string matters, for instance before using the value as an array offset or passing it to a strictly-typed function parameter.

<?php

    var_dump(is_int(42));     // true
    var_dump(is_int(4.0));    // false
    var_dump(is_int('42'));   // false

    $id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
    if (is_int($id)) {
        $user = find_user_by_id($id);
    }

?>

Documentation

See Also

is_iterable()

is_iterable() is a PHP native function, introduced in version 7.1, that checks whether a variable can be iterated over with foreach. It returns true if the value is either an array or an object implementing the Traversable interface, such as a Generator or an Iterator.

is_iterable() is the runtime counterpart of the iterable pseudo-type, which may be used in type declarations for parameters, return types, and properties. It is looser than is_array(), since it also accepts objects, but it does not accept plain objects that merely implement ArrayAccess without also being Traversable.

It is typically used to validate arguments of functions designed to accept both arrays and generators or iterators interchangeably, before looping over them with foreach.

<?php

    function process(iterable $items): void {
        foreach ($items as $item) {
            echo $item . PHP_EOL;
        }
    }

    var_dump(is_iterable([1, 2, 3]));           // true
    var_dump(is_iterable((function () { yield 1; })())); // true
    var_dump(is_iterable('hello'));             // false
    var_dump(is_iterable(new ArrayObject([1]))); // true

?>

Documentation

See Also

is_numeric()

is_numeric() is a PHP native function that checks whether a variable is a number or a numeric string. It returns true for integers, floats, and strings that represent a valid number, such as "42", "3.14", " 1e10", or "0x1A" in older PHP versions; it returns false for non-numeric strings, null, arrays, and booleans.

is_numeric() is deliberately more permissive than is_int() or is_float(): it accepts leading whitespace, scientific notation, and numeric strings, which makes it well suited to validating raw input from $_GET, $_POST, or a CSV file, where numbers always arrive as strings. It does not, however, confirm the actual internal type, so code that also needs to know whether a value is already an int versus a numeric string should combine it with is_int() or a cast.

Since PHP 8.0, leading numeric strings that also contain trailing non-numeric characters, such as "123abc", are treated differently from earlier versions: is_numeric() still returns false for them, only fully numeric strings qualify.

<?php

    var_dump(is_numeric(42));      // true
    var_dump(is_numeric('42'));    // true
    var_dump(is_numeric('3.14'));  // true
    var_dump(is_numeric('12abc')); // false

    $id = $_GET['id'] ?? '';
    if (is_numeric($id)) {
        $user = find_user_by_id((int) $id);
    }

?>

Documentation

See Also

is_object()

is_object() is a PHP native function that checks if the content of a variable is an object or not, without consideration for the actual class. It is the equivalent of object type, which cannot be used with instanceof; or the (object) cast, that turns a value into an object of class stdClass.

is_object() is rarely used, as instanceof with the expected class or interface is more precise.

<?php

var_dump(is_object((object)[])); // true

$trunk = new stdClass();
var_dump(is_object($trunk)); // true

$trunk = 1;
var_dump(is_object($trunk)); // false

?>

Documentation

See Also

is_string()

is_string() is a PHP native function that checks whether a variable is of type string. It returns true if the value is a string, false otherwise.

is_string() does not perform any conversion: it only reports the actual internal type. A numeric string like "42" is a string, and is_string() returns true for it, even though is_numeric() also returns true for the same value. Objects implementing __toString() are not strings, even though they may be used anywhere a string is expected through implicit conversion.

It is frequently used in input validation, and in functions accepting mixed arguments that need to branch on whether a string, as opposed to an array, an object, or a number, was actually passed.

<?php

    var_dump(is_string('hello'));  // true
    var_dump(is_string('42'));     // true
    var_dump(is_string(42));       // false

    function greet(mixed $name): string {
        if (!is_string($name)) {
            throw new InvalidArgumentException('Name must be a string');
        }
        return 'Hello, ' . $name;
    }

?>

Documentation

See Also

Interface Segregation Principle (ISP)

The interface segregation principle, or ISP, states that no code should be forced to depend on methods it does not use. It is the I in the SOLID principles of object-oriented design, and it recommends splitting large, general-purpose interfaces into smaller, more specific ones, so that implementing classes only need to know about the methods that are actually relevant to them. Violating ISP typically shows up as fat interfaces, where implementers are forced to provide empty or throwing stubs for methods they don’t need, which increases coupling and makes the codebase harder to maintain and extend.

Documentation

See Also

Isset

isset() is a function that determines if a variable is declared and is different than null.

isset() is also related to the magic method __isset(), which is used to determine if a property in an object exists or not.

isset() has an error suppression feature, that masks various errors, such as undefined offset or undefined variables. Some other errors, like an invalid type as offset, are still reported.

isset() may be compared to array_key_exists() to check if an index exists in an array. As a micro-optimisation, it is faster than the function.

<?php

    $var = 'something';
    
    if (isset($var)) {
        echo 'The variable $var contains '.$var;
    } else {
        echo 'No such variable as $var';
    }

?>

Documentation

See Also

Iterable

Iterable is a pseudo-type, which accepts any array or object implementing the Traversable interface. This is equivalent to the type array|Traversable, as one keyword.

<?php

    function trumpet(iterable $iterable) {
        foreach ($iterable as $value) {
            // ...
        } 
    }

?>

Documentation

See Also

Iterator

An iterator is an object which can be traversed with a foreach() loop.

Iterator is an interface, which shall be implemented by objects. There are also a list of default iterators in the SPL extension.

An iterator may be turned into an array, with the iterator_to_array() function. Arrays may be used as iterator natively, or used as an object with the ArrayObject class.

<?php

    class myIterator implements Iterator { /**/ }
    
    $it = new myIterator;
    
    foreach($it as $key => $value) {
        var_dump($key, $value);
        echo "\n";
    }

?>

Documentation

See Also

iterator_to_array()

iterator_to_array() converts Iterators and Generators into an array. The iterator is entirely run, and each yielded value is stored in the resulting array.

While iterators play a similar role to arrays, they are not typed the same way. Sometimes, it might be necessary to pass an array rather than the iterator to a method.

iterator_to_array() may use a lot of memory: iterators often save memory by emitting values one by one, instead of creating them before running some more code. Here, iterator_to_array() runs the iterator and creates the values before the next step.

iterator_to_array() attempts to run infinite generators, until PHP runs out of memory.

<?php

    function trumpet(): Generator {
        yield 1;
        yield 2;
        yield 3;
    }

    print_r(iterator_to_array(trumpet()));

?>

Documentation

See Also

IteratorAggregate

IteratorAggregate is an interface to create a custom iterator.

It requires a single method, that returns an iterator that will be used with PHP native functions.

It also suggest that several iterators may be merged in one, by creating a class that merges them.

<?php

    declare(strict_types=1);
    
    class MergedIteratorAggregate implements IteratorAggregate
    {
        /** @var iterable[] */
        private array $iterables = [];
    
        public function addIterable(iterable $iterable): void
        {
            $this->iterables[] = $iterable;
        }
    
        public function getIterator(): Traversable
        {
            foreach ($this->iterables as $iterable) {
                // yield from works with arrays AND Traversable objects
                yield from $iterable;
            }
        }
    }
    
    $aggregate = new MergedIteratorAggregate();

    function diceRoll() {
        yield rand(0, 10);

    }

    // Using iterator with generators
    $aggregate->addIterable(diceRoll());
    $aggregate->addIterable(diceRoll());
    foreach($aggregate as $value) {
        print $value.PHP_EOL;
    }

?>

Documentation

See Also

Javascript

JavaScript is a programming language primarily used to make websites interactive. It runs mainly in the browser, on the client side, allowing things like form validation before submitting, dynamic page updates without reloading, animations and UI interactions, fetching data asynchronously.

PHP interacts with JavaScript to serve it, or produce specific datasets.

It can also run on the server side using environments like Node.js.

Documentation

See Also

Just In Time (JIT)

Just-In-Time compilation is a technique used in computer science and programming languages to improve the runtime performance of code execution.

In traditional interpretation of programming languages like PHP, code is executed line by line by an interpreter. This can lead to some performance bottlenecks, especially for code that is executed frequently or for applications that require high throughput.

With Just-In-Time compilation, the code is not interpreted line by line. Instead, it’s analyzed and compiled into machine code just before it’s executed. This compiled code is then stored in memory and can be executed much more efficiently than interpreted code. This approach can significantly improve the performance of a programming language.

Documentation

See Also

Jitter

Jitter is a small random variation added to a computed delay, most often the delay between retry attempts, so that independent clients do not all wake up and act at exactly the same instant.

Without jitter, every client that failed at the same moment, for example right after a dependency restarted or a deploy finished, recomputes the same exponential backoff delay and retries in lockstep, producing repeated bursts of load known as a thundering herd or retry storm; each burst can itself trigger new failures, which are then retried in a new burst, and so on. Adding randomness spreads those retries out over time and decorrelates the clients from one another.

Several jitter strategies exist, trading off predictability for effectiveness at spreading load: full jitter picks the delay as a random value between 0 and the full computed backoff, for example rand(0, base * 2 ** attempt), which is simple and effective at breaking synchronization, at the cost of some retries firing sooner than the backoff alone would suggest; equal jitter keeps half of the computed backoff fixed and randomizes only the other half, guaranteeing a minimum delay while still adding randomness; and decorrelated jitter randomizes each delay based on the previous delay rather than solely on the attempt count, further reducing correlation across many retrying clients.

Jitter is typically added by hand around usleep() or sleep() calls, using random_int() for the random component, or provided by retry libraries and by Guzzle/Laravel retry middleware that accept a delay callback.

<?php

    // Full jitter: sleep = rand(0, base * 2^attempt)
    function jitteredDelayMs(int $attempt, int $baseMs = 250): int {
        return random_int(0, $baseMs * (2 ** $attempt));
    }

    usleep(jitteredDelayMs($attempt) * 1000);

?>

Documentation

See Also

Jobqueue

A job queue is a concept that refers to a system or data structure used to manage and schedule the execution of various tasks or jobs in a sequential or parallel manner.

Job queues are commonly used in scenarios where there is a need to process multiple tasks asynchronously, ensuring that tasks are executed efficiently and in an organized manner.

A job queue may organize the tasks in different way: by priority, by type, by sequence, by estimated load, by available worker, etc.

Documentation

See Also

JPEG

JPEG, the Joint Photographic Experts Group, is a lossy image compression format widely used for photographs and complex images. It is identified by the file extensions .jpg and .jpeg.

JPEG compression reduces file size by discarding some image data, making it suitable for photographs but less ideal for images with sharp edges or text.

PHP’s GD extension handles JPEG images with functions such as imagecreatefromjpeg(), imagejpeg(), and imagecolorat(). imagejpeg() accepts an optional quality parameter from 0 to 100.

<?php

$image = imagecreatefromjpeg('input.jpg');

// Resize or manipulate...

imagejpeg($image, 'output.jpg', 85); // Save at quality 85
imagedestroy($image);

?>

Documentation

See Also

JSON-LD

JSON-LD, short for JSON for Linking Data, is a W3C standard serialization format for RDF: it lets ordinary JSON, the format most PHP applications already produce and consume, carry linked-data meaning by adding a small number of reserved keywords, most notably @context, which maps the document’s plain property names to globally unique URIs, and @id and @type, which identify a resource and its class. Because a JSON-LD document is still syntactically valid JSON, it can be parsed with json_decode() like any other payload, while tools built for linked data can additionally interpret it as a graph of RDF triples, expand or compact it against different contexts, or convert it to other RDF serializations such as Turtle or N-Quads. The lanthaler/JsonLD library provides a fully conforming JSON-LD processor implementing the official expansion, compaction, flattening, and framing algorithms, plus an object-oriented API for building and querying documents programmatically, and it is commonly paired with libraries like EasyRdf when a full RDF toolchain is needed. Its most common real-world use in web applications is embedding structured data inside a <script type="application/ld+json"> tag so that search engines and other crawlers can understand a page’s content, such as a product, an article, or an event, without needing to parse the visible HTML.

<?php

    $document = (object) [
        '@context' => 'https://schema.org',
        '@type'    => 'Article',
        'headline' => 'Understanding JSON-LD',
        'author'   => (object) ['@type' => 'Person', 'name' => 'Ada Lovelace'],
    ];
    
    echo json_encode($document, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);

?>

Documentation

See Also

JavaScript Object Notation (JSON)

JSON, or JavaScript Object Notation, is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language Standard ECMA-262 3rd Edition - December 1999.

<?php

    $array = ['a' => 1, 'b' => "c", 'c' => [3, 4], 'd' => new stdclass()];
    
    echo json_encode($arr);
    // displays {\a\:1,\b\:\c\,\c\:[3,4],\d\:{}}

?>

Documentation

See Also

json_decode()

json_decode() decodes a JSON string into a data structure.

In case an error arise during parsing, a null value is returned, as the default value. This error may be confused with the decoding of the 'null' string, which is a valid JSON value. It may also raise a ValueError, when the function is configured by JSON_THROW_ON_ERROR.

<?php

    $json = '[1,2,3]';
    try {
        $variable = json_decode($json, flags: JSON_THROW_ON_ERROR);
    } catch(ValueError $e) {
        print "JSON decoding error";
    }
    // $variable === [1,2,3];

?>

Documentation

See Also

json_encode()

json_encode() encodes a data structure into a JSON string.

In case an error arise during parsing, a null value is returned, as the default value. This error may be confused with the decoding of the 'null' string, which is a valid JSON value. It may also raise a ValueError, when the function is configured by JSON_THROW_ON_ERROR.

<?php

    $data = [1,2,3];
    try {
        $json = json_encode($data);
    } catch(ValueError $e) {
        print "JSON encoding error";
    }
    // $json === '[1,2,3]';

?>

Documentation

See Also

JSON Lines (JSONC)

JSONC, aka SON with Comments, is a superset of JSON that extends its functionality by allowing single-line // and multi-line /* */ comments.

This feature is commonly used in configuration files to improve readability, enabling developers to annotate data directly within the JSON structure.

Unlike standard JSON, which does not support comments, JSONC retains full compatibility with valid JSON. However, the reverse is not true: not all JSONC files are valid JSON.

<?php

    $JSONL = <<<JSONL
{a:1}
{b:2}
JSONL;

foreach(explode(\n, $JSONL) as $line) {
    print_r(json_decode($line));
}

/**
stdClass Object
(
    [a] => 1
)
stdClass Object
(
    [b] => 2
)
*/

?>

Documentation

See Also

JsonException

Exception thrown if JSON_THROW_ON_ERROR option is set for json_encode() or json_decode(). code contains the error type, for possible values see json_last_error().

<?php

try {
    $data = json_decode($incomingJSON, JSON_THROW_ON_ERROR);

    return base64_encode($data);
} catch (JsonException $e) {
    print 'Could not decrypt the data.';
}

?>

Documentation

See Also

JSON Lines (JSONL)

JSONL, JSON Lines, is a text-based format where each line is a valid, independent JSON object, separated by newline characters.

It is ideal for storing structured data, large datasets, and logging, as it allows for streaming and processing files line-by-line without loading the entire file into memory. It is also known as newline-delimited JSON, NDJSON.

<?php

    $JSONL = <<<JSONL
{a:1}
{b:2}
JSONL;

foreach(explode(\n, $JSONL) as $line) {
    print_r(json_decode($line));
}

/**
stdClass Object
(
    [a] => 1
)
stdClass Object
(
    [b] => 2
)
*/

?>

Documentation

See Also

JsonSerializable

The JsonSerializable interface is used to customize how an object is serialized into JSON using json_encode().

JsonSerializable simplifies the conversion to JSON by introducing a method to prepare the data. These data may be based on the properties of the object, but they may also change these names, create virtual and hide existing properties; the values may also be formatted to fit any specification.

There is no reverse method, where a JSON representation is converted into an object. It has to be done in a custom method.

<?php

class Point implements JsonSerializable {
    public function __construct(
        private int $x, 
        private int $y,
        ) {
    }

    public function jsonSerialize(): mixed {
        return [
            'latitude' => $this->x,
            'longitude' => $this->y
        ];
    }
}

$point = new Point(10, 20);
echo json_encode($point); // {latitude:10,longitude:20}

?>

Documentation

See Also

Jump

A jump typically refers to any non-linear control flow, where the program skips from one part of the code to another. In fact, it is bypassing the normal sequential execution.

There are a few constructs that qualify as jumps: goto, break, continue, yield, yield from, throw, return.

<?php

    function trumpet(int $a) {
        // jumps out of the method
        if ($a > 10) { return; }
        
        foreach(range(1, 10) as $i) {
            if (doSomething($i, $a)) {
                // jumps out of the loop
                break 1; 
            }
        }
        
        // normal execution
        return $a + 1;
    }

?>

Documentation

See Also

JSON Web Token (JWT)

A JSON Web Token, JWT, is a compact, URL-safe token format defined in RFC 7519, used to securely transmit claims between parties as a JSON object. JWTs are widely used for stateless authentication and authorisation in web APIs.

A JWT consists of three Base64URL-encoded parts separated by dots:

  • Header: the token type and signing algorithm, e.g. HS256, RS256, …
  • Payload: the data. It is often an arbitrary JSON structure with fields, plus registered properties such as iss for issuer, exp for expiration date, sub for subject
  • Signature: computed over header + payload using a secret or private key

Because the signature is verified on receipt, the payload can be trusted without a database lookup, making JWTs ideal for stateless, horizontally-scaled services. However, JWTs carry risks: they cannot be revoked before expiry without extra infrastructure, alg: none attacks disable signature verification, and storing them in localStorage exposes them to XSS.

JWTs are typically handled via libraries such as firebase/php-jwt or lcobucci/jwt.

<?php

    use Firebase\JWT\JWT;
    use Firebase\JWT\Key;
    
    $secret = 'my-secret';
    $payload = ['sub' => 42, 'exp' => time() + 3600];
    
    $token = JWT::encode($payload, $secret, 'HS256');
    $decoded = JWT::decode($token, new Key($secret, 'HS256'));
    
    echo $decoded->sub; // 42

?>

Documentation

See Also

Key-value Stores

A key value store is a database which stores data like a hash. The server stores values as a collection, and each object is identified with a unique key.

Classic key-value stores include memcache, redis, tokyo-tyrant.

Documentation

See Also

Keyword

PHP has a list of keywords, which are also called reserved names. Those are names used with some functions or operators.

Keywords are not allowed in function, constant, class, interface, enum and trait names. They are allowed in method, properties, variables and class constant names.

While legit, it is usually recommended to avoid using PHP keywords as identifiers, so as to prevent confusion.

<?php

    class Elephpant {
        function array() {
            return array();
        }
    }

    print_r((new elephpant)->array());

    class Herd {
        const array ARRAY = array(); // possible confusion here
    }

?>

Documentation

See Also

KISS

KISS stands for Keep It Simple, Stupid. It is a design principle that emphasizes the importance of simplicity in system design, development, and problem-solving. The idea is to avoid unnecessary complexity, which can lead to confusion, errors, and inefficiency.

Documentation

See Also

Kubernetes

Kubernetes, nicknamed k8s, is an open-source container orchestration platform that automates the deployment, scaling, networking, and lifecycle management of containerised applications. Originally developed by Google, it is now maintained by the CNCF.

The core abstractions in Kubernetes are: Pod, the smallest deployable unit, one or more containers sharing a network namespace, Deployment, declarative specification of desired pod replicas, Service, stable network endpoint for a set of pods, Ingress, HTTP routing from outside the cluster, ConfigMap and Secret, configuration injection, and HorizontalPodAutoscaler, automatic scaling based on CPU/memory or custom metrics.

PHP applications are deployed on Kubernetes as Docker containers, typically using PHP-FPM with nginx or Caddy as the HTTP front-end, or as FrankenPHP/Swoole workers. The Kubernetes service layer provides built-in service discovery via DNS. Kubernetes is the most common runtime for PHP microservices at scale.

k8s is the numeronym for Kubernetes: 8 letters between K and s.

# deployment.yaml — PHP-FPM application on Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: order-service
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: php-fpm
          image: myregistry/order-service:latest
          ports:
            - containerPort: 9000
          env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: url
        - name: nginx
          image: nginx:alpine
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: order-service
spec:
  selector:
    app: order-service
  ports:
    - port: 80

Documentation

See Also

Goto Labels

Labels are the receiving end of a goto call. They must be in the same context than the goto they relate to: there, they must be unique. There might be several goto for a single label.

<?php

    goto migrate;
    echo 'Forage';

    migrate:
    echo 'Trumpet';

?>

Documentation

See Also

Linux Apache Mysql PHP (LAMP)

LAMP is a popular open-source software stack used to build and deploy web applications. The acronym stands for:

  • Linux: the operating system.
  • Apache: the web server.
  • MySQL: the database management system, or alternatives like MariaDB.
  • PHP: the programming language used for server-side scripting.

Documentation

Language Construct

PHP has a notion of language construct, which are special keywords, with an attached feature.

Language constructs are: echo, require, require_once, include, include_once, return, die, exit, unset, isset, print, empty.

Language constructs usually do not require parenthesis, and they are mostly known for that. The parenthesis is not necessary, but possible. It makes the language construct look like a function call.

Also, language construct do not behave like a function, so they can’t be used by their name, as a callback.

There have some special behavior: echo accepts an arbitrary number of argument, while print only accepts one. die and exit work without arguments, but, in the event that an argument is provided, it must be enclosed in parenthesis.

<?php

echo 'a', 'b', 'c';

die;

?>

Documentation

See Also

Language Server Protocol (LSP)

A Language Server Protocol, an LSP server, is a program that provides language-intelligence features to any code editor and IDE that speaks the LSP standard.

Language features may be autocomplete, go-to-definition, documentation, and diagnostics.

LSP actually stands for the protocol, but it is often used for the LSP server itself. LSP may be provided by the IDE, or stand alone as an autonomous server.

Documentation

See Also

Laravel

Laravel is a popular PHP framework used for building web applications. It follows the Model-View-Controller, or MVC, architectural pattern and provides a clean, elegant syntax designed to make development faster and more efficient.

Documentation

See Also

Late Static Binding

PHP implements a feature called late static bindings, or simply late binding, which can be used to reference the called class in a context of static inheritance.

Before PHP 5.3, the self keyword always referred to the class where it was written, regardless of which child class actually made the call. This made it impossible for a static method inherited by a subclass to refer to that subclass reliably: calling a parent’s static method that used new self(), for example, always instantiated the parent class, even when invoked through a child. Late static binding solves this by introducing the static:: keyword, which resolves at call time, hence “late”, to the class that was actually used to make the call, rather than the class where the method was defined.

The mechanism keeps track of the “called class” as execution moves through the call stack: a static call, an instance method call, or a parent:: / self:: forwarding call all propagate that information, unless it is reset by an explicit ClassName:: call, which starts a new binding scope. The special function get_called_class() returns the same class name that static::class would resolve to.

Late static binding is heavily used to implement patterns such as the Active Record pattern, fluent factory methods, or the Singleton pattern, where a base class needs to instantiate or refer to whichever subclass is actually being used, without hardcoding that subclass’s name.

<?php

    class Elephpant {
        public static function who() {
            echo __CLASS__;
        }
        public static function announce() {
            static::who(); // Here comes Late Static Bindings
        }
    }

    class AfricanElephpant extends Elephpant {
        public static function who() {
            echo __CLASS__;
        }
    }

    AfricanElephpant::announce();

?>

Documentation

See Also

Latency

Latency is the delay between a request being made and the response being received. It is typically measured in milliseconds and is a key indicator of perceived application responsiveness.

Sources of latency include network round-trip time, database query time, I/O wait, and processing overhead. Reducing latency involves techniques such as caching, connection pooling, query optimization, and co-locating services.

Documentation

See Also

Latin1

Latin1, also called ISO/IEC 8859-1 and iso-8859-1, is a character encoding.

In simple terms Latin-1 lets computers represent common Western European characters like letters A–Z and a–z, numbers 0–9, punctuation, and special characters like é, ñ, ö, ç, £, €.

Latin1 uses 1 byte per character. It can represent 256 characters. It is designed for Western European languages like English, French, Spanish, German and Dutch. These language are not totally covered by the Latin1: usually, it requires the usage of UTF-8.

PHP used Latin1 as the default character set for publishing text on the web. It has now replaced it with UTF-8.

Documentation

See Also

Layered Architecture

Layered architecture, also called multi-tier architecture, n-tier architecture, or three-tier architecture in its classic three-layer form, organises a codebase into horizontal layers, each with a specific responsibility, where each layer only depends on the layer directly below it. The classic four layers are: presentation, business logic, data access, and infrastructure.

The Presentation layer handles user interaction and HTTP concerns, with controllers, templates. The Business Logic layer contains domain rules and application workflows. The Data Access layer, such as repository or DAO, abstracts persistence. The Infrastructure layer wraps external systems, like email, queues, file storage.

Layered architecture is the implicit structure of most MVC frameworks: controllers belong to the presentation layer, services to the business logic layer, and repositories to the data access layer.

The main risk is layer bleeding: business logic leaking into controllers, aka fat controller, or SQL queries scattered through the business layer. The anemic domain model anti-pattern often accompanies layered architecture when domain logic is spread across service classes rather than entities.

<?php

    // Presentation layer, controller
    class OrderController {
        public function __construct(private OrderService $service) {}
    
        public function create(Request $request): Response {
            $order = $this->service->placeOrder($request->validated());
            return new JsonResponse($order->toArray(), 201);
        }
    }
    
    // Business logic layer, service
    class OrderService {
        public function __construct(private OrderRepository $orders) {}
    
        public function placeOrder(array $data): Order {
            $order = Order::new($data);
            $order->validate();
            return $this->orders->save($order);
        }
    }

    // Data access layer, repository
    class OrderRepository {
        public function save(Order $order): Order {
            $this->pdo->prepare('INSERT INTO orders ...');
            return $order;
        }
    }

?>

Documentation

See Also

Lazy Evaluation

Lazy evaluation is an evaluation strategy in which an expression’s value is not computed until it is actually needed, and, once computed, is often cached so it is never recomputed. Haskell evaluates every expression this way by default: a list can be infinite, because only the elements actually consumed are ever produced.

This is stronger than lazy iteration: it applies to any expression, including function arguments and let-bindings, not only to sequences produced one step at a time.

PHP is strictly, eagerly evaluated everywhere except in a few specific opt-in constructs. Generator functions built with yield produce values lazily, one at a time, on demand, and short-circuiting operators such as &&, ||, and ?? skip evaluating their right-hand side when the outcome is already known. Outside of these, every argument, every array element, and every expression is fully evaluated as soon as control reaches it; there is no general, opt-out mechanism to defer an arbitrary computation until its result is read.

<?php

    // Lazy, but only because it is explicitly written as a generator.
    function naturals(): Generator {
        $n = 1;
        while (true) {
            yield $n++;
        }
    }
    
    foreach (naturals() as $n) {
        if ($n > 5) break;
        echo $n, ' ';
    }

?>

Documentation

See Also

Lazy Loading

Lazy loading is a programming pattern that postpones the actual loading of a resource to the moment it is actually used.

This prevents the application from loading resources that may not be used later: it improves efficiency.

Lazy loading happens with data and source code. Some entities may be loaded only when they are actually needed, to avoid loading too much data from the repositories, while they are not used.

PHP also uses lazy loading: some structures are checked at linting time, when they are available. Otherwise, their validation is deferred to execution. For example, method signature compatibility with parents, or class constant values.

<?php

class File {
    private $path;
    private $content = null;

    function __construct($path) {
        $this->path = $path;
    }

    function get() {
        if ($this->content === null) {
            $this->content = file_get_contents($path);
        }
        
        return $this->content;
    }
}

$file = new File($path);
// some more code
echo $file->getContent();

class ErroneousConstant {
    const VALID = 1;
    // invalid value for the INVALID constant
    const INVALID = [] + 1;
}

// displays 1
echo ErroneousConstant::VALID;
// This produces a Fatal error, even though it could be detected before. 
echo ErroneousConstant::INVALID;

?>

Documentation

See Also

Lazy Objects

Lazy objects are an application of lazy-loading, directly available in the PHP engine, and available as an engine feature since PHP 8.4.

The traditional way to create an object is to use new. The object is immediately created, and then, accessed later if needed.

Lazy objects defer the actual instantiation of the object until it is actually accessed. Nothing happens until the object is used. In the case of large applications, where lots of services or assets are created systematically, lazy objects postpone initialization, and may even skip it entirely if it is not needed.

Lazy objects are good for objects that take a lot of resources to initialize, or when there are lots of such objects, with a good proportion of them not being used, in the end.

<?php

    // taken from the RFC (https://wiki.php.net/rfc/lazy-objects)
    class Elephpant
    {
        public function __construct(private int $trunkLength)
        {
            // Heavy initialization logic here.
        }

        // ...
    }

    $initializer = static function (Elephpant $ghost): void {
        $ghost->__construct(123);
    };

    $reflector = new ReflectionClass(Elephpant::class);
    $object = $reflector->newLazyGhost($initializer);
     
    // At this point, $object is a lazy ghost object.

?>

Documentation

See Also

LDAP Injection

LDAP injection is a security vulnerability that occurs when untrusted user input is incorporated into an LDAP query without proper sanitisation or escaping. An attacker can manipulate the LDAP filter or distinguished name, or DN, to bypass authentication, escalate privileges, or extract sensitive directory information.

LDAP filters use special characters such as *, (, ), \, and NUL. Injecting these characters can alter the logic of a filter. For example, inserting * as a username may cause a wildcard match that returns all users.

Mitigation strategies include:

  • Escaping special characters with ldap_escape(), available since PHP 5.6
  • Using allowlists to validate input before use in a query
  • Applying the principle of least privilege on the LDAP service account.
<?php

    $username = $_POST['username'] ?? '';
    
    // Vulnerable: attacker can inject LDAP metacharacters
    $filter = '(uid=' . $username . ')';
    
    // Safe: use ldap_escape() with LDAP_ESCAPE_FILTER
    $safe   = ldap_escape($username, '', LDAP_ESCAPE_FILTER);
    $filter = '(uid=' . $safe . ')';
    
    $result = ldap_search($conn, 'ou=People,dc=example,dc=com', $filter);

?>

Documentation

See Also

Lightweight Directory Access Protocol (LDAP)

LDAP, acronym of Lightweight Directory Access Protocol, is an open, vendor-neutral, industry standard application protocol for accessing and maintaining distributed directory information services over an Internet Protocol, IP network.

<?php

    // LDAP server details
    $ldapServer = "ldap://your-ldap-server.com"; // or "ldaps://" for SSL
    $ldapPort = 389; // 636 for LDAPS
    $ldapDn = "cn=admin,dc=example,dc=com"; // Admin DN (Distinguished Name)
    $ldapPassword = "your-password";
    
    // Connect to the LDAP server
    $ldapConn = ldap_connect($ldapServer, $ldapPort);
    if (!$ldapConn) {
        die("Could not connect to LDAP server.");
    }
    
    // Set LDAP options (e.g., for protocol version)
    ldap_set_option($ldapConn, LDAP_OPT_PROTOCOL_VERSION, 3);
    ldap_set_option($ldapConn, LDAP_OPT_REFERRALS, 0);
    
    // Bind (authenticate) to the LDAP server
    $ldapBind = @ldap_bind($ldapConn, $ldapDn, $ldapPassword);
    if (!$ldapBind) {
        die("LDAP bind failed: " . ldap_error($ldapConn));
    }
    
    // Search for a user
    $searchBase = "ou=People,dc=example,dc=com";
    $searchFilter = "(cn=Damien Seguy)";
    $attributes = ["cn", "mail", "uid"]; // Attributes to retrieve
    
    $searchResult = ldap_search($ldapConn, $searchBase, $searchFilter, $attributes);
    if (!$searchResult) {
        die("LDAP search failed: " . ldap_error($ldapConn));
    }
    
    // Get the first entry
    $entry = ldap_first_entry($ldapConn, $searchResult);
    if (!$entry) {
        die("No entries found.");
    }
    
    // Retrieve attributes
    $attrs = ldap_get_attributes($ldapConn, $entry);
    echo "<pre>";
    print_r($attrs);
    echo "</pre>";

    // Close the connection
    ldap_unbind($ldapConn);

?>

Documentation

See Also

Leading Numeric String

A leading numeric string is a subset of numeric strings, where the first characters are numbers, or the occasional + or -, and the rest of the string is non-digits.

Leading numeric strings are used during conversion of strings into a number, although they are not used with the implicit integer conversion for arrays.

Leading numeric strings emit a warning when they drop the final characters.

<?php

    echo '123bc' + 1;
    // Warning: A non-numeric value encountered 
    // 124
    
    print_r(['123bc' =>1]);
    /*
      Array
      (
          [123bc] => 1
      )
    */

?>

Documentation

See Also

Leading Zero Means Octal

PHP integer syntax has some special formats for binary, octal and hexadecimal formats. In particular, an integer starting with 0 is in octal format. This leads to easy confusion, as the leading 0 is considered neutral.

A new notation with an 0 was introduced in version 8.0: it makes the octal format just as explicit as the binary or the hexadecimal one.

Octal numbers are mainly used with the mkdir() function, and special math domains.

<?php

    echo 017; // displays 15
    echo 0o17; // displays 15
    
    echo 17; // displays 17
    
    echo 0x17; // displays 23 (hexadecimal format)

?>

Documentation

See Also

Leak

A leak generally refers to a situation where resources are not properly released after they should have been. This can lead to degraded performance, crashes, or security issues.

Different types of leaks:

  • Memory leaks: memory is not freed, voluntarily or not, and reach memory_limit.
  • Resource leaks: resources such as file handles are not freed, voluntarily or not.
  • Data Leaks: sensitive data are made available, in an indirect way, and may even reach attackers.

Documentation

See Also

Legacy

Legacy code refers to existing code written under older practices, PHP versions, or conventions that are no longer considered current. It typically predates modern PHP features such as namespaces, type declarations, object-oriented design, or PSR standards.

Common PHP legacy patterns include procedural scripts, the use of mysql_* functions, which was removed in version 7.0, the var keyword for properties, global variables, register_globals, the absence of autoloading, and short open tags.

Maintaining and evolving legacy code requires careful refactoring to avoid regressions, since test coverage is often absent or incomplete. Static analysis tools can help identify outdated constructs.

<?php

    // Legacy PHP 4/5 style
    global $db;
    var $property;
    mysql_connect('localhost', 'root', '');

?>

Documentation

See Also

Linux Nginx Mysql PHP (LEMP)

LEMP is a popular open-source software stack used to build and deploy web applications. The acronym stands for:

  • Linux: the operating system
  • Nginx: the application server
  • MySQL: the database management system, or alternatives like MariaDB
  • PHP: the programming language used for server-side scripting

It is very similar to LAMP.

Documentation

LengthException

The LengthException exception is thrown if a length is invalid.

LengthException is one of the exception classes provided by the Standard PHP Library, called SPL, available since PHP 5.1. It extends LogicException, which itself extends the base Exception class, placing it in the family of exceptions that represent errors in the program’s logic, as opposed to runtime conditions that could not have been foreseen. Its intended use is to signal that a given length, whether of a string, an array, or any other measurable collection, does not meet the constraints expected by the code, for example a fixed-size buffer receiving too much data, or an argument that must contain a minimum number of characters.

Despite being part of the SPL, LengthException is not thrown by any native PHP function or class: PHP’s own standard library and internal functions instead raise ValueError or TypeError for equivalent situations since PHP 8. LengthException is therefore mostly a userland convention, adopted by libraries and frameworks that follow the SPL exception hierarchy to give callers a precise, catchable exception type when validating lengths themselves, rather than relying only on a generic Exception or InvalidArgumentException.

Because it is a subclass of LogicException, catching LogicException also catches LengthException, which lets calling code choose the granularity of the catch block depending on whether it needs to react specifically to length problems, or to logic errors in general.

<?php

    function trumpet(string $sound) {
        if (empty($sound)) {
           throw new \UnexpectedValueException('trumpet() expects a non-empty string');
        }
    }

?>

Documentation

See Also

Letter Logical Bug

PHP offers two sets of operators for logical operations: the letter operators, and, or, xor, and the symbol operators, &&, ||, no xor in symbol.

While they do the same, those operators have a difference: they do not share the same precedence. In particular, && has higher priority than = while = has higher priority than and. This leads to a difference in execution.

When combining = and &&, the logical operation happens before the assignation. While combining = and and actually ignore the logical operation.

The same problem affect yield, yield from, print, all assignations, including the short assignations, the ternary operator and the null-coalesce.

It is recommended to always use the symbol logical operators, which is closer to human expectations.

<?php

    $a = 1 && 3;
    
    $b = 1 and 3;
    // equivalent to 
    ($b = 1) and 3;
    
    var_dump($a); // true
    var_dump($b); // 1

?>

Documentation

See Also

Lexical Analysis

Lexical analysis, also called tokenisation, tokenization, or scanning, is the first phase of a compiler or static analyser. It reads a stream of source characters and groups them into meaningful units called tokens.

Each token carries a type, keyword, identifier, operator, literal, comment, whitespace, and the text it was matched from. The lexer discards whitespace and comments, or classifies them as separate token types when they are relevant.

PHP provides token_get_all() to tokenise a PHP source string into the same tokens the PHP engine itself produces, using the constants defined in the T_* family, like T_ECHO, T_VARIABLE, T_STRING, etc. This is useful for static analysis tools, code formatters, and documentation generators.

Lexical analysis operates on the surface form of the code and has no notion of program structure or meaning. Those concerns belong to parsing and semantic analysis.

<?php

    $source = '<?php echo $greeting . "world"; ?>';
    $tokens = token_get_all($source);
    
    foreach ($tokens as $token) {
        if (is_array($token)) {
            [$id, $text, $line] = $token;
            echo token_name($id) . ': ' . var_export($text, true) . PHP_EOL;
        } else {
            echo 'SYMBOL: ' . var_export($token, true) . PHP_EOL;
        }
    }

?>

Documentation

See Also

Lexical Variable

A lexical variable is the type of variable that appears in the use part of a closure definition. They are both variables of the current scope, which defines the closure, and parameters of the scope of the closure.

<?php

$c = 1;

function ($a, $b) use ($c) {
    // doSomething();
}

?>

Documentation

See Also

Library Loading

PHP has a modular structure, which allows it to load extensions. The extensions may be part of PHP at compilation time, and always available: this is the case for core, or string.

On the other hand, some extensions are loaded dynamically, with the dl() function. This is done during execution. It usually has an impact on performance, and security, and was restricted to be used only in command line, not on web servers.

<?php

    if (!extension_loaded('sqlite3')) {
        dl('sqlite3.so');
    }

?>

Documentation

See Also

Library

A library is a collection of reusable code, functions, classes, or constants, that provides specific functionality and can be included in different applications.

Libraries are included, and then executed: yet, they do not have an entry point of their own. The calling application controls when and how the library’s code is invoked. This distinguishes a library from a framework, which imposes a structure and calls the application’s code instead.

Libraries cover a wide range of concerns: string manipulation, date handling, HTTP clients, cryptography, image processing, data parsing, and more. Using a well-maintained library avoids reinventing the wheel and benefits from the work and review of the wider community.

Libraries are distributed through a package manager. The most common is Composer and libraries are indexed on Packagist. A library is declared as a dependency in composer.json and loaded via the Composer autoloader. Choosing a library involves evaluating its activity, test coverage, license, and compatibility with the target PHP version.

Writing a library requires extra discipline compared to application code: the public API must be stable, backward compatibility must be maintained across versions, and the library should have no opinion about the application’s framework or infrastructure.

Documentation

See Also

libsodium

Sodium is a modern, easy-to-use software library for encryption, decryption, signatures, password hashing and more.

The library is integrated into PHP as an extension. It provides a lot of functions and features to the language.

<?php
//Generate a random key for sodium_crypto_auth
$key = sodium_crypto_auth_keygen();

?>

Documentation

See Also

Licence

The licence refers to legal terms under which a source code is distributed and can be used.

PHP has its own licence, which is Open Source.

PHP source code may have a different licence. Common licences are MIT licence, Apache License 2.0, BSD License, GPL, LGPL, Copyleft Licenses.

Documentation

See Also

Lifecycle

The lifecycle of an application spans from initial development to decommissioning, covering stages like specifications, prototyping, coding, testing, deployment, maintenance, and eventual retirement.

Understanding the lifecycle helps teams build, deploy, and manage applications efficiently while ensuring reliability, security, and scalability.

The lifecycle is different depending on the team building it, and factors like community effort, personal interest or company mission.

As such, PHP itself has a lifecycle, with the regular release of a new version every year.

Lifecycle also refers to the execution cycle or request lifecycle, from starting the PHP engine, executing the code and terminating.

Documentation

See Also

Last In, First Out (LIFO)

Last In, First Out is the principle of management of a stack. The most recently added element is the first one to be removed. This is exactly how a stack behaves: it is also the way a backpack behaves.

The other management is FIFO: first in, first out.

Documentation

See Also

Line Feed

A line feed is a whitespace character, that historically represents moving the cursor to the next line, without going back to the beginning of the line.

A line feed is represented by the escape sequence \f, in double quote strings. It is also the ASCII code 12.

Line feed are important when formatting code, as they are at the end of a line.

<?php

    echo "\f";
    echo chr(12); // ASCII code 12

?>

Documentation

See Also

Linear Type

Linear types and affine types, together sometimes called ownership types, are type disciplines that constrain how many times a value may be used.

A linear type requires that a value is used exactly once: it must be consumed, neither discarded nor duplicated. This mirrors the mathematical concept of linear logic where a resource is a one-time token.

An affine type relaxes the constraint to at most once: a value may be consumed or silently dropped, but not used twice. Rust’s ownership system is built on affine types: moving a value transfers ownership, and the original binding becomes invalid.

The primary motivation is resource safety. A file handle typed as linear or affine cannot be closed twice, cannot be forgotten open, and cannot be shared without explicit transfer. The compiler enforces correct resource lifecycle without runtime bookkeeping.

Related to this is the concept of uniqueness types, Clean language, and borrowing, which temporarily grants read-only access without transferring ownership.

PHP has no linear or affine types. Values are reference-counted and can be freely copied, aliased, or ignored. Resource handles, like file handles, database connections, can be opened, re-used, or left unclosed without any static-analysis enforcement. The closest approximations are:

  • Destructor-based cleanup, __destruct, which runs when the last reference is dropped, but does not prevent double-use.
  • Value objects that track consumed state with a boolean flag at runtime.
  • Static analysis rules that heuristically warn about unclosed resources.

Documentation

See Also

Link

A link, or hyperlink, connects two resources, allowing navigation or reference from one to the other.

In web development, links are expressed as HTML <a> anchor elements and <link> elements. PHP generates both when rendering HTML.

In the filesystem, a link is a reference to a file or directory. PHP provides link() for hard links and symlink() for symbolic links. Both are used for deployment strategies, shared asset management, and plugin architectures.

In data structures, a linked list uses node-to-node references to chain elements. PHP does not have a native linked list, but SplDoublyLinkedList provides one.

In REST APIs, links in responses describe available actions and related resources as URLs.

<?php

    // Filesystem symlink
    symlink('/var/www/releases/v2.0', '/var/www/current');
    
    // HTML link generation
    $url = htmlspecialchars('https://www.php.net/', ENT_QUOTES, 'UTF-8');
    echo "<a href=\"$url\">PHP Manual</a>";
    
    // HTML <link> element for stylesheet
    echo '<link rel="stylesheet" href="style.css">';

?>

Documentation

See Also

Lint, Won’t Execute

Lint, won't execute is a special state of the code, where the source can be parsed, but cannot be executed.

This covers a range of problems, from very obvious to hidden syntaxes. They depend on the moment where PHP applies its checks.

Some situations depend on the inclusion, autoloading and, generally, the order of execution of the code.

<?php

    function trumpet() {
        clone 1; // obviously fails when executed
    }

    function forage(int $a = A) {}
    const A = 'abc';

    // fails when called without arguments
    trumpet(1); // OK
    trumpet();  // KO

?>

Documentation

See Also

Linting

Linting is the process to turn the text file that holds the source code into tokens. During this first phase, PHP applies some checks, and report anything that makes no sense.

After linting, the code is processed further before reaching the status of opcode, where it can be executed.

Linting is an option of the PHP CLI: -l.

Linting is sometimes mistaken with compile: linting is a part of a compilation. Since PHP has only this one step between the code and its execution, with eval() or the PHP CLI, linting is often considered as compiling. Reality is more complex.

Documentation

See Also

Liskov Substitution Principle (LSP)

The Liskov Substitution Principle states that an object from a class and a sub-object, from a class that extends that object, must be interchangeable without breaking the program.

Documentation

See Also

List Comprehension

A list comprehension is an expression-level syntax for building a new collection by describing it declaratively: a source, a transformation, and an optional filter, all in a single readable expression, as in Python’s [x * 2 for x in items if x > 0] or Haskell’s [x * 2 | x <- items, x > 0]. It is meant to read like the set-builder notation it is named after.

Because it is a single expression rather than a sequence of statements, a list comprehension can be nested, assigned, or passed as an argument directly, and many languages let the compiler fuse the filtering and mapping steps into a single pass.

PHP has no list comprehension syntax. The same result requires either an explicit loop that pushes onto an accumulator array, or a chain of array_map() and array_filter() calls, both of which are statements or nested function calls rather than a single declarative expression, and array_filter() followed by array_map() walks the array twice unless carefully reordered.

<?php

    // PHP equivalent of [x * 2 for x in items if x > 0]
    $doubled = array_map(
        fn ($x) => $x * 2,
        array_filter($items, fn ($x) => $x > 0)
    );

?>

Documentation

See Also

List

list() acts as the contrary to array(): it will break an array into individual elements, and assign them to the arguments of the list.

list() also has a short array version, which is [ ] the square brackets. Those square brackets only appear on the left side of an assignation.

list() may omit extracted values by skipping their value, and leaving seemingly empty arguments. list() also supports double-arrow notation, where the key is provided.

list() may be nested. It may also be used with foreach() structures.

list() looks like a function, though it is the only one to appears on the left part of an assignation, and is actually a language-construct.

A list is also the name given to arrays where the index are the automatic ones.

list() is the only expression where successive commas may be used.

<?php

    list($a, $b, $c) = [1,2,3];
    
    [$a, , [$c]] = [1,2,[3],4];
    
    [2 => $c, 0 => $a] = [1,2,3,4];
    
    $rows = [[1,2], [3, 4]];
    foreach($rows as [$a, $b]) {
        print "$a + $b\n";
    }
    
    // Only values are important here
    $list = range(10, 12);
    
    // some keys are missing => not a list
    $array = array(10, 4 => 12);

?>

Documentation

See Also

Listener

A listener, or event listener, also called a subscriber in pub/sub terminology, is a callable function that is registered to handle a specific event or message when it is dispatched. Listeners are a core concept in event-driven and pub/sub architectures.

Listeners are commonly registered with an event dispatcher. When an event is dispatched, the dispatcher calls all registered listeners for that event type, passing the event object as an argument. Listeners may be prioritised, stoppable, or asynchronous.

PSR-14 standardises the event dispatcher interface, making listeners interoperable across frameworks. Symfony’s EventDispatcher, Laravel’s Events system, and many other frameworks implement this pattern.

A listener differs from an observer in that listeners are usually registered externally on a dispatcher, while observers are typically attached directly to the subject object they watch.

<?php

// PSR-14 compliant listener
use App\Event\UserRegisteredEvent;

final class SendWelcomeEmailListener
{
    public function __invoke(UserRegisteredEvent $event): void
    {
        $user = $event->getUser();
        // send welcome email to $user->getEmail()
    }
}

// Registering the listener (Symfony example)
// In services.yaml:
// App\Listener\SendWelcomeEmailListener:
//     tags:
//         - { name: kernel.event_listener, event: App\Event\UserRegisteredEvent }

?>

Documentation

See Also

Literal Types

Literal types are types which not only check the type of a value but also the value itself. PHP has support for two literal types: false as of PHP 8.0.0, and true as of PHP 8.2.0.

<?php

    // bool is a type
    // false is a literal type : a bool, which value is false
    function trumpet(bool $a) : false {
        return false;
    }

?>

Documentation

See Also

Literal

A literal is a hard coded value in the source.

Literals may be of type int, float, boolean, null, array.

Objects and resources cannot be hardcoded, though their creation call may be.

Literals are given names by creating a constant, global or class.

<?php

    // Literal 1 to $a
    $a = 1;
    
    // The object is created during execution.
    $b = new Elephpant();

?>

Documentation

See Also

Large Language Model (LLM)

An LLM, or Large Language Model, is a type of artificial intelligence model designed to understand, generate, and interact with human language. These models are trained on vast amounts of text data, allowing them to recognize patterns, context, and nuances in language.

Documentation

See Also

Load Balancer

A load balancer, performing load balancing, is a component that distributes incoming network traffic across multiple backend servers to improve availability, throughput, and fault tolerance.

During deployment, the load balancer sits in front of a pool of PHP application servers, typically PHP-FPM behind Nginx or Apache. When a request arrives, the load balancer forwards it to one of the available servers according to a strategy: round-robin, least connections, IP hash, or weighted distribution.

Because requests can land on any server, PHP applications behind a load balancer must be stateless or externalise their state:

  • Sessions must be stored in a shared backend server, not on the local filesystem
  • Uploaded files must be written to shared storage, like NFS, an S3-compatible object store
  • Caches should be shared or invalidated across all nodes
  • Any resource that must persist between calls must be stored in a common server

A load balancer also provides health checks, in order to remove unhealthy nodes automatically, SSL termination, and sticky sessions, where it is routing a user’s requests to the same backend when true statelessness is not possible.

<?php

    // Detect the real client IP behind a trusted load balancer
    $clientIp = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'];

?>

Documentation

See Also

Local File Inclusion

A local file inclusion is a security vulnerability, where an external attacker can choose which file from the local system is processed by the called script.

This vulnerability is often used to access password files, such as /etc/passwd, or other hidden files. They might be read and displayed, or furthermore processed and modified.

<?php

    // Input URL : http://vulnerable_host/preview.php?file=../../../../etc/passwd
    file_get_contents($_GET['file']); 

?>

Documentation

See Also

Local Variable

A local variable is a variable in a method or a function. It is in the local scope, and is not available anywhere else.

A local variable is created by assigning it a value in a method, using the static keyword, or using the extract() function. It might be removed by the unset() function.

<?php

    function trumpet() {
        $localVariable = 1;
        // ... more code
    }

    function forage() {
        // this variable is distinct from the one in trumpet()
        $localVariable = 2;
        // ... more code
    }

?>

Documentation

See Also

Local Scope

The local scope is the scope inside a function or method. The variables are contained within that scope, and are not available beyond it.

The opposite of local scope is the global scope.

<?php

    function trumpet() {
        // $trunk variable is only available in the trumpet scope
        $trunk = 1;

        $closure = function () {
            // this scope is different from trumpet()
            // its definition is nested in the trumpet() function
            // but those are 2 distinct scopes
        };
    }

    function forage() {
        // $tusk variable is only available in the forage scope
        $tusk = 1;
    }

?>

Documentation

See Also

Locale

Locale are a set of configuration which describe how to handle different formats of data, such as monetary values, dates and time.

Locales are extracted from the system, and depends on a country name and a language name. For example, fr-FR for French French, nl_NL for Dutch, or zh_CN for Chinese Chinese.

Locale are supported with the ext/icu extension, and also, natively with the setlocale() function.

<?php

    /* Set locale to Dutch */
    setlocale(LC_ALL, 'nl_NL');
    
    /* Output: vrijdag 22 december 1978 */
    echo strftime("%A %e %B %Y", mktime(0, 0, 0, 12, 22, 1978));

?>

Documentation

See Also

Lock

A lock is a mechanism used to control access to a shared resource so that only one process can use it at a time.

There are different kinds of locks:

  • File locks, when using flock() function
  • Database locks, via transactions or explicit locks in the database
  • Semaphore locks, based on sem extension.
<?php

    $sem = sem_get(123456);
    
    sem_acquire($sem);
    // critical section
    sem_release($sem);

?>

Documentation

See Also

Log File

Log, or logging, is a list of events that happen during execution of a piece of software. Logs are often referred to as log file, though they might be handled by specific servers, nowadays.

Log reports meaningful events during execution. They are used after execution to provide overview of the process: performance, exceptional events, etc.

Logs may be saved on the local machine, or exported to external storage.

Log is also the short name for logarithm.

Documentation

See Also

Log

Log has several meanings:

  • Log file, or logging, to collect events traces as they happen
  • Logarithm, the math function

As a logging mechanism, PHP provides the low-level error_log() function to write a message to the system logger, a file, or by email, and the log_errors/error_log php.ini directives to route uncaught errors there automatically. Above that layer, PSR-3 Psr\Log\LoggerInterface standardizes a common logging API across eight severity levels, from debug to emergency, and Monolog is the de facto implementation used by Symfony, Laravel, and most modern frameworks, dispatching log records to handlers such as files, syslog, Slack, Sentry, or Elasticsearch.

As a math function, log() computes the natural logarithm by default, or the logarithm to an arbitrary base when a second argument is supplied; log10() provides base-10 logarithms directly, but PHP has no dedicated base-2 function, so it is computed as log($x, 2).

Documentation

See Also

Logarithm

The logarithm is a family of mathematical functions, where log($a * $b) == log($a) + log($b). There are two logarithm functions: the natural logarithm, where log(M_E) == 1, and the base-10 logarithm, where log(10) == 1.

PHP also offers log1p($x) == log(1 + $x). This function exists because log($x) is very close to 0 when $x is close to 1. To avoid rounding errors, log1p() is dedicated to this calculations and immediately yields the decimal part of the logarithm.

The opposite function of the logarithm is exponential, exp(), and the ** operator.

A logarithm is not the same as an algorithm, or a log file.

<?php

    echo log(M_E);
    print PHP_EOL;  // 1
    
    echo log(1); 
    print PHP_EOL;  // 0
    
    echo log(1.001); 
    print PHP_EOL;  // 0.00099950033308342
    
    echo log1p(0.001); //0.00099950033308353
    print PHP_EOL;

?>

Documentation

See Also

Logical Operators

Logical operators applies four logical functions to booleans.

  • and and &&, the and operator
  • or and ||
  • xor, no symbolic version for xor
  • !, no letter version for not

The logical operators are either symbolic or letter. Be aware that the symbolic operators have a higher precedence than the letter one, in particular in regards to comparisons.

The logical operators work on various types, and output booleans. They are different from the bitwise operators, which work on the value as a bit level, not as a whole.

<?php

    if ($a == $b) {
        print "a and b are equal";
    }

?>

Documentation

See Also

LogicException

Exception that represents error in the program logic. This kind of exception should lead directly to a fix in your code.

LogicException is part of the SPL exception hierarchy introduced in version 5.1, extending the base Exception class. It signals a fault that could, in principle, be detected before runtime by inspecting the code, a violated precondition, an unreachable code path, or a contract broken by the caller, as opposed to RuntimeException, whose sibling hierarchy covers errors that can only be detected while the script is executing, such as I/O failures or unexpected external data.

PHP never throws a bare LogicException itself; it serves as the common base for more specific SPL exceptions: BadFunctionCallException, and its child BadMethodCallException, for calling an undefined function or method, DomainException for a value outside a defined set of valid values, InvalidArgumentException for an argument of the wrong type, LengthException for a value of invalid length, and OutOfRangeException for an illegal index requested outside of iteration. Catching LogicException lets code handle all of these programmer-error cases with a single catch block.

<?php

    // No direct exemples. Use the children classes.

?>

Documentation

See Also

Look-up

A look-up is the operation of retrieving a value from a data structure by key, index, or identity. It is one of the most fundamental operations in programming, and its efficiency depends on the underlying structure: O(1) for hash tables, O(log n) for sorted arrays or trees, and O(n) for linear search.

The most common look-up structures are associative arrays, which use hash tables internally and offer average O(1) access by string or integer key. Objects, SPL data structures, and databases serve as look-up sources in larger systems.

Look-up tables are a specific pattern where a computation is replaced by a precomputed array indexed by the input. They trade memory for speed by eliminating repeated calculations.

Look-ups also appear implicitly in many places: variable resolution, function dispatch, method resolution, and class autoloading are all look-up operations performed by the engine itself.

Understanding look-up complexity matters for performance-sensitive code: choosing a hash-based structure over a sequential scan can change an O(n) bottleneck into an O(1) operation.

<?php

    // Simple look-up in an associative array
    $countryNames = [
        'FR' => 'France',
        'DE' => 'Germany',
        'JP' => 'Japan',
    ];
    
    $code = 'FR';
    $name = $countryNames[$code] ?? 'Unknown'; // O(1) look-up
    
    // Look-up table replacing a computation
    $dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
    $dayName = $dayNames[date('w')]; // index look-up instead of switch/match

?>

Documentation

See Also

Loops

A loop is a control structure that allows to execute a block of code repeatedly based on a specified condition. Loops are essential for automating repetitive tasks and processing arrays or collections of data. PHP provides several types of loops, including: for, while, do…while and foreach.

The most popular loop is foreach().

Loops may hide in certain functions: for example, array_map() and array_walk() apply a method to every element in an array.

Generators are closely related to the foreach() loop.

<?php

    foreach([11,12,13] as $id => $value) {
        print "$id => $value\n";
    }
    
    for ($i = 1; $i <= 10; $i++) {
        echo $i;
    }
    
    $i = 10;
    while ($i <= 10) {
        echo $i++;  
    }
    
    $i = 10;
    do {
        echo $i++;  
    } while ($i <= 10);

?>

Documentation

See Also

Lossless

Lossless refers to any encoding, compression, or conversion process that preserves all of the original data exactly. After a lossless operation, the original content can be reconstructed bit-for-bit from the encoded form.

In image processing, lossless formats such as PNG and GIF use lossless compression: every pixel is preserved and no image quality is sacrificed to reduce file size. Lossless compression is suited to images with sharp edges, text, icons, and screenshots, where artefacts introduced by lossy compression would be visible.

In data serialisation and encoding, lossless round-trips guarantee that encoding then decoding returns the original input, with no data truncated or altered.

PHP’s GD extension produces lossless output with imagepng() and imagegif(). The compression level passed to imagepng() affects file size but not image fidelity.

<?php

// PNG is lossless: every pixel survives the encode/decode cycle
$image = imagecreatefrompng('original.png');
imagepng($image, 'copy.png', 6); // level 6 compression, still lossless
imagedestroy($image);

?>

Documentation

See Also

Lossy

Lossy refers to any encoding, compression, or conversion process that permanently discards some of the original data in order to reduce size or simplify the representation. Once a lossy operation has been applied, the discarded data cannot be recovered.

In image processing, lossy formats such as JPEG and WebP reduce file size by approximating colour information and discarding fine detail that the human eye is less sensitive to. Higher compression levels increase the degree of loss, introducing visible artefacts such as blocking and ringing. Lossy compression is well suited to photographs where a small quality reduction is imperceptible.

Repeated encode/decode cycles with a lossy format degrade quality cumulatively, because each cycle discards additional data.

PHP’s GD extension produces lossy output with imagejpeg(). The optional quality parameter, 0–100, controls the trade-off between file size and fidelity.

<?php

    // JPEG is lossy: quality 60 discards more data than quality 90
    $image = imagecreatefromjpeg('photo.jpg');
    imagejpeg($image, 'compressed.jpg', 60);
    imagedestroy($image);

?>

Documentation

See Also

LSP

LSP is an acronym that has several meanings:

  • Liskov Substitution Principle, part of SOLID programming paradigm
  • The Language Server Protocol, which provides language intelligence.

Documentation

See Also

Lvalue

An lvalue is an expression that designates a storage location capable of holding a value, as opposed to an rvalue, which only produces a value. The name comes from left value: historically, the kind of expression allowed on the left-hand side of an assignment.

An lvalue may be modifiable or non-modifiable. A modifiable lvalue, such as a variable, an array element or an object property, can be the target of an assignment or of a by-reference operation. A non-modifiable lvalue, such as a class constant or the result of a function returned by value, designates a location whose value cannot be changed through that expression.

<?php

    $a = 1;      // $a is a modifiable lvalue
    $arr[0] = 2; // $arr[0] is a modifiable lvalue
    
    class Elephpant {
        const HABITAT = 1;
    }

    // Elephpant::HABITAT is a non-modifiable lvalue: this is a compile-time error
    // Elephpant::HABITAT = 2;

?>

Documentation

See Also

Machine Learning

Machine learning is a field of artificial intelligence, which teaches an application how to react to a vast number of situations with a training dataset, before applying these teachings on new situations.

Documentation

See Also

Macro

A macro is a rule or pattern that maps a source text or syntax fragment to a replacement, which is then substituted before or during compilation. Macros operate at the level of source text, for example the C preprocessor, tokens, for example Rust macro_rules!, or AST nodes, asin Lisp and Elixir, and allow programmers to extend the syntax of a language or eliminate repetitive code without the overhead of a function call.

Two main families of macros exist:

  • Textual macros non-hygienic: the C preprocessor #define replaces a name with a literal text fragment. Variable names inside the macro can accidentally shadow names in the calling scope, leading to subtle bugs.
  • Hygienic macros: as in Scheme’s syntax-rules, Rust’s macro_rules!, and Elixir’s defmacro, each identifier introduced by the macro is automatically renamed to prevent accidental capture of caller variables.

PHP has no native macro system. PHP source code is parsed and executed directly by the Zend Engine; there is no macro-expansion phase. The mechanisms that approximate macros are:

  • eval(): executes a PHP string at runtime, but provides no hygiene and operates after parsing.
  • Token-level preprocessors such as yay run before the PHP parser and perform textual or token-level substitutions, but offer no hygiene guarantees.
  • nikic/php-parser allows full AST rewriting via a visitor pattern, enabling macro-like transformations with explicit, manually implemented scope tracking.
  • Compile-time constants const and class constants serve a narrow, value-substitution role similar to object-like C macros, but without the generality of function-like macros.

See also hygienic macro for the hygiene-specific aspects of macro systems.

<?php

    // PHP has no macro expansion. Constants are the closest equivalent
    // to simple object-like C macros (#define MAX 100).
    const MAX_RETRIES = 3;

    // For function-like macros, PHP uses ordinary functions.
    // No inline expansion; call overhead applies.
    function clamp(int $value, int $min, int $max): int {
        return max($min, min($max, $value));
    }

    // Token-level macro with the yay preprocessor (external tool, run before PHP):
    //   macro {clamp(·v, ·lo, ·hi)} >> {max(·lo, min(·hi, ·v))}
    // This expands inline but is not hygienic.

?>

Documentation

See Also

Magento

Magento is an open-source PHP e-commerce platform. It provides a comprehensive feature set for building online stores, including product catalogue management, checkout, payment integration, and a flexible extension system.

Magento was created by Varien and released in 2008. It was acquired by eBay in 2011, spun off as an independent company in 2015, and acquired by Adobe in 2018, where it continues under the name Adobe Commerce. The open-source edition remains available as Magento Open Source.

Magento 2, released in 2015, is a full rewrite using modern PHP practices, including dependency injection, service contracts, and a modular architecture.

Documentation

See Also

Magic Bytes

Magic bytes are the first bytes of the content of a file. This is where the format of the file is actually defined, or specified. These bytes are used to recognize the type of the file.

Documentation

See Also

Magic Constants

Constants which hold information about the current location of the code.

Those constants are magic, because they have a constant syntax, yet their value may change, even during the execution of the code.

  • LINE The current line number of the file.
  • FILE The full path and filename of the file with symlinks resolved. If used inside an include, the name of the included file is returned.
  • DIR The directory of the file. If used inside an include, the directory of the included file is returned. This is equivalent to dirname(__FILE__). This directory name does not have a trailing slash unless it is the root directory.
  • FUNCTION The function name, or {closure} for anonymous functions.
  • CLASS The class name. The class name includes the namespace it was declared in, e.g. Foo\Bar. When used in a trait method, CLASS is the name of the class the trait is used in.
  • TRAIT The trait name. The trait name includes the namespace it was declared in, e.g. Foo\Bar.
  • METHOD The class method name.
  • NAMESPACE The name of the current namespace.
  • PROPERTY The name of the current property hook.

Those constants are case insensitive. While the common convention is to use them all in uppercase, all the following syntaxes work: __METHOD__, __method__, __meTHod__.

<?php

function trumpet() {
    // shows trumpet
    echo __FUNCTION__;
}

function forage() {
    // shows forage
    echo __FUNCTION__;
}

?>

Documentation

See Also

Magic Hash

A magic hash is a hash string which is mistakenly compared to another hash.

In the example below, the same MD5 hash is taken for two distinct strings, which ends up being identical, per ==.

In reality, the two hashes are different strings: 0e462097431906509019562988736854 and 0e830400451993494058024219903391 respectively. When they are compared, as strings, PHP identifies the initial 0 of the strings, and assume the comparison should be an integer comparison.

Each string is turned into a int, which are 0 in both cases. Hence, the comparison succeeds, yet it wrong.

The protection against magic hashes is to use the identity operator ===, rather than the equality. It makes a type comparison and do not apply type juggling, which leads to the two hashes above different.

This example is applicable with any hash algorithm which produces a string that starts with 0. Check the magic hash repository for examples with SHA256, HAVAL, PHOTON, RIPEMD or SPONGENT.

There are PHP functions and operators that perform safe comparisons ,such as ===, !== and hash_equals().

<?php

    var_dump(md5('240610708') == md5('QNKCDZO'));
    
    //md5('240610708')
    //0e462097431906509019562988736854
    //md5('QNKCDZO')
    //0e830400451993494058024219903391

?>

Documentation

See Also

Magic Code

Magic in the code happens when a simple command execute a lot more than it seems. Things that are happening in the background must be known to the coder, or it will come as a surprise.

Documentation

See Also

Magic Methods

Special methods, which provide extended support for PHP features.

The magic methods are: __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() and __debugInfo().

The constructor and destructor are not considered as magic methods, even though they are reserved.

<?php

class Elephpant {
    function __get($name) {
        return $this->$name;
    }
}

?>

Documentation

See Also

Magic Numbers

A magic number is a number that appears in the code, and has no obvious signification.

It is recommended to make the meaning of that number obvious. This is achieved by using constants, class or global, where the name of the constant improves readability.

Magic numbers also applies to other literal values, such as string, float, arrays. Though, they are more difficult to sort out of the code.

Magic numbers are difficult to categorize, when they are very common across different fields. For example, 0, 1, 2, 10 are very common for different tasks, and may need several disambiguations. Others, such as 60, 404, 1024, are common usage. Finally, there might be business specific numbers, such as 42.

<?php

foreach($array as $id => $values) {
    // Only displaying 10 values, but couldn't that limit be parametered?
    if ($id > 10) {
        break;
    }
    
    print $values.PHP_EOL;
}

?>

Documentation

See Also

Magic Property

Special properties, each also called an overloaded property, which are not declared, but dynamically handled by the magic methods. They do not have specific declaration.

The magic methods to handle magic properties are: __get(), __set(), __isset() and __unset().

<?php

class Elephpant {
    function __get($name) {
        return 'World!';
    }
}

$elephpant = new Elephpant;
echo $elephpant->hello; // display World!

?>

Documentation

See Also

Magic Values

A magic value is a literal value that appears in the code without a clear explanation of its meaning.

Similar to magic numbers, magic values can be strings, arrays, or other literal types. They should be replaced with named constants or configuration values to improve readability and maintainability.

<?php

    // Magic string value
    $role = 'admin';
    
    // Better: use a constant
    const ROLE_ADMIN = 'admin';
    $role = ROLE_ADMIN;

?>

Documentation

See Also

Magic

Magic is used to characterize something that happens out of the blue, without rational explanation. It mostly used in the sentence: There is too much magic in this code. It usually refers to conventions which trigger certain behaviors, though they are not explicit in the code, but rather documented and learnt.

Magic has only a remote relationship to PHP’s magic constants, magic numbers and magic methods.

Documentation

See Also

Mail

mail() is the PHP native function that sends emails. It is a relay to system commands that actually send the mail.

mail() does not provide support to structure mail, in particular attachments. This is left to custom components, such as PHPMailer.

<?php

    $message = World;

    mail('contact@php.net', 'Hello!', $message);

?>

Documentation

See Also

Maintenability

Maintainability refers to how easy it is to understand, modify, and extend source code over time, especially as the project grows or / and requirements change.

A maintainable codebase is:

  • Readable: code is well-structured, uses meaningful names, and follows consistent formatting
  • Modular: functions, classes, and files are logically organized and decoupled
  • Documented: clear comments and documentation explain complex logic and intent
  • Testable: unit and integration tests ensure changes don’t break existing functionality
  • Debuggable: errors and logs are clear, and debugging is straightforward
  • Up-to-date: code adheres to modern PHP standards and avoids deprecated features.

Documentation

See Also

Maintenance

Maintenance is the operation to keep a source code running, long time after it was created. While the source code itself may be unchanged, some of the contextual features it relies on may have changed. The main challenge of maintenance is to understand the current level of features, to be able to reproduce them with a different set of tools.

Maintenance is also used to identify the period between two running versions of a software. To avoid interference with actual usage of the application, an application is put in maintenance mode, updated, and then, released from the maintenance mode. This notion of maintenance is related to operations and production.

Documentation

See Also

Makefile

A Makefile is a configuration file used by the make build automation tool. It defines targets, their dependencies, and the shell commands to run when a target is built. Targets declared with .PHONY are always executed regardless of any file with the same name.

In projects, Makefile files act as task runners that group common developer operations: installing dependencies, running tests, checking code style, running static analysis, or deploying.

# Makefile
.PHONY: install test lint fix deploy

install:
\tcomposer install

test:
\tvendor/bin/phpunit

lint:
\tvendor/bin/phpstan analyse src/
\tvendor/bin/php-cs-fixer check src/

fix:
\tvendor/bin/php-cs-fixer fix src/

deploy: test
\trsync -avz src/ user@server:/var/www/app/

Documentation

See Also

Man In The Middle

A Man-in-the-Middle attack, aka MitM, is a cyberattack where a malicious actor intercepts and possibly alters communications between two parties without their knowledge. In this attack, the attacker positions themselves between the communicating parties, acting as a relay for the messages exchanged between them.

Man-in-the-Middle attacks can be executed in various ways, such as by compromising public Wi-Fi networks, exploiting vulnerabilities in network protocols, or through techniques like ARP spoofing or DNS spoofing. The goal of these attacks can vary, from eavesdropping on sensitive information to injecting malware or conducting phishing scams.

To mitigate the risk of MitM attacks, encryption protocols like SSL/TLS are often used to secure communications between parties, making it difficult for attackers to intercept and decipher the data being transmitted. Additionally, users should be cautious when connecting to public Wi-Fi networks and ensure they are accessing websites over HTTPS to reduce the risk of interception and manipulation.

Documentation

See Also

Map

A map refers to an abstract data type, ADT, that stores key-value pairs, where each key is unique within the map. This feature is supported by arrays.

PHP’s array syntax supports a feature to assign the index an arbitrary key. A map allows efficient lookup, insertion, and deletion of values based on their associated keys. The key-value pairs are typically unordered, meaning that the order of insertion may not be preserved when iterating over the map’s elements.

Maps are also called associative array, dictionary, or hashes.

Maps are useful to associate a value with a specific key and perform operations like searching for a value by its key or updating the value associated with a key. They provide a convenient way to store and retrieve data based on some unique identifier.

<?php

    // explicit keys : this is a map
    $array = ['a' => 0, 2 => 1, '123' => 2];
    
    
    // keys are assigned automatically
    $array = [0, 1, 2];

?>

Documentation

See Also

Markdown

Markdown is a lightweight markup language that can be used to add formatting elements to plain text documents. Created by John Gruber in 2004, it uses simple, readable syntax – such as # for headings, * for emphasis, and - for lists – that a parser converts into HTML or other output formats. It is widely used for README files, documentation, code comments, changelogs, and static site generators, precisely because it stays easy to read even before it is rendered. Several libraries implement Markdown parsing, such as league/commonmark, erusev/parsedown, and michelf/php-markdown.

Documentation

See Also

Marker Interface

A marker interface, also called a tagging interface, embodying the marker interface pattern, is an interface with no methods or constants. It is used only to ‘mark’ or ‘tag’ a class as having a certain property, so that property can be checked at runtime with instanceof, without imposing any method to implement.

Marker interfaces rely on type-checking rather than polymorphism: the mere presence of the interface carries the information, not any method call on it. This is different from a regular interface, which enforces a contract of methods.

Attributes are often a more expressive, modern replacement for marker interfaces, since they may also carry data alongside the tag.

<?php

// An empty interface, used only to tag a class
interface Cacheable {}

class Report implements Cacheable {}
class Invoice {}

function persist(object $object) {
    if ($object instanceof Cacheable) {
        // store the object in a cache layer
    }
}

?>

Documentation

See Also

Marketplace

A marketplace usually means a platform where developers can buy, sell, or distribute PHP or framework related products or services. These products are typically code packages, themes, plugins, scripts, APIs, or SaaS integrations that other developers or businesses can use in their PHP projects.

Documentation

See Also

Mass Assignment

Mass assignment is the practice of setting several properties of an object at once from an associative array, instead of assigning each property individually. It is a common convenience feature of ORMs and frameworks: Laravel’s Eloquent models can be filled with Model::create($data) or $model->fill($data), and similar patterns exist in Doctrine, Symfony forms, and plain constructors that loop over an input array and set matching properties.

The convenience becomes a vulnerability when the array being assigned comes directly from user input, such as $request->all(), without restricting which fields are allowed to be set. An attacker can then add extra keys to the submitted data, such as is_admin or role, and have them silently written to the object alongside the fields the form actually intended to expose. This class of vulnerability is also known as auto-binding or over-posting, and was responsible for a well-known 2012 GitHub incident where a user added his own public key to any organization through a mass-assigned parameter.

The standard mitigation is allow-listing: explicitly declaring which properties may be mass-assigned, such as Eloquent’s $fillable array, or the inverse deny-list $guarded, which allow-listing is generally considered safer than. A stricter alternative is to avoid binding user input directly to domain or persistence objects altogether, and instead pass it through a dedicated Data Transfer Object that only exposes the fields the operation is meant to accept.

A related but distinct case is mass variable assignment, done directly in userland code rather than through an ORM. extract() takes an associative array and creates one local variable per key in a single call, and compact() performs the reverse, packing a list of variable names into an associative array. This carries the same class of risk as ORM mass assignment when the array comes from unfiltered input: extract($_GET) silently creates or overwrites any local variable named by a request parameter, which is why extract() on untrusted data is generally discouraged, in favor of naming the expected variables explicitly.

<?php

    // Vulnerable: any key in the request can set any Eloquent attribute
    class User extends Model {}
    User::create($request->all());
    // an attacker submitting ['name' => 'Bob', 'is_admin' => 1] becomes an admin

    // Mitigated: only the allow-listed fields can be mass-assigned
    class User extends Model
    {
        protected $fillable = ['name', 'email'];
    }
    User::create($request->all());
    // 'is_admin' is silently ignored

    // Mass variable assignment: extract() and compact()
    $data = ['name' => 'Bob', 'age' => 42];
    extract($data);
    echo $name; // 'Bob', now a local variable

    $packed = compact('name', 'age');
    // ['name' => 'Bob', 'age' => 42], the reverse of extract()

    // Vulnerable: any request parameter becomes a local variable
    extract($_GET);

?>

Documentation

See Also

Mass

mass shows up in several distinct PHP and ORM concepts. They are easy to confuse because they all involve applying one operation to several attributes or rows at once:

  • Mass assignment: filling several properties of a single object at once from an associative array, typically Model::create($data) or $model->fill($data). When the array comes from unfiltered user input, it is a well-known security vulnerability, since an attacker can inject extra keys the form never intended to expose.
  • Mass update / mass deletion: running an update() or delete() directly against a query builder result, affecting every row that matches the query in a single SQL statement, without ever loading the matching models. This is a behavioral gotcha rather than a security issue: since the models are never retrieved, per-model events, mutators, and observers do not fire.
  • Mass mailing: sending the same, or templated, email to a large number of recipients at once, usually through a dedicated queue or third-party service rather than PHP’s synchronous mail().

Absent further context, mass in a PHP codebase or discussion most often refers to mass assignment.

Documentation

See Also

Match

The match expression is the remote cousin of the switch. It takes a value, branch among a list of cases, or fallback to a default one, and returns a unique value.

match use a strict comparison for the comparison. match raise an error if no case match, unless the default case is provided.

match is an expression, to be used in an assignment, while switch is a command, and must be used alone.

<?php

    $return_value = match ($food) {
        'apple' => 'This food is an apple',
        'bar'   => 'This food is a bar',
        'cake'  => 'This food is a cake',
        default => 'This is not food'
    };

?>

Documentation

See Also

Math

PHP offers many math features. There are the native math functions, such as exp(), cos() or abs(); there are operators, such as +, *, **, etc. There are special notions, such as NaN, Not a number, and the constant INF, which represents the infinite.

There are also extension, such as bcmath and gmp, to handle arbitrary large numbers.

Finally, there are many packages that provide optimized code to run math specialties, like matrices, complex numbers or statistical tools.

<?php

    $total = 1 + 2 * 3 - 4 ** 5; 

?>

Documentation

See Also

max_execution_time

The max_execution_time directive sets the maximum amount of time that PHP will work on an application.

The default value is 30 seconds. It may be lowered down to 1 second, or set to infinity with -1.

max_execution_time may be changed from the code with set_time_limit(). This function may also be disabled, and not available.

It is recommended to set this value as low as possible, and optimize the code to run below that limit.

Documentation

See Also

max_input_vars

The max_input_vars directive caps the number of input variables PHP will accept per request, counting every entry in $_GET, $_POST and $_COOKIE, including each element of nested arrays.

The default value is 1000. When a request exceeds that limit, PHP silently drops the extra variables instead of raising a catchable error: a warning is only emitted if E_WARNING is part of error_reporting and displayed, which makes the failure easy to miss in production.

This directive exists to mitigate a denial-of-service vector related to hash collisions in the internal array implementation: a request with a huge number of keys forces expensive hash-table rebuilding. Large forms, big multi-select inputs, or deeply structured JSON-like arrays submitted as form fields are the usual reasons legitimate applications need to raise this value.

max_input_vars can only be set in php.ini, a virtual host configuration, or .htaccess: unlike memory_limit, it cannot be changed with ini_set() at runtime, since the limit must be enforced while the request body is still being parsed, before user code ever executes.

Documentation

See Also

max_memory_limit

max_memory_limit is not a PHP core directive: it designates the pattern, used by several frameworks and CMS, of defining an upper bound that a script is allowed to raise memory_limit to at runtime, on top of the regular, lower, day-to-day memory_limit.

The best known example is WordPress’ WP_MAX_MEMORY_LIMIT constant, which caps the value that wp_raise_memory_limit() may apply with ini_set('memory_limit', ...) when running memory-hungry admin tasks, such as image processing or plugin updates, while WP_MEMORY_LIMIT keeps the front-end footprint low.

This two-tier approach avoids granting every request the same generous ceiling: routine requests keep a conservative memory_limit, while a small set of known heavy operations may temporarily request more, up to max_memory_limit, without risking unbounded memory consumption on the rest of the application.

<?php

    // WordPress-style pattern
    define('WP_MEMORY_LIMIT', '64M');
    define('WP_MAX_MEMORY_LIMIT', '256M');

    function raise_memory_limit(string $context = 'admin'): void {
        $current = ini_get('memory_limit');
        $limit = $context === 'admin' ? WP_MAX_MEMORY_LIMIT : WP_MEMORY_LIMIT;

        if ($current !== '-1' && wp_convert_hr_to_bytes($limit) > wp_convert_hr_to_bytes($current)) {
            ini_set('memory_limit', $limit);
        }
    }

?>

Documentation

See Also

Multibyte String

mbstring is the PHP extension dedicated to processing multibyte character strings, that is, text encoded in character sets where a single character can occupy more than one byte, such as UTF-8, UTF-16, EUC-JP, Shift-JIS, or Big5. Native PHP string functions like strlen, substr, or strtoupper operate byte by byte and were designed for single-byte encodings such as ASCII or Latin-1; applied blindly to multibyte text, they routinely miscount character lengths, cut a multibyte character in half, or fail to case-convert characters outside the ASCII range. mbstring provides a parallel set of functions, all prefixed with mb_, such as mb_strlen, mb_substr, mb_strtoupper, and mb_convert_case, that are character-aware and behave correctly regardless of the encoding in use. Beyond string manipulation, the extension also performs encoding detection and conversion between character sets through mb_convert_encoding and mb_detect_encoding, integrates with regular expressions through a multibyte-safe regex engine, and can override PHP’s built-in string functions transparently via configuration so that legacy code becomes multibyte-safe without modification. It is essential for internationalized applications handling Asian languages, emoji, or any text outside the ASCII range, and is bundled with most PHP distributions though it must still be enabled explicitly.

<?php

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

?>

Documentation

See Also

Model Context Protocol (MCP)

An MCP server usually refers to a server that implements the Model Context Protocol, or MCP. It’s a relatively new standard used to connect AI models, like assistants or coding agents, with external tools, data sources, and services in a structured way.

Documentation

See Also

mcrypt Extension

mcrypt is a PHP extension that provides access to the mcrypt library. It provides a variety of cryptographic algorithms.

mcrypt was deprecated in version 7.1 and removed in version 7.2. It is recommended to use sodium or openssl instead.

<?php

    $key = pack('H*', "bcb04b7e103a0cd8b54763051cef08bc55abe029fdebae5e1d417e2ffb2a00a3");

    $key_size =  strlen($key);
    echo "Key size: " . $key_size . "\n";
    
    $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_128, MCRYPT_MODE_CBC);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

    $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key,
                                 $plaintext, MCRYPT_MODE_CBC, $iv);

?>

Documentation

See Also

Message Digest Algorithm 5 (MD5)

MD5 is a hash function, that produce a 128-bit footprint for a value.

MD5 was used a lot for secure hashing and control. Nowadays, it may be useful for hashing and comparing data, though it is not considered secure.

<?php

//Generate a MD5 hash with the history md5() native function
echo hash('md5', 'Le rapide goupil brun sauta par dessus le chien paresseux.');

//Generate a MD5 hash with the history md5() native function
print md5("Some text.")

?>

Documentation

See Also

Memcached

Memcached is a distributed, in-memory key-value store used to cache the results of database queries, API calls, or rendered fragments, so that repeated requests can be served from RAM instead of recomputing them. Unlike APCu, whose cache lives inside a single PHP process pool, Memcached runs as a separate daemon and can be shared across many web servers, making it a natural fit for load-balanced, multi-server deployments.

PHP talks to Memcached through the Memcached extension, built on libmemcached, which offers a richer API, including binary protocol support and consistent hashing across a server pool, than the older, now unmaintained, memcache extension.

A Memcached instance connects to one or more servers with addServer(), then stores and retrieves values with set() and get(), optionally passing a TTL, time-to-live, after which the entry is evicted. Memcached has no built-in persistence: on restart or eviction under memory pressure, cached data is simply gone, so it should only ever hold data that can be recomputed.

<?php

    $memcached = new Memcached();
    $memcached->addServer('127.0.0.1', 11211);

    $memcached->set('user:42', json_encode(['name' => 'Ada']), 300); // cache for 5 minutes

    $user = json_decode($memcached->get('user:42'), true);

?>

Documentation

See Also

Memoization

Memoization is an optimisation technique to speed up a function by avoiding re-processing previously calculated results.

Usually, memoization trades processing time with memory. The best suited situation are when the load takes some time to process, and the result is a small amount of memory, such as a count.

<?php

function docs($file) {
    // local cache 
    static $cache = [];
    
    // If it was already cached, use it. 
    // Docs are supported to be constant during the execution
    if (isset($cache[$file])) {
        return $cache[$file];
    }
    
    $cache[$file] = file_get_contents($file) ?? '';
}

?>

Documentation

See Also

Memory Arena

A memory arena is a large, contiguous block of memory that is pre-allocated upfront and then carved into smaller pieces on demand. Rather than calling the system allocator individually for each object, code requests slices from the arena, which simply advances an internal pointer. When the arena is done, the entire block is freed in a single operation.

The pattern trades deallocation granularity for speed and locality. Individual objects in an arena cannot be freed independently; the whole region is reclaimed at once when the arena’s lifetime ends. This makes arenas well-suited for short-lived, batch-style work such as parsing, compilation, or request processing where many small allocations are created together and discarded together.

PHP’s Zend Engine uses arena allocators internally for per-request memory. The emalloc/efree family of functions that extensions use are backed by a per-request arena that is wiped at the end of each request, making object-by-object deallocation unnecessary. OPcache similarly uses dedicated memory regions for its shared memory segment. PHP’s JIT compiler uses arenas for generated machine code buffers.

From a PHP developer’s perspective, arenas are invisible: the engine manages them automatically. Understanding them helps explain why PHP’s per-request memory model is efficient and why memory_limit is enforced at the request level rather than the object level.

Documentation

See Also

Memory Leak

A memory leak is the allocation of memory, without its deallocation when that memory is not needed anymore.

As PHP manages the memory itself, memory leaks happen in different situations:

  • Accumulation of data, without release. For example, an array that collects new data and never removes them.
  • Circular reference: objects or variables keep a link one onto each other, and the PHP garbage collector sees them in use.
  • Disabled garbage collector: the garbage collector was disabled, and does not perform collection
  • Bugs: sometimes, the memory usage is not voluntary.

Documentation

See Also

Memory

Memory refers to the portion of server RAM that PHP uses to execute scripts.

Whenever a PHP application runs, it needs memory to load the PHP engine, parse the code, store data and various caches.

Memory usage is controlled by the memory_limit directive, and functions like memory_get_usage().

PHP handles the memory management, and there is little more to do beyond setting the overall limit, although some features may become memory hungry easily, such as array_merge() in loops, or the N+1 query problem.

Documentation

See Also

memory_limit

memory_limit is the directive that caps the maximum amount of memory that PHP can use.

The limit is expressed in bytes, although options are available for kb K, Mb M and Gb G, case insensitive.

The limit may be lifted by setting this directive to -1.

PHP requires a minimum of memory when starting. Usually, it is about 2Mb of RAM. Setting any positive value for memory_limit below that threshold prevents PHP from starting.

The default value of memory_limit is 128 Mb.

memory_limit may be changed during execution with ini_set().

<?php

    echo ini_get('memory_limit');  //128M

?>

Documentation

See Also

Merge

To merge is the action of combining two things into one. There are usually two meaning associated with PHP code:

  • Merging arrays, with the eponymous function array_merge(), or the + operator
  • Code merge, using a VCS, such as git, svn, etc.
<?php

    $array1 = [1,2];
    $array2 = [3,4];
    
    array_merge($array1, $array2); // [1,2,3,4]
    $array1 + $array2;             // [1,2,3,4]

?>

Documentation

See Also

Message Bus

A message bus is a communication mechanism that allows different components or services to exchange messages in a decoupled manner. It acts as an intermediary channel through which senders publish messages and receivers consume them, without either party having direct knowledge of the other.

In applications, a message bus is typically implemented as an synchronous in-process dispatcher or as a wrapper around an asynchronous external message broker. The Symfony Messenger component is a popular PHP implementation that supports both modes and can route messages to queues backed by AMQP, Redis, Doctrine, or other transports.

A message bus often covers three patterns:

  • Command bus: routes commands to a single handler.
  • Event bus: broadcasts domain events to multiple listeners.
  • Query bus: routes queries to a single handler that returns a result.

Using a message bus decouples the code that sends a message from the code that handles it, improving maintainability, testability, and scalability.

<?php

    // Symfony Messenger: dispatching a command
    use App\Message\SendEmailNotification;
    use Symfony\Component\Messenger\MessageBusInterface;
    
    final class UserRegistrationService
    {
        public function __construct(
            private readonly MessageBusInterface $bus,
        ) {}
    
        public function register(string $email): void
        {
            // ... persist the user ...
    
            $this->bus->dispatch(new SendEmailNotification($email));
        }
    }

?>

Documentation

See Also

Message Digest

A message digest is the fixed-size output of a cryptographic hash function, applied to an arbitrary piece of data, called the message. The term comes from the MD family of algorithms, MD2, MD4 and MD5, but it is now used generically for the result of any cryptographic hash.

A message digest acts as a fingerprint: it is small, deterministic, and any change to the original message, even a single bit, produces a completely different digest. This makes digests useful to detect tampering, verify downloads, and sign data.

Unlike a checksum, which mainly targets accidental corruption, a message digest is designed to resist deliberate manipulation: it should be computationally infeasible to find two different messages producing the same digest, an event called a collision, or to reconstruct a message from its digest alone.

Message digests are produced with the hash() function, or its dedicated shortcuts such as md5() and sha1(). Older algorithms like MD5 and SHA1 are now considered broken for security purposes, and SHA256 or better should be preferred.

<?php

    // generic access, through the hash extension
    echo hash('sha256', 'The quick brown fox jumped over the lazy dog.');

    // dedicated shortcut functions
    echo md5('The quick brown fox jumped over the lazy dog.');
    echo sha1('The quick brown fox jumped over the lazy dog.');

?>

Documentation

See Also

Message Queue

A message queue server is a middleware component or service that facilitates communication between different software components or systems by enabling asynchronous message passing. It provides a mechanism for sending, storing, and receiving messages between different parts of an application or between separate applications, often across distributed or networked environments.

Message queues are commonly used in scenarios where components need to communicate and exchange data without requiring immediate responses or direct interaction. This decoupling of components through asynchronous communication offers several advantages, including improved scalability, fault tolerance, and responsiveness.

Documentation

See Also

Meta-object Protocol (MOP)

A Meta-object Protocol, also called for MOP, is an API that exposes a language’s own object system as a first-class, programmable layer. Through a MOP, user code can redefine how classes are created, how methods are looked up and dispatched, how instances are allocated, and how inheritance is resolved: extending or replacing the object model itself from within the language. The canonical MOP is CLOS, Common Lisp Object System, which exposes generic functions such as make-instance, compute-applicable-methods, and slot-value as overridable entry points.

Python’s data model, with __new__, __init_subclass__, __class_getitem__, metaclasses, and Ruby’s BasicObject and method_missing give partial MOP-like access. Smalltalk’s entire class hierarchy is itself a set of Smalltalk objects, making it fully reflective by design.

PHP does not have a Meta-object Protocol. PHP’s object system is implemented in C and is not programmable from userland. PHP does provide several approximations:

  • The Reflection API, ReflectionClass, ReflectionMethod, ReflectionProperty, exposes read access to the object model at runtime, but cannot modify it.
  • Magic methods, __get, __set, __call, __callStatic, __isset, __unset, intercept individual property and method access operations, giving hook points that resemble parts of a MOP.
  • class_alias() lets user code create alternative names for classes, but cannot alter dispatch behaviour.
  • Closure::bind() and Closure::bindTo() allow closures to be rebound to a different object scope, approximating dynamic method injection.
  • Libraries such as ocramius/proxy-manager implement lazy-loading and interception proxies on top of these primitives, simulating part of what a MOP would provide natively.
<?php

    // PHP Reflection: read-only introspection of the object model.
    // A true MOP would also allow redefining dispatch and instantiation.

    $rc = new ReflectionClass(ArrayObject::class);

    foreach ($rc->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
        echo $method->getName() . "\n";
    }

    // Magic methods: intercept property/method access, limited MOP hooks.
    class DynamicEntity {
        private array $data = [];

        public function __get(string $name): mixed {
            return $this->data[$name] ?? null;
        }

        public function __set(string $name, mixed $value): void {
            $this->data[$name] = $value;
        }

        public function __call(string $name, array $args): mixed {
            // intercept unknown method calls, not full method-dispatch override
            throw new \BadMethodCallException("No method: $name");
        }
    }

    // Rebind a closure to a different object scope (approximates method injection)
    $greet = Closure::bind(
        static function (string $suffix): string { return self::class . $suffix; },
        null,
        DynamicEntity::class
    );

?>

Documentation

See Also

Metaclass

A metaclass is a class whose instances are themselves classes. In a language with a full metaclass system, every class is an object, and that object is an instance of a metaclass. The metaclass controls how the class is created, how its instances are instantiated, and how method resolution, attribute access, and inheritance work. Python’s type is the default metaclass; a custom metaclass inherits from type and overrides __new__, __init__, or __call__ to intercept class creation.

Smalltalk was the original language to formalise the idea: every class in Smalltalk has a corresponding metaclass that describes the class’s own behaviour. Ruby’s eigenclasses, singleton classes, serve a related role.

PHP does not have metaclasses. PHP classes are not objects that can be instantiated from a metaclass, and there is no hook point at which user code can intercept or modify class creation at the language level.

PHP approximations of metaclass-like behaviour:

  • Abstract classes and interfaces constrain what a class must look like without controlling how it is created.
  • The Reflection API ReflectionClass allows runtime introspection of a class’s structure but cannot alter it.
  • Magic methods __get, __set, __call, and __callStatic intercept property and method access on instances, approximating some MOP hooks.
  • Attribute-driven frameworks such as Doctrine or Symfony DI read class-level #[Attribute] annotations and generate or register behaviour at build time, simulating what a metaclass might do during class creation in Python.
  • class_alias() can create alternative names for classes but cannot redefine their behaviour.
<?php

    // PHP has no metaclass. The Reflection API offers read-only introspection.
    $rc = new ReflectionClass(DateTime::class);
    echo $rc->getName() . ' has ' . count($rc->getMethods()) . " methods\n";

    // Attribute-driven behaviour: closest PHP equivalent to metaclass registration.
    #[\Attribute(\Attribute::TARGET_CLASS)]
    final class Entity {
        public function __construct(public readonly string $table) {}
    }

    #[Entity(table: 'users')]
    class User {
        public function __construct(
            public readonly int $id,
            public readonly string $name,
        ) {}
    }

    // A framework reads the attribute at build or boot time — similar to what
    // a Python metaclass __init_subclass__ hook would do automatically.
    $attr = (new ReflectionClass(User::class))
        ->getAttributes(Entity::class)[0]
        ->newInstance();
    echo $attr->table; // 'users'

?>

Documentation

See Also

Metadata

Metadata is data that describes other data: it does not carry the actual content, but information about its structure, origin, or meaning.

Metadata takes several forms:

  • Attributes, since PHP 8.0, allow attaching structured metadata to classes, methods, properties, and functions, readable at runtime through Reflection, and used by frameworks for routing, serialization, validation, or dependency injection
  • Docblocks, PHPDoc comments, provide informal metadata such as @param, @return, or @deprecated, consumed by IDE, static analysis tools, and documentation generators, though not by the PHP engine itself
  • Reflection exposes structural metadata about classes, methods, and parameters at runtime, such as visibility, type declarations, and attributes
  • File metadata, such as timestamps, permissions, or EXIF data embedded in images, describes properties of a file rather than a class or function

Metadata is central to many cross-cutting concerns: ORM use it to map classes to database tables, serializers use it to control field visibility, and routers use it to bind URLs to controllers.

<?php

    #[Attribute]
    class Route {
        public function __construct(public string $path) {}
    }

    class UserController {
        #[Route('/users')]
        public function list(): array {
            return [];
        }
    }

    $method = new ReflectionMethod(UserController::class, 'list');
    foreach ($method->getAttributes(Route::class) as $attribute) {
        $route = $attribute->newInstance();
        echo $route->path; // /users
    }

?>

Documentation

See Also

Metaprogramming

Metaprogramming is the practice of writing code that treats other code as data. This is reading, generating, transforming, or executing programs at runtime or compile time. A metaprogram operates at a higher level of abstraction than an ordinary program because it manipulates the representation of programs rather than, or in addition to, running domain logic.

Common metaprogramming techniques include:

  • Reflection: inspecting types, methods, properties, or annotations at runtime, with the ReflectionClass
  • Code generation: emitting source files, proxy classes, or configuration from schemas, attributes, or templates
  • Macros: transforming code at a syntactic level before or during parsing
  • Eval: constructing and executing code strings at runtime
  • Dynamic dispatch: routing method calls through __call or __callStatic based on runtime state
  • Homoiconicity: using a language’s native data structures to represent and manipulate programs

PHP supports several forms of metaprogramming:

  • The Reflection API, with the classes ReflectionClass, ReflectionMethod, ReflectionProperty, ReflectionAttribute, provides read-only introspection of the live object model.
  • Magic methods, with the methods __get, __set, __call, __callStatic, __invoke, __clone, __toString, intercept property and method access at runtime.
  • eval() and create_function() execute dynamically constructed code strings.
  • nikic/php-parser enables full AST-level read and write access to PHP source from PHP itself.
  • PHP 8.0+ attributes allow structured metadata on declarations, consumed at runtime by frameworks and code generators.
  • Userland code generators, such as Doctrine proxies, Rector, Symfony DI compilation, etc. produce PHP files before or at application boot.

PHP does not support compile-time generics, hygienic macros, metaclasses, or a Meta-object Protocol: the object model is implemented in C and is not programmable from userland.

<?php

    // 1. Reflection: introspect a class at runtime
    $rc = new ReflectionClass(ArrayObject::class);
    echo $rc->getMethod('offsetGet')->getNumberOfParameters(); // 1

    // 2. Dynamic dispatch via magic method
    class DynamicProxy {
        public function __call(string $name, array $args): mixed {
            return strtoupper($name) . '(' . implode(', ', $args) . ')';
        }
    }
    echo (new DynamicProxy())->hello('world'); // HELLO(world)

    // 3. Attribute-driven metadata (PHP 8.0+)
    #[\Attribute(\Attribute::TARGET_METHOD)]
    final class Route {
        public function __construct(public readonly string $path) {}
    }

    class UserController {
        #[Route('/users')]
        public function index(): void {}
    }

    $attr = (new ReflectionMethod(UserController::class, 'index'))
        ->getAttributes(Route::class)[0]
        ->newInstance();
    echo $attr->path; // '/users'

?>

Documentation

See Also

Method Collision

A method collision happens when a trait is imported in a class, and it holds a method that already exists in the class.

To solve such a collision, the code must use insteadof and use keywords, in the use expression.

There is no collision between the imported trait and the parent of the class, as the trait has priority over the parent. There is also no collision when a trait imports another trait: the last method has precedence.

<?php

    trait Herd {
        function trumpet() { echo __METHOD__; }
    }

    trait Waterhole {
        function trumpet() { echo __METHOD__; }
    }

    class Elephpant {
        use waterhole, herd {
            use herd::trumpet instead of waterhole;
        }
    }

    new elephpant()->stampede();

?>

Documentation

See Also

Method Compatibility

Method compatibility means that when a class overrides a method, from a parent class or interface, the new method must keep a compatible signature.

In short, the child method must:

  • Have the same or wider visibility, e.g. public stays public, private becomes protected
  • Accept the same parameter types, or more general ones
  • Return the same type, or a more specific one
  • Not require more mandatory parameters

If it’s incompatible, PHP throws a fatal error.

<?php

class Elephpant {
    function trumpet(int $a): void {}
    function forage(int $a): Elephpant {}
    function migrate(int $a): string {}
}

class Calf extends Elephpant {
    // This is compatible, as it is identical to the parent method
    function trumpet(int $a): void {}

    // This is compatible, yet not identical
    // the parameter is more general
    // the return type is more precise
    function forage(int|string $a): Calf {}

    // This is not compatible with the parent's method signature
    function migrate(int $a): int {}
}

?>

Documentation

See Also

Method Overloading

Method overloading is a feature that allows multiple definitions of a method, depending on the type of the passed parameters.

Method overloading is a PHP feature, based on the usage of the func_get_args() native function. It differs from other language’s implementation as there is only one method definition, but multiple execution paths. Method overloading usually requires other features, such as typing or default values, to be handled manually.

<?php

//
class Elephpant {
    // $a and $b could be typed array|int
    // returntype could be array|int 
    // yet, it may end up being confusing
    function substract($a, $b) {
        if (is_int($a)) {
            return $a - (int) $b; 
        }
        
        if (is_array($a)) {
            return array_diff($a, (array) $b);
        }
    }
}

?>

Documentation

See Also

Method Signature

The signature of a method or a function is the list of arguments and constraints that apply when calling it.

In its simplest form, signature of a method is its name, its argument’s type and list, though modern syntax also includes default values, visibilities, attributes and parameter names.

Method signature also applies to functions and closures, where it is also called a function signature or closure signature. It may also be referenced as signature.

<?php

    function trumpet(string &$s = 'abc') {}

    class Elephpant {
        function trumpet(string &$s = 'abc') {}
    }

?>

Documentation

See Also

Method

Methods are functions, dedicated to a class. They are defined inside the body of a class, and may only be accessed in relation to that class: via an object, the class name or another method.

Methods are defined in traits, and then imported in a class for usage.

Methods are also called member functions. Indeed, they are functions, but they belong to an object, just like a member, or property. This is less used.

<?php

    class Elephpant {
        public function trumpet() {
            echo "I am trumpet!\n";
        }
    }

    $elephpant = new Y();
    $calf->trumpet(); // calling the trumpet method, defined in Elephpant,

?>

Documentation

See Also

Methodcall

A method call is the actual usage of a method. It requires an object, the method name and the arguments for the method.

A method call is based on an object, and the -> and ?-> operators. A method call may be static: the operator is then ::, and the left operand is a class name, expressed as a string; although, it may also be an object, though the class of that object is used, not the object itself.

Methods may be called by using the array syntax: array($object, $methodname)($arguments).

Method call may be chained. This means that the method returns an object, either the current one or another; then another call of method is built on top of this call.

Static methods must be called statically. Method must be called non-statically, although it is possible to call them statically within a class: this is convenient for parent::__construct(), for example.

<?php

    class Elephpant {
        function trumpet($a) {}

        static function stampede($b) {}
    }

    $elephpant = new elephpant;

    // a method call
    $elephpant->trumpet(1);
    [$elephpant, 'trumpet'](1);

    // a static method call
    elephpant::stampede(2);
    $elephpant::stampede(3);
    elephpant::class::stampede(4);
    [elephpant::class, 'stampede'](1);

?>

Documentation

See Also

Metrics

Metrics refer to quantitative measurements used to evaluate the performance, quality, and behavior of the code.

These metrics help understand how the application behaves in production, identify bottlenecks, optimize performance, and ensure code quality.

Here are some common metrics:

  • Time of execution
  • Memory consumption
  • Number of database queries
  • Cyclomatic complexity
  • Code coverage
  • Cognitive complexity
  • Code duplication
  • Lines of code

PHPMetrics is also the name of an eponymous project.

Documentation

See Also

Multi-Factor Authentication (MFA)

Multi-Factor Authentication, MFA, also called two-factor authentication when exactly two factors are used, is a security mechanism that requires a user to provide two or more independent verification factors before access is granted. The three classical factors are:

  • Something known: a password or PIN.
  • Something possessed: a hardware token, authenticator app, TOTP/HOTP, or SMS code.
  • Something being: a biometric such as a fingerprint or face recognition.

Requiring at least two factors dramatically reduces the risk of account compromise: stealing a password alone is no longer enough.

In the PHP ecosystem, MFA is relevant both at the application level, protecting user accounts, and at the infrastructure level. Packagist, for example, has introduced mandatory MFA for package publishers to harden the supply chain against account takeover.

PHP itself does not ship MFA libraries, but the ecosystem offers several: scheb/2fa-bundle with Symfony, pragmarx/google2fa with Laravel, and generic TOTP/HOTP packages.

<?php

    use OTPHP\TOTP;
    
    // Generate a TOTP secret for a user at enrolment time
    $totp   = TOTP::generate();
    $secret = $totp->getSecret(); // store this in the user record
    
    // At login time, verify the code the user typed
    $userCode = $_POST['totp_code'];
    if (!$totp->verify($userCode)) {
        throw new RuntimeException('Invalid MFA code');
    }

?>

Documentation

See Also

Micro-optimisation

A micro-optimisation is a piece of code that performs better than another, yet brings only a small gain of performance.

Micro-optimisation should be done only for highly constrained systems, or applications that deliver a high number of hits in short times: usually, it takes one to ten million usages for the gain to be visible.

Yet, micro-optimisations may be valuable in the long run, or as a good practice.

It is often pointless to discuss the micro-optimisation. It is a do or don’t, and should raise a consensus, or be left alone.

<?php

    // this is faster than calling 3 times echo
    echo 1, 2, 3;
    
    // This is slower, yet it doesn't speed up the process a lot
    echo 1;
    echo 2;
    echo 3;

?>

Documentation

See Also

Micro-second

Micro-seconds are one thousandth of a second. They are accessible in different ways:

  • Datetime and DateTimeImmutable objects, for dates
  • microtime() for dates
  • hrtime() for intervals

Do not use date() to get micro-seconds, as the function always returns 0.

<?php

$ms = (new Datetime()->format('u'));

$ms = microtime(true);

?>

Documentation

See Also

Micro-framework

A micro-framework is a small, minimal framework that provide only the core essentials for routing and handling HTTP requests, without large stacks or heavy dependencies. Examples include Slim and Lumen.

Documentation

See Also

Microservice

A microservice is a software architectural style that structures an application as a collection of small, independent services, each focused on performing a specific business functionality. These services are designed to work together seamlessly, usually communicating over well-defined APIs. Unlike traditional monolithic architectures, where an entire application is built as a single, tightly integrated unit, microservices break down the application into smaller, loosely coupled components.

Documentation

See Also

microtime()

microtime() is a native PHP function, which returns the current timestamp, including microseconds. This is a very precise measure of time.

microtime() is often used for speed measurements, and it may be easily replaced by hrtime() for that purpose, since PHP 7.3.

<?php

    $time_start = microtime(true);
    
    // Sleep some time
    usleep(100);
    
    $time_end = microtime(true);
    $time = $time_end - $time_start;
    
    echo "Slept for $time seconds\n";

?>

Documentation

See Also

Middleware Pattern

A middleware, or middleware pattern, is a design pattern used to extend the behavior of a component by chaining layers that can modify inputs, outputs, or short-circuit the call, dynamically at runtime.

Unlike the Decorator pattern, middlewares can be added at runtime, conditionally, from configuration. This pattern is inspired by PSR-15, which standardizes HTTP middleware for request handlers.

The key characteristic is that the $next parameter is typed to the component’s own interface, enabling IDE autocompletion and type safety throughout the chain. Implementing the middleware stack requires some glue code to chain the layers together; see the documentation link below for a complete implementation.

<?php

    interface HtmlRendererInterface
    {
        public function render(string $template, array $data = []): string;
    }
    
    // The middleware interface mirrors the component interface,
    // with an additional $next parameter typed to HtmlRendererInterface
    interface MiddlewareInterface
    {
        public function render(
            string $template,
            array $data,
            HtmlRendererInterface $next,
        ): string;
    }
    
    // Before pattern: modify input, then delegate
    class TimestampMiddleware implements MiddlewareInterface
    {
        public function render(
            string $template,
            array $data,
            HtmlRendererInterface $next,
        ): string {
            $data['generatedOn'] = date(DateTime::ATOM);
    
            return $next->render($template, $data);
        }
    }
    
    // Before+After pattern: wrap $next to also process output
    class CacheMiddleware implements MiddlewareInterface
    {
        private array $cache = [];
    
        public function render(
            string $template,
            array $data,
            HtmlRendererInterface $next,
        ): string {
            $key = hash('sha256', $template . serialize($data));
    
            if (isset($this->cache[$key])) {
                return $this->cache[$key]; // short-circuit: return early without calling $next
            }
    
            $this->cache[$key] = $next->render($template, $data);
    
            return $this->cache[$key];
        }
    }

?>

Documentation

See Also

Migration

Migration is the incremental upgrade of a piece of code.

It is often used for databases, for example, with Laravel database migrations; for components and frameworks, a framework migration: for example, CakePHP migration. Migration applies to versions, a version migration, within a framework, or between two distinct framework.

Usually, migration requires some action from the user, although a migration script may be provided.

Migration may also be called upgrades. They may be paired with a rollback, which allows to go back to the previous state, and try again later.

Documentation

See Also

Minification

Minification is the process to remove elements that are useless in a PHP code, without changing its execution.

For example, whitespaces and comments may be removed from PHP code: it makes the code much smaller, but also, less readable.

Minified code has a smaller footprint on the disk, and may be faster to load, read and process. Minifying has very limited impact on PHP code, and is not considered an optimisation technique.

Minification is applied successfully on HTML, CSS, SVG, XML, JSON, JavaScript, and image formats.

Minification may be used for obfuscation.

Unminify is the contrary of minifying.

<?php

    // minified version
    for($i=0; $i<10;++$i) { print "$i\n";}
    
    // minified version
    for($i = 0; $i < 10; ++$i) {
        // This displays a number
        print "$i\n";
    }
    
    // structure that cannot be minified
    echo 1 . 2; // displays 12 
    echo 1.2; // displays 1.2 

?>

Documentation

See Also

Minus One -1

Minus one is the -1 integer. -1 is part of the truthy values: it is the equivalent of true.

-1 is part of the three values returned by the spaceship operator.

0 is a classic magic number, although it has so many uses that it is usually overlooked, as generating too many false positives or scattered issues.

<?php

    $zero = 0;

    $four = 4 + 0;
    
    // may it returns 1 or -1, this is true
    var_dump((bool) 1 <=> -1); // true
    var_dump((bool) -1 <=> 1); // true

?>

Documentation

See Also

Minus -

- is a native PHP operator, which allows subtraction on numbers, both integers and decimals, or produce the opposite of a number.

- silently triggers a conversion to a number, preferably integers, but otherwise decimal. It may produce a warning or a fatal error, if this is not possible.

It may also be repeated, with the pre- and post- increment operators.

It is the contrary to +.

<?php

$a = 2 - 1; // 1

$a = -$a; // -1
$a = -$a; //  1

--$a; // 0
$a--; // -1 

?>

Documentation

Missing Subpattern

Final subpatterns, when not used by a regex to succeed, are omitted from the result. This happens as PHP optimizes the last results, and do not report non-finding subpatterns.

On the other hand, the program may expect the subpatterns to be available, albeit empty. Generally speaking, subpatterns are actually filled when the regex succeed.

The safe solution is to use the PREG_UNMATCHED_AS_NULL flag, which makes sure they are always provided.

This situation applies to preg_match() and preg_match_all(). It also applies to the ? and * quantifiers, when they are used on a subpattern, at the end of the regex. Non-terminal subpatterns are provided, to avoid confusion with the following ones.

<?php

    preg_match('/(a)(b)?(c)?/', 'a', $matches);
    var_dump($matches);
    // [a, a] 
    
    preg_match('/(a)(b)?(c)?/', 'a', $matches, flags: PREG_UNMATCHED_AS_NULL);
    var_dump($matches);
    // [a, a, null, null] 

?>

Documentation

Missing Validation

Missing Validation is a common security vulnerability that occurs when an application fails to validate user input or data before processing it. This can lead to a wide range of security issues, including injection attacks, data corruption, unauthorized access, or even system compromise.

Missing validation means the application does not check whether the input or data it receives is:

  • Correctly formatted, e.g., an email address, number, or date
  • Within expected boundaries, e.g., length, type, or range
  • Safe to process, e.g., free from malicious code or unexpected characters

It is important to remember that validation applies to incoming variables, such as $_GET, but also with formatted data, like JSON or YAML; formatted files like PDF or Zip; database data, etc. In fact, every external source of data should be considered a potential vector of attack.

<?php

$file = $_GET['fileName'];

// Some validation on the name size.
if (strlen($file) > 150) { die('This file name is too long');}

// Validation is not sufficient, and any file may be reached on the system
fopen($filename);

?>

Documentation

See Also

Mixed

A special type that represents any available type. It is equivalent to not explicitly setting the type, though it is now explicitly done.

A mixed type may be also represented by a union of all possible types.

mixed is useful when literally any type should be supported, such as with a cache system. Yet, it is usually recommended to consider reducing the number of possible types by using a common interface or a union type.

<?php

    function cache(string $name, mixed $value) : bool {
        static $cache = [];
        
        $cache[$name] = $value;
        
        return true;
    }

?>

Documentation

See Also

Mixin

A mixin, or class mixin, is a class-level construct that provides a set of methods intended to be incorporated into other classes, without forming a base-class relationship. Unlike inheritance, a mixin does not impose an is-a relationship. Unlike an interface, it supplies concrete implementations. Unlike a trait, as PHP defines it, a mixin is itself an instantiable class or a first-class language entity that is composed through language syntax rather than a use directive inside the class body.

Languages such as Dart, Kotlin via delegation, and Scala via self-types and stackable modifications offer mixins as distinct, class-level features.

PHP does not have mixins. PHP traits are the closest analogue: they provide method reuse without inheritance. However, traits differ from true mixins in several ways:

  • A trait is not a class and cannot be instantiated on its own
  • A trait is composed inside the class definition: it cannot be applied after the fact
  • A trait cannot extend another class; a mixin in some languages can carry its own class hierarchy
  • PHP traits are resolved at compile time; some mixin systems allow run-time composition

PHP interfaces with default implementations as in Java are also a common comparison point, but PHP interfaces carry no implementation at all.

<?php

    // PHP uses traits as the closest equivalent to mixins.
    // They share the intent but differ from class-level mixins.
    
    trait Timestampable {
        private \DateTimeImmutable $createdAt;
    
        public function getCreatedAt(): \DateTimeImmutable {
            return $this->createdAt;
        }
    }
    
    class Article {
        use Timestampable;   // composed here, not applied externally
    }
    
    // A true class-level mixin (as in Dart) would be declared separately
    // and applied without modifying the target class source.

?>

Documentation

See Also

Mobile Application

A mobile application runs on a mobile device such as a smartphone or tablet. PHP is not natively compiled to mobile targets, but it can power the backend API consumed by a mobile frontend written in Swift, Kotlin, React Native, or Flutter. Projects like NativePHP also explore packaging PHP as a mobile app. Mobile apps may be native and compiled for a specific OS, web views wrapped in a native shell, or PWA progressive web apps.

Documentation

See Also

Mock

A mock replaces a code dependency with an object, to make testing easier. Mocks are used when the dependency is difficult to set in a reproducible state: for example, in a rare state, or after a long set up.

Mocks turns the dependency into another piece of code, with total control over its behavior.

On the other hand, mocks have to be coded to replace the dependency, and emulates its behavior as closely as possible: any change to the dependency behavior has to be back-ported.

Mock objects are also called test double.