Skip to content

Latest commit

 

History

History
446 lines (331 loc) · 15.9 KB

php71-reference.md

File metadata and controls

446 lines (331 loc) · 15.9 KB

PHP 7.1

PHP 7.1 was released towards the end of 2016, and with it came some interesting features and changes (outlined below).

Features

Changes

Features

Nullable Types

Types can now be made nullable, enabling for either the specified type or null to be passed to or returned from a function. The syntax chosen is the same used by Hack, where a question mark is used to prefix a type to denote it as nullable.

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

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

Invoking test() without any arguments causes an Error exception to be thrown (see Throw on Passing too few Function Arguments). This is because nullable types are distinctly different from default parameters, where they still require an argument to be passed.

With respect to subtyping, the following rules hold true:

  • Parameter types of subclasses may add type nullability
  • Return types of subclasses may remove type nullability
interface ParentClass
{
    function test(string $param) : ?string;
}

interface ChildClass2 extends ParentClass
{
    // parameter type made nullable
    // return type made un-nullable
    function test(?string $param) : string;
}

RFC: Nullable Types

Void Functions

A void return type has been introduced to amalgamate the other return types introduced into PHP 7. Functions declared with void as their return type can 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;
}

$a = 1;
$b = 2;
var_dump(swap($a, $b), $a, $b); // null, int(2), int(1)

Attempting to use a void function's return value simply evaluates to null, with no warnings are emitted. The reason for this is because warnings would implicate the use of generic higher order functions.

RFC: Void Return Type

Symmetric Array Destructuring on Assignment

The shorthand array syntax ([]) may now be used to destructure arrays for assignments (including within foreach). This pattern matching ability enables for values to be more easily extracted from arrays.

$pdo = new PDO('mysql:host=...;dbname=...', '...', '...');
$stmt = $pdo->query('SELECT id, val FROM ...');

while (['id' => $id, 'val' => $val] = $stmt->fetch(PDO::FETCH_ASSOC)) {
    // logic here with $id and $val
}

RFC: Square bracket syntax for array destructuring assignment

Class Constant Visibility

Support for specifying the visibility of class constants has been added.

class Something
{
    const PUBLIC_CONST_A = 1;
    public const PUBLIC_CONST_B = 2;
    protected const PROTECTED_CONST = 3;
    private const PRIVATE_CONST = 4;
}

RFC: Class Constant Visibility

iterable Pseudo-Type

A new pseudo-type (similar to callable) - 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 object (provided object implements Traversable). With return types, child classes may widen a parent's return type of array or object to iterable.

This type will typically be used for type checking parameter or return values that will be used either in a foreach loop or yield from statement.

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

A new function, is_iterable has also been introduced to match the other is_ functions. It effectively performs the following check: is_array($var) || $var instanceof Traversable.

RFC: Iterable

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 (AnException | AnotherException $e) {
    // handle exceptions
}

RFC: Catching Multiple Exception Types

Support for Keys in list()

The list() language construct now enables for keys to be specified inside of it. This means that it can now destructure any type of arrays (like with the new symmetric array destructuring syntax).

$pdo = new PDO('mysql:host=...;dbname=...', '...', '...');
$stmt = $pdo->query('SELECT id, val FROM ...');

while (list('id' => $id, 'val' => $val) = $stmt->fetch(PDO::FETCH_ASSOC)) {
    // logic here with $id and $val
}

RFC: Allow specifying keys in list()

Support for Negative String Offsets

Ubiquituous support for negative string offsets has been added. This affects a number of built-in functions, as well as the array dereferencing operator ([]).

var_dump("abcdef"[-2]); // string (1)"e"
var_dump(strpos("aabbcc", "b", -3)); // int(3)

RFC: Generalize support of negative string offsets

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.

RFC: OpenSSL AEAD support

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. This is because Closures are more performant to invoke than other callables, and allow for out-of-scope methods to be executed in other contexts.

class Test
{
    public function exposeFunction()
    {
        return Closure::fromCallable([$this, 'privateFunction']);
    }

    private function privateFunction($param)
    {
        return $param;
    }
}

$privFunc = (new Test)->exposeFunction();
$privFunc('some value');

RFC: Closure from callable function

Asynchronous Signal Handling with pcntl_async_signals()

Prior to PHP 7.1, PCNTL signal handling could be done synchronously via pcntl_signal_dispatch or asynchronously via ticks. Now, a new function - pcntl_async_signals([bool $async = false]) - has been introduced to switch asynchronous signal handling either on or off, without having to use 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);

RFC: Asynchronous Signal Handling (without TICKs)

Additions to ext/curl

Support for HTTP/2 Server Push

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.

RFC: ext/curl HTTP/2 Server Push Support

Better Error Retrieval

Three new functions have been introduced to enable for errors related to multi and share handles to be retrieved.

int curl_multi_errno(resource $mh);
int curl_share_errno(resource $rh);
string curl_share_strerror(int $errno);

RFC: Add curl_multi_errno(), curl_share_errno() and curl_share_strerror()

Changes

Apprise on Arithmetic with Invalid Strings

New E_WARNING and E_NOTICE errors have been introduced when invalid strings are coerced using the arithmetic operators (+ - * / ** % << >> | & ^). An E_NOTICE is emitted when the string can be partially converted to a sensical numeric, and an E_WARNING is emitted when the string cannot be converted at all to a sensical numeric.

'1b' + 'something';

// results in a notice for '1b' and a warning for 'something':
// Notice: A non well formed numeric value encountered in %s on line %d
// Warning: A non-numeric value encountered in %s on line %d

RFC: Warn about invalid strings in arithmetic

Deprecation of ext/mcrypt

The mcrypt extension has been abandonware for quite some time now (nearly a decade). It was also fairly complex to use, causing many to implement it incorrectly (and subsequently, insecurely). It has therefore been deprecated in favour of OpenSSL, where it will be removed from the core and into PECL in PHP 7.2.

RFC: Deprecate (then Remove) Mcrypt

Deprecation of mb_ereg(i)_replace() Eval Option

The e pattern modifier has been deprecated for the mb_ereg_replace() and mb_eregi_replace() functions. This was already done in PHP 5.5 for preg_replace(), but it was overlooked for the mb_ereg functions.

RFC: Deprecate mb_ereg_replace eval option

Warn on Octal Overflow

Previously, 3 octit octals could overflow without warning the programmer. Now, an E_WARNING will be emitted on such overflows (with the previous overflow behaviour remaining the same).

var_dump("\500");

// Warning: Octal escape sequence overflow \500 is greater than \377 in %s on line %d
// string(1) "@"

Forbid Dynamic Calls to Scope Introspection Functions

Dynamic calls for certain functions have been forbidden. These functions either inspect or modify another scope, and present with them ambiguous and unreliable behaviour. The functions are as follows:

assert() - with a string as the first argument
compact()
extract()
func_get_args()
func_get_arg()
func_num_args()
get_defined_vars()
mb_parse_str() - with one arg
parse_str() - with one arg

For example, the following will not work:

(function () {
    'func_num_args'();
})();

// Warning: Cannot call func_num_args() dynamically in %s on line %d

RFC: Forbid dynamic calls to scope introspection functions

Throw on Passing too few Function Arguments

An Error exception will now be thrown when a user-defined function (not an internal function) is passed too few arguments. This new behaviour aims to help expose potentially buggy code.

function test($param){}
test(); // Uncaught Error: Too few arguments to function test(), 0 passed in %s on line %d and exactly 1 expected in %s:%d

RFC: Replace "Missing argument" warning with "Too few arguments" exception

Inconsistency Fixes to $this

Whilst $this is considered a special variable in PHP, it lacked proper checks to ensure it wasn't used as a variable name or reassigned. This has now been rectified to ensure that $this cannot be a user-defined variable, reassigned to a different value, or be globalised.

RFC: Fix inconsistent behavior of $this variable

Session ID Generation without Hashing

Session IDs will no longer be hashed upon generation. This was an unnecessary operation that slowed down ID generation. With this change brings about the removal of the following four ini settings:

And the addition of the following two ini settings:

  • session.sid_length - defines the length of the session ID, defaulting to 32 characters for backwards compatibility)
  • session.sid_bits_per_character - defines the number of bits to be stored per character (i.e. increases the range of characters that can be used in the session ID), defaulting to 4 for backwards compatibility

RFC: Session ID without hashing

RNG Fixes and Changes

Fix mt_rand() Implementation

mt_rand() will now default to using the fixed version of the Mersenne Twister algorithm, with the ability to preserve the old (incorrect) implementation via an additional optional second parameter to mt_srand().

RFC: RNG fixes and changes: Fix mt_rand() implementation

Alias rand() to mt_rand()

rand() has little use nowadays given how weak its RNG is, and so it will now be aliased to mt_rand() (since dropping the function all together would cause too much of a BC break). This will improve the quality of output, including no longer having system-dependent output, but rather seed-dependent output.

RFC: RNG fixes and changes: Alias rand() to mt_rand()

(The RFC has two further changes, but they will have no practical impact to PHP developers.)