Skip to content

Instantly share code, notes, and snippets.

@Najki
Last active November 17, 2018 16:03
Show Gist options
  • Save Najki/13a93087bffcd883baea to your computer and use it in GitHub Desktop.
Save Najki/13a93087bffcd883baea to your computer and use it in GitHub Desktop.
New features of PHP 5.5, 5.6, 7.0 and 7.1

New PHP features

  1. PHP 5.5
  2. PHP 5.6
  3. PHP 7.0
  4. PHP 7.1

PHP 5.5

Generators

Link Note that an array is never created or returned, which saves memory.

foreach (xrange(1, 9, 2) as $number) {
    echo "$number "; // 1 3 5 7 9
}

finally keyword added

Link try-catch blocks now support a finally block for code that should be run regardless of whether an exception has been thrown or not.

New password hashing API

Link A new password hashing API that makes it easier to securely hash and manage passwords using the same underlying library as crypt() in PHP has been added. See the documentation for password_hash() for more detail.

foreach now supports list()

Link The foreach control structure now supports unpacking nested arrays into separate variables via the list() construct. For example:

$array = [
    [1, 2],
    [3, 4],
];

foreach ($array as list($a, $b)) {
    echo "A: $a; B: $b\n";
}

empty() supports arbitrary expressions

Link Passing an arbitrary expression instead of a variable to empty() is now supported. For example:

function always_false() {
    return false;
}

if (empty(always_false())) {
    echo "This will be printed.\n";
}

if (empty(true)) {
    echo "This will not be printed.\n";
}

array and string literal dereferencing

Link Array and string literals can now be dereferenced directly to access individual elements and characters:

echo 'Array dereferencing: ';
echo [1, 2, 3][0];
echo "\n";

echo 'String dereferencing: ';
echo 'PHP'[0];
echo "\n";

Class name resolution via ::class

Link It is possible to use ClassName::class to get a fully qualified name of class ClassName. For example:

namespace Name\Space;
class ClassName {}

echo ClassName::class;

OPcache extension added

Link The Zend Optimiser+ opcode cache has been added to PHP as the new OPcache extension. OPcache improves PHP performance by storing precompiled script bytecode in shared memory, thereby removing the need for PHP to load and parse scripts on each request. See the installation instructions for more detail on enabling and using OPcache.

PHP 5.6

Constant expressions

Link It is now possible to provide a scalar expression involving numeric and string literals and/or constants in contexts where PHP previously expected a static value, such as constant and property declarations and default function arguments.

const ONE = 1;
const TWO = ONE * 2;

class C {
    const THREE = TWO + 1;
    const ONE_THIRD = ONE / self::THREE;
    const SENTENCE = 'The value of THREE is '.self::THREE;

    public function f($a = ONE + self::THREE) {
        return $a;
    }
}

echo (new C)->f()."\n";
echo C::SENTENCE;

It is also now possible to define a constant array using the const keyword:

const ARR = ['a', 'b'];
echo ARR[0];

Variadic functions via ...

Link Variadic functions can now be implemented using the ... operator, instead of relying on func_get_args().

function f($req, $opt = null, ...$params) {
    // $params is an array containing the remaining arguments.
    printf('$req: %d; $opt: %d; number of params: %d'."\n",
           $req, $opt, count($params));
}

Argument unpacking via ...

Link Arrays and Traversable objects can be unpacked into argument lists when calling functions by using the ... operator. This is also known as the splat operator in other languages, including Ruby.

function add($a, $b, $c) {
    return $a + $b + $c;
}

$operators = [2, 3];
echo add(1, ...$operators);

use function and use const

Link The use operator has been extended to support importing functions and constants in addition to classes. This is achieved via the use function and use const constructs, respectively.

namespace Name\Space {
    const FOO = 42;
    function f() { echo __FUNCTION__."\n"; }
}

namespace {
    use const Name\Space\FOO;
    use function Name\Space\f;

    echo FOO."\n";
    f();
}

phpdbg

Link PHP now includes an interactive debugger called phpdbg implemented as a SAPI module. For more information, please visit the phpdbg documentation.

php://input is reusable

Link php://input may now be reopened and read as many times as required. This work has also resulted in a major reduction in the amount of memory required to deal with POST data.

Large file uploads

Link Files larger than 2 gigabytes in size are now accepted.

hash_equals() for timing attack safe string comparison

Link The hash_equals() function has been added to compare two strings in constant time. This should be used to mitigate timing attacks; for instance, when testing crypt() password hashes (assuming that you are unable to use password_hash() and password_verify(), which aren't susceptible to timing attacks).

$expected  = crypt('12345', '$2a$07$usesomesillystringforsalt$');
$correct   = crypt('12345', '$2a$07$usesomesillystringforsalt$');
$incorrect = crypt('1234',  '$2a$07$usesomesillystringforsalt$');

var_dump(hash_equals($expected, $correct)); // bool(true)
var_dump(hash_equals($expected, $incorrect)); // bool(false)

__debugInfo()

Link The __debugInfo() magic method has been added to allow objects to change the properties and values that are shown when the object is output using var_dump().

class C {
    private $prop;

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

    public function __debugInfo() {
        return [
            'propSquared' => $this->prop ** 2,
        ];
    }
}

var_dump(new C(42));

Output

object(C)#1 (1) {
  ["propSquared"]=>
  int(1764)
}

PHP 7.0

Scalar type declarations

Link Scalar type declarations 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.

// Coercive mode
function sumOfInts(int ...$ints)
{
    return array_sum($ints);
}

var_dump(sumOfInts(2, '3', 4.1));

Output

int(9)

To enable strict mode, a single declare directive must be placed at the top of the file. This means that the strictness of typing for scalars is configured on a per-file basis. This directive not only affects the type declarations of parameters, but also a function's return type (see return type declarations, built-in PHP functions, and functions from loaded extensions.

Full documentation and examples of scalar type declarations can be found in the type declaration reference.

Return type declarations

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

function arraysSum(array ...$arrays): array
{
    return array_map(function(array $array): int {
        return array_sum($array);
    }, $arrays);
}

print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));

The above example will output:

Array
(
    [0] => 6
    [1] => 15
    [2] => 24
)

Null coalescing operator

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

// Coalescing can be chained: this will return the first
// defined value out of $_GET['user'], $_POST['user'], and
// 'nobody'.
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';

Spaceship operator

Link 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

Constant arrays using define()

Link Array constants can now be defined with define(). In PHP 5.6, they could only be defined with const.

define('ANIMALS', [
    'dog',
    'cat',
    'bird'
]);

echo ANIMALS[1]; // outputs "cat"

Anonymous classes

Link 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;
    }
});

var_dump($app->getLogger());

Output

object(class@anonymous)#2 (0) {
}

Unicode codepoint escape syntax

Link 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}";

Output

ª
ª (same as before but with optional leading 0's)
香

Closure::call()

Link 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
$getXCB = function() {return $this->x;};
$getX = $getXCB->bindTo(new A, 'A'); // intermediate closure
echo $getX();

// PHP 7+ code
$getX = function() {return $this->x;};
echo $getX->call(new A);

Output

1
1

Filtered unserialize()

Link 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]);

Group use declarations

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

Generator Return Expressions

Link 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 finishing yielding values.

$gen = (function() {
    yield 1;
    yield 2;

    return 3;
})();

foreach ($gen as $val) {
    echo $val, PHP_EOL;
}

echo $gen->getReturn(), PHP_EOL;

Output

1
2
3

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.

Generator delegation

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

Output

1
2
3
4

Integer division with intdiv()

Link The new intdiv() function performs an integer division of its operands and returns it.

var_dump(intdiv(10, 3)); // int(3)

Session options

Link 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:

session_start([
    'cache_limiter' => 'private',
    'read_and_close' => true,
]);

preg_replace_callback_array()

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

CSPRNG Functions

Link Two new functions have been added to generate cryptographically secure integers and strings in a cross platform way: random_bytes() and random_int().

list() can always unpack objects implementing ArrayAccess

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

PHP 7.1

Nullable types

Link 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';
}

var_dump(testReturn()); // elePHPant

function testReturn(): ?string
{
    return null;
}

var_dump(testReturn()); // NULL

function test(?string $name)
{
    var_dump($name);
}

test('elePHPant'); // elePHPant
test(null); // NULL
test(); // Uncaught Error: Too few arguments to function test(), 0 passed in...

Void functions

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

function swap(&$left, &$right) : void
{
    if ($left === $right) {
        return;
    }

    $tmp = $left;
    $left = $right;
    $right = $tmp;
}

Symmetric array destructuring

Link 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
}

Class constant visibility

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

iterable pseudo-type

Link 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 narrow a parent's iterable type to either array or an object (that implements Traversable). With return types, child classes may widen a parent's return type of array or an object to iterable.

function iterator(iterable $iter)
{
    foreach ($iter as $val) {
        //
    }
}

Multi catch exception handling

Link 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
}

Support for keys in list()

Link 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
}

Asynchronous signal handling

Link 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);

Output:

SIGHUP

HTTP/2 server push support in ext/curl

Link 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_PUST_OK and CURL_PUSH_DENY have also been added so that the execution of the server push callback can either be approved or denied.

Catching Multiple Exception Types

try {
    $user->payMonth($month);
} catch (PaidMonthException | UserSuspendedException $ex) {
    // ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment