Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
A list of changes in PHP 7.0+ all on one page

New Stuff in PHP 7.0

  1. Scalar type definitions: they come in two flavours: coercive (default) and strict. The following types for parameters can now be enforced (either coercively or strictly): strings (string), integers (int), floating-point numbers (float), and booleans (bool). They augment the other types introduced in PHP 5: class names, interfaces, array and callable.

    • Typed pass-by-reference Parameters gotcha: Declared types of reference parameters are checked on function entry, but not when the function returns, so after the function had returned, the argument's type may have changed. For example:
    function array_baz(array &$param)
    	$param = 1;
    $var = [];
    array_baz($var); 	// $var is an array at this point
    var_dump($var);  	// $var is now an int with the value 1 at this point 
    array_baz($var); 	// Fatal error: Uncaught TypeError: Argument 1 passed
    					// to array_baz() must be of the type array, int given ...
    • Catching type errors:
    function sum(int $a, int $b) {
    	return $a + $b;
    try {
    	var_dump(sum(1, 2));
    	var_dump(sum(1.5, 2.5));
    } catch (\TypeError $e) {
    	echo 'Error: '.$e->getMessage();
  2. Return type declarations: PHP 7 adds support for return type declarations. Similarly to argument type declarations, return type declarations specify the type of the value that will be returned from a function. The same types are available for return type declarations as are available for argument type declarations.

  3. The null coalescing operator (??) has been added as syntactic sugar for the common case of needing to use a ternary in conjunction with isset(). It returns its first operand if it exists and is not NULL; otherwise it returns its second operand.

    // Fetches the value of $_GET['user'] and returns 'nobody'
    // if it does not exist.
    $username = $_GET['user'] ?? 'nobody';
    // This is equivalent to:
    $username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
  4. The spaceship operator is used for comparing two expressions. It returns -1, 0 or 1 when $a is respectively less than, equal to, or greater than $b. Comparisons are performed according to PHP's usual type comparison rules.

    // Integers
    echo 1 <=> 1; // 0
    echo 1 <=> 2; // -1
    echo 2 <=> 1; // 1
    // Floats
    echo 1.5 <=> 1.5; // 0
    echo 1.5 <=> 2.5; // -1
    echo 2.5 <=> 1.5; // 1
    // Strings
    echo "a" <=> "a"; // 0
    echo "a" <=> "b"; // -1
    echo "b" <=> "a"; // 1
  5. Constant arrays using define()

    define('ANIMALS', ['dog', 'cat', 'bird']);
    echo ANIMALS[1]; // outputs "cat"
  6. Support for anonymous classes has been added via new class. These can be used in place of full class definitions for throwaway objects:

    interface Logger {
    	public function log(string $msg);
    class Application {
    	private $logger;
    	public function getLogger(): Logger {
    		 return $this->logger;
    	public function setLogger(Logger $logger) {
    		 $this->logger = $logger;
    $app = new Application;
    $app->setLogger(new class implements Logger {
    	public function log(string $msg) {
    		echo $msg;
    // The above example will output:
    // object(class@anonymous)#2 (0) { }
  7. Unicode codepoint escape syntax: This takes a Unicode codepoint in hexadecimal form, and outputs that codepoint in UTF-8 to a double-quoted string or a heredoc. Any valid codepoint is accepted, with leading 0's being optional.

    echo "\u{aa}";
    echo "\u{0000aa}";
    echo "\u{9999}";
    // The above example will output:
    // ª
    // ª (same as before but with optional leading 0's)
    // 香
  8. Closure::call(): is a more performant, shorthand way of temporarily binding an object scope to a closure and invoking it.

    class A {private $x = 1;}
    // Pre PHP 7 code
    $getX = function() {return $this->x;};
    $getXCB = $getX->bindTo(new A, 'A'); // intermediate closure
    echo $getXCB();
    // PHP 7+ code
    $getX = function() {return $this->x;};
    echo $getX->call(new A);
    // The above example will output:
    // 1
    // 1
  9. Filtered unserialize(): This feature seeks to provide better security when unserializing objects on untrusted data. It prevents possible code injections by enabling the developer to whitelist classes that can be unserialized.

    // converts all objects into __PHP_Incomplete_Class object
    $data = unserialize($foo, ["allowed_classes" => false]);
    // converts all objects into __PHP_Incomplete_Class object except those of MyClass and MyClass2
    $data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]]);
    // default behaviour (same as omitting the second argument) that accepts all classes
    $data = unserialize($foo, ["allowed_classes" => true]);
  10. IntlChar: The new IntlChar class seeks to expose additional ICU functionality. The class itself defines a number of static methods and constants that can be used to manipulate unicode characters. In order to use this class, the Intl extension must be installed.

    printf('%x', IntlChar::CODEPOINT_MAX);
    echo IntlChar::charName('@');
    // The above example will output:
    // 10ffff
    // bool(true)
  11. Expectations are a backwards compatible enhancement to the older assert() function. They allow for zero-cost assertions in production code, and provide the ability to throw custom exceptions when the assertion fails. While the old API continues to be maintained for compatibility, assert() is now a language construct, allowing the first parameter to be an expression rather than just a string to be evaluated or a boolean value to be tested. Full details on this feature, including how to configure it in both development and production environments, can be found in the expectations section of the assert() reference.

    ini_set('assert.exception', 1);
    class CustomError extends AssertionError {}
    assert(false, new CustomError('Some error message'));
    // The above example will output:
    //	Fatal error: Uncaught CustomError: Some error message
  12. Group use declarations: Classes, functions and constants being imported from the same namespace can now be grouped together in a single use statement.

    // Pre PHP 7 code
    use some\namespace\ClassA;
    use some\namespace\ClassB;
    use some\namespace\ClassC as C;
    use function some\namespace\fn_a;
    use function some\namespace\fn_b;
    use function some\namespace\fn_c;
    use const some\namespace\ConstA;
    use const some\namespace\ConstB;
    use const some\namespace\ConstC;
    // PHP 7+ code
    use some\namespace\{ClassA, ClassB, ClassC as C};
    use function some\namespace\{fn_a, fn_b, fn_c};
    use const some\namespace\{ConstA, ConstB, ConstC};
  13. Generator Return Expressions: This feature builds upon the generator functionality introduced into PHP 5.5. It enables for a return statement to be used within a generator to enable for a final expression to be returned (return by reference is not allowed). This value can be fetched using the new Generator::getReturn() method, which may only be used once the generator has finished yielding values. Being able to explicitly return a final value from a generator is a handy ability to have. This is because it enables for a final value to be returned by a generator (from perhaps some form of coroutine computation) that can be specifically handled by the client code executing the generator. This is far simpler than forcing the client code to firstly check whether the final value has been yielded, and then if so, to handle that value specifically.

    $gen = (function() {
    	yield 1;
    	yield 2;
    	return 3;
    foreach ($gen as $val) {
    	echo $val, PHP_EOL;
    echo $gen->getReturn(), PHP_EOL;
    // The above example will output:
    // 1
    // 2
    // 3
  14. Generator delegation: Generators can now delegate to another generator, Traversable object or array automatically, without needing to write boilerplate in the outermost generator by using the yield from construct.

    function gen()
    	yield 1;
    	yield 2;
    	yield from gen2();
    function gen2()
    	yield 3;
    	yield 4;
    foreach (gen() as $val)
    	echo $val, PHP_EOL;
    // The above example will output:
    // 1
    // 2
    // 3
    // 4
  15. Integer division with intdiv(). The new intdiv() function performs an integer division of its operands and returns it.

    var_dump(intdiv(10, 3));
    // The above example will output:
    // int(3)
  16. Session options: session_start() now accepts an array of options that override the session configuration directives normally set in php.ini. These options have also been expanded to support session.lazy_write, which is on by default and causes PHP to only overwrite any session file if the session data has changed, and read_and_close, which is an option that can only be passed to session_start() to indicate that the session data should be read and then the session should immediately be closed unchanged. For example, to set session.cache_limiter to private and immediately close the session after reading it:

        'cache_limiter' => 'private',
        'read_and_close' => true,
  17. preg_replace_callback_array(): The new preg_replace_callback_array() function enables code to be written more cleanly when using the preg_replace_callback() function. Prior to PHP 7, callbacks that needed to be executed per regular expression required the callback function to be polluted with lots of branching. Now, callbacks can be registered to each regular expression using an associative array, where the key is a regular expression and the value is a callback.

  18. Cryptographically Secure Pseudo-Random Number Generator (CSPRNG) Functions: Two new functions have been added to generate cryptographically secure integers and strings in a cross platform way: random_bytes() and random_int().

  19. list() can always unpack objects implementing ArrayAccess. Previously, list() was not guaranteed to operate correctly with objects implementing ArrayAccess. This has been fixed.

  20. Class member access on cloning has been added, e.g. (clone $foo)->bar()

Backward incompatible changes in PHP 7.0

Deprecated features in PHP 7.0

Changed functions in PHP 7.0

New functions, Classes & Interfaces & Global constants in PHP 7.0

Changes in SAPI Modules, Removed Extensions and SAPIs & Other Changes in PHP 7.0

New Stuff in PHP 7.1

  1. Nullable types: Type declarations for parameters and return values can now be marked as nullable by prefixing the type name with a question mark. This signifies that as well as the specified type, NULL can be passed as an argument, or returned as a value, respectively.
    function testReturn(): ?string {
    	return 'elePHPant';
    function testReturn(): ?string {
    	return null;
    function test(?string $name) {
    // The above example will output:
    //		string(10) "elePHPant"
    //		NULL
    //		string(10) "elePHPant"
    //		NULL
    //		Uncaught Error: Too few arguments to function test(), 0 passed in...
  2. Void functions: A void return type has been introduced. Functions declared with void as their return type must either omit their return statement altogether, or use an empty return statement. NULL is not a valid return value for a void function. Attempting to use a void function's return value simply evaluates to NULL, with no warnings emitted. The reason for this is because warnings would implicate the use of generic higher order functions.
    function swap(&$left, &$right): void {
    	if ($left === $right) { return; }
    	$tmp = $left; $left = $right; $right = $tmp;
    $a = 1; $b = 2;
    var_dump(swap($a, $b), $a, $b);
    // The above example will output:
    //		null
    //		int(2)
    //		int(1)
  3. Symmetric array destructuring: The shorthand array syntax ([]) may now be used to destructure arrays for assignments (including within foreach), as an alternative to the existing list() syntax, which is still supported.
    $data = [ [1, 'Tom'], [2, 'Fred'], ];
    // list() style
    list($id1, $name1) = $data[0];
    // [] style
    [$id1, $name1] = $data[0];
    // list() style
    foreach ($data as list($id, $name)) {
    	// logic here with $id and $name
    // [] style
    foreach ($data as [$id, $name]) {
    	// logic here with $id and $name
  4. Class constant visibility: Support for specifying the visibility of class constants has been added.
    class ConstDemo
    	const PUBLIC_CONST_A = 1;
    	public const PUBLIC_CONST_B = 2;
    	protected const PROTECTED_CONST = 3;
    	private const PRIVATE_CONST = 4;
  5. iterable pseudo-type: A new pseudo-type (similar to callable) called iterable has been introduced. It may be used in parameter and return types, where it accepts either arrays or objects that implement the Traversable interface. With respect to subtyping, parameter types of child classes may broaden a parent's declaration of array or Traversable to iterable. With return types, child classes may narrow a parent's return type of iterable to array or an object that implements Traversable.
    function iterator(iterable $iter) {
    	foreach ($iter as $val) { // }
  6. Multi catch exception handling: Multiple exceptions per catch block may now be specified using the pipe character (|). This is useful for when different exceptions from different class hierarchies are handled the same.
    try {
    	// some code
    } catch (FirstException | SecondException $e) {
    	// handle first and second exceptions
  7. Support for keys in list(): You can now specify keys in list(), or its new shorthand [] syntax. This enables destructuring of arrays with non-integer or non-sequential keys.
    $data = [
    	["id" => 1, "name" => 'Tom'],
    	["id" => 2, "name" => 'Fred'],
    // list() style
    list("id" => $id1, "name" => $name1) = $data[0];
    // [] style
    ["id" => $id1, "name" => $name1] = $data[0];
    // list() style
    foreach ($data as list("id" => $id, "name" => $name)) {
    	// logic here with $id and $name
    // [] style
    foreach ($data as ["id" => $id, "name" => $name]) {
    	// logic here with $id and $name
  8. Support for negative string offsets: has been added to the string manipulation functions accepting offsets, as well as to string indexing with [] or {}. In such cases, a negative offset is interpreted as being an offset from the end of the string.
    var_dump(strpos("aabbcc", "b", -3));
    // The above example will output:
    //		string (1) "e"
    //		int(3)
    // Negative string and array offsets are now also supported in the 
    // simple variable parsing syntax inside of strings.
    $string = 'bar';
    echo "The last character of '$string' is '$string[-1]'.\n";
    // The above example will output:
    //		The last character of 'bar' is 'r'.
  9. Support for AEAD in ext/openssl: Support for AEAD (modes GCM and CCM) have been added by extending the openssl_encrypt() and openssl_decrypt() functions with additional parameters.
  10. Convert callables to Closures with Closure::fromCallable(): A new static method has been introduced to the Closure class to allow for callables to be easily converted into Closure objects.
    class Test {
    	public function exposeFunction() {
    		return Closure::fromCallable([$this, 'privateFunction']);
    	private function privateFunction($param) {
    $privFunc = (new Test)->exposeFunction();
    $privFunc('some value');
    // The above example will output:
    //		string(10) "some value"
  11. Asynchronous signal handling: A new function called pcntl_async_signals() has been introduced to enable asynchronous signal handling without using ticks (which introduce a lot of overhead).
    pcntl_async_signals(true); // turn on async signals
    pcntl_signal(SIGHUP, function($sig){ echo "SIGHUP\n"; });
    posix_kill(posix_getpid(), SIGHUP);
    // The above example will output:
    // 		SIGHUP
  12. HTTP/2 server push support in ext/curl: Support for server push has been added to the CURL extension (requires version 7.46 and above). This can be leveraged through the curl_multi_setopt() function with the new CURLMOPT_PUSHFUNCTION constant. The constants CURL_PUSH_OK and CURL_PUSH_DENY have also been added so that the execution of the server push callback can either be approved or denied.
  13. Stream Context Options: The tcp_nodelay stream context option has been added.

New functions, Classes & Interfaces & Global constants in PHP 7.1

Backward incompatible changes in PHP 7.1

Deprecated features in PHP 7.1

Changed functions in PHP 7.1

Other changes in PHP 7.1

Windows Support in PHP 7.1

New Stuff in PHP 7.2

  1. New object type: A new type, object, has been introduced that can be used for (contravariant) parameter typing and (covariant) return typing of any objects.
    function test(object $obj) : object {
    	return new SplQueue();
    test(new StdClass());
  2. Extension loading by name: Shared extensions no longer require their file extension (.so for Unix or .dll for Windows) to be specified. This is enabled in the php.ini file, as well as in the dl() function.
  3. Abstract method overriding: Abstract methods can now be overridden when an abstract class extends another abstract class.
    abstract class A {
    	abstract function test(string $s);
    abstract class B extends A {
    	// overridden - still maintaining contravariance for parameters and covariance for return
    	abstract function test($s) : int;
  4. Sodium is now a core extension: The modern Sodium cryptography library has now become a core extension in PHP. For a complete function reference, see the Sodium chapter.
  5. Password hashing with Argon2: Argon2 has been added to the password hashing API, where the following constants have been exposed:
  6. Extended string types for PDO: PDO's string type has been extended to support the national character type when emulating prepares. These constants are utilised by bitwise OR'ing them with PDO::PARAM_STR. This has been done with the following constants:
    $db->quote('über', PDO::PARAM_STR | PDO::PARAM_STR_NATL);
  7. Additional emulated prepares debugging information for PDO: The PDOStatement::debugDumpParams() method has been updated to include the SQL being sent to the DB, where the full, raw query (including the replaced placeholders with their bounded values) will be shown. This has been added to aid with debugging emulated prepares (and so it will only be available when emulated prepares are turned on).
  8. Support for extended operations in LDAP: Support for EXOP has been added to the LDAP extension. This has been done by exposing the following functions and constants:
    • ldap_parse_exop()
    • ldap_exop()
    • ldap_exop_passwd()
    • ldap_exop_whoami()
  9. Address Information additions to the Sockets extension: The sockets extension now has the ability to lookup address information, as well as connect to it, bind to it, and explain it. The following four functions have been added for this:
    • socket_addrinfo_lookup()
    • socket_addrinfo_connect()
    • socket_addrinfo_bind()
    • socket_addrinfo_explain()
  10. Parameter type widening: Parameter types from overridden methods and from interface implementations may now be omitted. This is still in compliance with LSP, since parameters types are contravariant.
    interface A {
    	public function Test(array $input);
    class B implements A {
    	public function Test($input){} // type omitted for $input
  11. Allow a trailing comma for grouped namespaces: A trailing comma can now be added to the group-use syntax introduced in PHP 7.0.
    use Foo\Bar\{ Foo, Bar, Baz, };
  12. proc_nice() support on Windows: The proc_nice() function is now supported on Windows.
  13. pack() and unpack() endian support: The pack() and unpack() functions now support float and double in both little and big endian.
  14. Enhancements to the EXIF extension: The EXIF extension has been updated to support a much larger range of formats. This means that their format specific tags are now properly translated when parsing images with the exif_read_data() function. The EXIF functions exif_read_data() and exif_thumbnail() now support passing streams as their first argument. The following new formats are now supported:
    • Samsung
    • DJI
    • Panasonic
    • Sony
    • Pentax
    • Minolta
    • Sigma/Foveon
    • AGFA
    • Kyocera
    • Ricoh
    • Epson
  15. New features in PCRE: The J modifier for setting PCRE_DUPNAMES has been added.
  16. SQLite3 allows writing BLOBs: SQLite3::openBlob() now allows to open BLOB fields in write mode; formerly only read mode was supported.
  17. Oracle OCI8 Transparent Application Failover Callbacks: Support for Oracle Database Transparent Application Failover (TAF) callbacks has been added. TAF allows PHP OCI8 applications to automatically reconnect to a preconfigured database when a connection is broken. The new TAF callback support allows PHP applications to monitor and control reconnection during failover.
  18. Enhancements to the ZIP extension: Read and write support for encrypted archives has been added (requires libzip 1.2.0). The ZipArchive class now implements the Countable interface. The zip:// stream now accepts a 'password' context option.

New functions, Classes & Interfaces & Global constants in PHP 7.2

Backward incompatible changes in PHP 7.2

Deprecated features in PHP 7.2

Other changes in PHP 7.2

New Stuff in PHP 7.3

  1. More Flexible Heredoc and Nowdoc Syntax: The closing marker for doc strings is no longer required to be followed by a semicolon or newline. Additionally the closing marker may be indented, in which case the indentation will be stripped from all lines in the doc string.
  2. Array Destructuring supports Reference Assignments: Array destructuring now supports reference assignments using the syntax [&$a, [$b, &$c]] = $d. The same is also supported for list().
  3. Instanceof Operator accepts Literals: instanceof now allows literals as the first operand, in which case the result is always FALSE.
  4. CompileError Exception instead of some Compilation Errors: A new CompileError exception has been added, from which ParseError inherits. A small number of compilation errors will now throw a CompileError instead of generating a fatal error. Currently this only affects compilation errors that may be thrown by token_get_all() in TOKEN_PARSE mode, but more errors may be converted in the future.
  5. Trailing Commas are allowed in Calls: Trailing commas in function and method calls are now allowed.
  6. Argon2id Support: The --with-password-argon2[=dir] configure argument now provides support for both Argon2i and Argon2id hashes in the password_hash(), password_verify(), password_get_info(), and password_needs_rehash() functions. Passwords may be hashed and verified using the PASSWORD_ARGON2ID constant. Support for both Argon2i and Argon2id in the password_*() functions now requires PHP be linked against libargon2 reference library ≥ 20161029.
  7. FastCGI Process Manager: New options have been added to customize the FPM logging:
    • log_limit: This global option can be used for setting the log limit for the logged line which allows to log messages longer than 1024 characters without wrapping. It also fixes various wrapping issues.
    • log_buffering: This global option allows an experimental logging without extra buffering.
    • decorate_workers_output: This pool option allows to disable the output decoration for workers output when catch_workers_output is enabled.
  8. BC Math Functions: bcscale() can now also be used as getter to retrieve the current scale in use.
  9. Lightweight Directory Access Protocol: Full support for LDAP Controls has been added to the LDAP querying functions and ldap_parse_result():
    • A $serverctrls parameter to send controls to the server in ldap_add(), ldap_mod_replace(), ldap_mod_add(), ldap_mod_del(), ldap_rename(), ldap_compare(), ldap_delete(), ldap_modify_batch(), ldap_search(), ldap_list() and ldap_read() has been added.
    • The out parameter $serverctrls to get controls from the server in ldap_parse_result() has been added.
    • Support for LDAP_OPT_SERVER_CONTROLS and LDAP_OPT_CLIENT_CONTROLS in ldap_get_option() and ldap_set_option() has been fixed.
  10. Full Case-Mapping and Case-Folding Support: Support for full case-mapping and case-folding has been added. Unlike simple case-mapping, full case-mapping may change the length of the string. For example:
    // Produces STRAßE on PHP 7.2
    // Produces STRASSE on PHP 7.3
    The different casing mapping and folding modes are available through mb_convert_case():
    MB_CASE_LOWER (used by mb_strtolower())
    MB_CASE_UPPER (used by mb_strtoupper())
    MB_CASE_FOLD_SIMPLE (used by case-insensitive operations)
    Only unconditional, language agnostic full case-mapping is performed.
  11. Case-Insensitive String Operations use Case-Folding: Case-insensitive string operations now use case-folding instead of case- mapping during comparisons. This means that more characters will be considered (case insensitively) equal now.
  12. mb_convert_case() with MB_CASE_TITLE now performs title-case conversion based on the Cased and CaseIgnorable derived Unicode properties. In particular this also improves handling of quotes and apostrophes.
  13. Unicode 11 Support: The Multibyte String data tables have been updated for Unicode 11.
  14. Long String Support: The Multibyte String Functions now correctly support strings larger than 2GB.
  15. Performance Improvements: Performance of the Multibyte String extension has been significantly improved across the board. The largest improvements are in case conversion functions.
  16. Named Captures Support: The mb_ereg_* functions now support named captures. Matching functions like mb_ereg() will now return named captures both using their group number and their name, similar to PCRE:
    mb_ereg('(?<word>\w+)', '国', $matches);
    // => [0 => "国", 1 => "国", "word" => "国"];
    // Additionally, mb_ereg_replace() now supports the \k<> and \k'' 
    // notations to reference named captures in the replacement string:
    mb_ereg_replace('\s*(?<word>\w+)\s*', "_\k<word>_\k'word'_", ' foo ');
    // => "_foo_foo_"
    // \k<> and \k'' can also be used for numbered references, 
    // which also works with group numbers greater than 9.
  17. Readline: Support for the completion_append_character and completion_suppress_append options has been added to readline_info(). These options are only available if PHP is linked against libreadline (rather than libedit).

New functions, Classes & Interfaces & Global constants in PHP 7.3

  • (Most Notable: array_key_first(), array_key_last() & is_countable())
     // Correct polyfill (one that doesn't make copies of arrays, and that doesn't make use of the IAP) is:
     if( !function_exists('array_key_first') ) {
         function array_key_first(array $array) {
             if( $array === [] ) { return NULL; }
             foreach($array as $key => $_) { return $key; }
     if( !function_exists('array_key_last') ) {
         function array_key_last(array $array) {
             if( $array === [] ) { return null; }
             // the last 2 args to array_slice are crucial
             return array_key_first(array_slice($array, -1, null, true));

Backward incompatible changes in PHP 7.3

Deprecated features in PHP 7.3

Other changes in PHP 7.3

Windows Support in PHP 7.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.