New features to consider when updating from PHP7.0 to PHP7.3

PHP 7.0

PHP7.0 new features

1. Combination comparison character (<=>)

Can’t compare

var_dump('PHP' <=> 'Node'); // int(1)
var_dump(123 <=> 456); // int(-1)
var_dump(['a', 'b'] <=> ['a', 'b']); // int(0)

2. Null merge operator

Due to the large number of simultaneous use of ternary expressions and isset operations in daily use. Use the null coalescing operator to simplify operations

// php7
if (isset($_GET['a'])) {
  $a = $_GET['a'];
}
// php7
$a = isset($_GET['a']) ? $_GET['a'] : 'none';
// PHP 7
$a = isset($_GET['a']) ?? 'none';

4. Variable type declaration

There are two modes of variable type declaration. The following type parameters are allowed: int , string , float , bool

At the same time, you can no longer use integer, string, floating point, and boolean as class names.

function sumOfInts(int ...$ints)
{
    return array_sum($ints);
}
var_dump(sumOfInts(2, '3', 4.1)); // int(9)
declare(strict_types = 1);
function add(int $x, int $y)
{
    return $x + $y;
}
var_dump(add('2', 3)); // Fatal error: Argument 1 passed to add() must be of the type integer

5. Return value type declaration

Added the return type declaration, the return value of the more convenient control function like the parameter type is added after the function definition: the type name is enough

function fun(int $a): array
{
  return $a;
}
fun(3); // Fatal error

6. Anonymous class

php7 allows the new class {} to create an anonymous object.

// php7
class Logger
{
    public function log($msg)
    {
        echo $msg;
    }
}
$util->setLogger(new Logger());
// php7+
$util->setLogger(new class {
    public function log($msg)
    {
        echo $msg;
    }
});

7. Unicode codepoint translation syntax

This accepts a Unicode codepoint in hexadecimal form and prints out a string in UTF-8 encoding format surrounded by double quotes or heredoc. Any valid codepoint can be accepted, and the 0 at the beginning can be omitted

echo "\u{aa}"; 
echo "\u{0000aa}"; 
echo "\u{9999}"; 

8. Closure :: call

Closure binding is short and capable of temporarily binding a method to the object closure and using it.

class A {
    private $x = 1;
}
// PHP 7
$getXCB = function() {
    return $this->x;
};
$getX = $getXCB->bindTo(new A, 'A');
echo $getX();
// PHP 7+
$getX = function() {
    return $this->x;
};
echo $getX->call(new A);

9. Deserialization with filtering

Provide a safer way to unpack unreliable data. It uses whitelisting to prevent potential code injection

// _PHP_Incomplete_Class
$data = unserialize($foo, ["allowed_classes" => false]);
//  MyClass MyClass2  __PHP_Incomplete_Class
$data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]);
$data = unserialize($foo, ["allowed_classes" => true]);

10. IntlChar Class

This class itself defines many static methods for manipulating unicode characters in multiple character sets. Need to install intl extension

printf('%x', IntlChar::CODEPOINT_MAX);
echo IntlChar::charName('@');
var_dump(IntlChar::ispunct('!'));

11. Anticipation

It makes it zero cost to enable assertions in a production environment, and provides the ability to throw specific exceptions when the assertion fails. You can use this for assertion testing in the future

ini_set('assert.exception', 1);
class CustomError extends AssertionError {}
assert(false, new CustomError('Some error message'));

12. Namespace import by group

Classes, functions, and constants imported from the same namespace can be imported once in a group

// php7
use app\model\A;
use app\model\B;
// php7+
use app\model{A, B};

13. The generator supports return expressions

It allows the generator function  to return an expression by using the  return syntax (but it is not allowed to return a reference value), and the return value of the generator can be obtained by calling the  Generator::getReturn()  method, but this method can only be used in the generation It is called once after the generator completes the production work.

$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

14. Generator Delegation

Now, just use yield from in the outermost generation to automatically delegate a generator to other generators

function gen()
{
    yield 1;
    yield 2;
    yield from gen2();
}
function gen2()
{
    yield 3;
    yield 4;
}
foreach (gen() as $val)
{
    echo $val, PHP_EOL;
}

15. Integer division function intdiv

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

16. Session Option Settings

session_start() can add an array to override the php.ini configuration

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

17. preg_replace_callback_array

You can use an associative array to register a callback function for each regular expression, the regular expression itself is used as the key of the associative array, and the corresponding callback function is the value of the associative array

string preg_replace_callback_array(array $regexesAndCallbacks, string $input);
$tokenStream = []; // [tokenName, lexeme] pairs
$input = <<<'end'
$a = 3; // variable initialisation
end;
// Pre PHP 7 code
preg_replace_callback(
    [
        '~\$[a-z_][a-z\d_]*~i',
        '~=~',
        '~[\d]+~',
        '~;~',
        '~//.*~'
    ],
    function ($match) use (&$tokenStream) {
        if (strpos($match[0], '$') === 0) {
            $tokenStream[] = ['T_VARIABLE', $match[0]];
        } elseif (strpos($match[0], '=') === 0) {
            $tokenStream[] = ['T_ASSIGN', $match[0]];
        } elseif (ctype_digit($match[0])) {
            $tokenStream[] = ['T_NUM', $match[0]];
        } elseif (strpos($match[0], ';') === 0) {
            $tokenStream[] = ['T_TERMINATE_STMT', $match[0]];
        } elseif (strpos($match[0], '//') === 0) {
            $tokenStream[] = ['T_COMMENT', $match[0]];
        }
    },
    $input
);
// PHP 7+ code
preg_replace_callback_array(
    [
        '~\$[a-z_][a-z\d_]*~i' => function ($match) use (&$tokenStream) {
            $tokenStream[] = ['T_VARIABLE', $match[0]];
        },
        '~=~' => function ($match) use (&$tokenStream) {
            $tokenStream[] = ['T_ASSIGN', $match[0]];
        },
        '~[\d]+~' => function ($match) use (&$tokenStream) {
            $tokenStream[] = ['T_NUM', $match[0]];
        },
        '~;~' => function ($match) use (&$tokenStream) {
            $tokenStream[] = ['T_TERMINATE_STMT', $match[0]];
        },
        '~//.*~' => function ($match) use (&$tokenStream) {
            $tokenStream[] = ['T_COMMENT', $match[0]];
        }
    ],
    $input
);

18. Random number, random character function

string random_bytes(int length);
int random_int(int min, int max);

19. Define support to define an array

// php7+
define('ALLOWED_IMAGE_EXTENSIONS', ['jpg', 'jpeg', 'gif', 'png']);

PHP7.0 changes

1. Error and exception handling related changes

PHP 7 has changed the way most errors are reported. Unlike the traditional (PHP 5) error reporting mechanism, most errors are now  thrown as  error exceptions.

This also means that when the current error occurs, some error handling code in the previous code will not be triggered. Because in PHP 7 version, the error handling mechanism of throwing exceptions has been used. (If the error  exception is not caught in the code  , then a fatal error will be raised) .set_error_handle may not receive an exception, it may be an error.

ERROR hierarchy

interface Throwable
    |- Exception implements Throwable
        |- ...
    |- Error implements Throwable
        |- TypeError extends Error
        |- ParseError extends Error
        |- AssertionError extends Error
        |- ArithmeticError extends Error
            |- DivisionByZeroError extends ArithmeticError
function handler(Exception $e) { ... }
set_exception_handler('handler');
// PHP 5 to 7
function handler($e) { ... }
// PHP 7
function handler(Throwable $e) { ... }

2. Checklist

The list will be assigned in the original order. It’s no longer a reverse order

list($a,$b,$c) = [1, 2, 3];
var_dump($a); // 1
var_dump($b); // 2
var_dump($c); // 3

List no longer supports unwrapping strings,

3. foreach no longer changes the internal array pointer

$array = [0, 1, 2];
foreach ($array as &$val) {
    var_dump(current($array));
}
// php 5
int(1)
int(2)
bool(false)
// php7
int(0)
int(0)
int(0)

4. Hexadecimal strings are no longer considered numbers

var_dump("0x123" == "291");
// php5
true
// php7
false

5. $HTTP_RAW_POST_DATA is moved

$HTTP_RAW_POST_DATAIt is moved, using php://inputinstead of

6. Removed ASP and script PHP tags

Open labelClosed label
<%%>
<%=%>
<script language="php"></script>

PHP7.1

PHP7.1 new features

1. Nullable type

The types of parameters and return values ​​can now be nullable by adding a question mark in front of the type. When this feature is enabled, the parameter passed in or the result returned by the function is either of the given type or empty

// php5
function($a = null){
  if ($a === null) {
    return null;
  }
  return $a;
}
// php7+
function fun() :?string
{
  return null;
}
function fun1(?$a)
{
  var_dump($a);
}
fun1(null); // null
fun1('1'); // 1

No type

The method whose return value is declared as void type may simply omit the return statement. For void, NULL  is not a legal return value.

function fun() :void
{
  echo "hello world";
}

3. Class constant visibility

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

4. iterable pseudo-class

This can be used in a parameter or return value type, which represents an object that accepts an array or implements the Traversable interface.

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

5. Multiple exception capture processing

A catch statement block can now pass the pipe character (__) To achieve the capture of multiple exceptions. This is useful when you need to handle different exceptions from different classes at the same time
try {
    // some code
} catch (FirstException | SecondException $e) {
    // handle first and second exceptions
}

6. List the supported key names

$data = [
    ["id" => 1, "name" => 'Tom'],
    ["id" => 2, "name" => 'Fred'],
];
// list() style
list("id" => $id1, "name" => $name1) = $data[0];
var_dump($id1); // 1

7. String supports negative direction

$a = "hello";
$a[-2];

8. Turn the callback into a closure

Closure adds a new static method to quickly convert the callable into a Closure object.

class Test
{
    public function exposeFunction()
    {
        return Closure::fromCallable([$this, 'privateFunction']);
    }
    private function privateFunction($param)
    {
        var_dump($param);
    }
}
$privFunc = (new Test)->exposeFunction();
$privFunc('some value');

9. http2 service push

Support for http2 server push has now been added to the CURL extension

PHP7.1 changes

1. An error will be thrown when passing too few parameters

In the past, when we passed too few parameters, warning. php7.1 started to throw errors

2. Removed the ext / mcrypt extension

PHP7.2

PHP7.2 new features

Add new type objects

function test(object $obj) : object
{
    return new SplQueue();
}
test(new StdClass());

2. Load extension by name

Extension files no longer need to be specified by file loading (_.so_ is the file extension under Unix, and .dll  is the file extension under Windows  ). Can be enabled in the php.ini configuration file

; ini file
extension=php-ast
zend_extension=opcache

Allows to override abstract methods

When an abstract class inherits from another abstract class, the inherited abstract class can override the abstract methods of the inherited 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. Use Argon2 algorithm to generate password hash

Argon2 has been added to the password hash (password hash) API (these functions  start with  password_ ), the following constants are exposed

5. Added PDO string extension type

When you are ready to support multilingual character sets, the string type of PDO has been extended to support internationalized character sets. The following are the extended constants:

  • PDO::PARAM_STR_NATL
  • PDO::PARAM_STR_CHAR
  • PDO::ATTR_DEFAULT_STR_PARAM
$db->quote('über', PDO::PARAM_STR | PDO::PARAM_STR_NATL);

6. Naming group namespace supports trailing comma

use Foo\Bar\{
    Foo,
    Bar,
    Baz,
};

PHP7.2 changes

1. number_format return value

var_dump(number_format(-0.01)); // now outputs string(1) "0" instead of string(2) "-0"

2. get_class() no longer allows null

var_dump(get_class(null)); // warning

4. A warning will occur if the calculation is not a countable type

count(1); // integers are not countable

5. Unquoted string

The strings without quotes before are non-existent global constants, converted into their own strings. Hualin will now be produced.

var_dump(HEELLO);

6. __autoload is deprecated

__autoload method has been deprecated

7. Each is abandoned

When using this function to traverse,  it is slower than ordinary foreach and brings implementation problems to the new syntax changes. Therefore it was abandoned.

8. is_object, gettype correction

is_object works in __ PHP_Incomplete_Class

Apply gettype to the resource that the closure will return correctly

9. Convert numeric keys in object/array conversion

When you convert an array to an object, you can access the value of the integer key.

// array to object
$arr = [0 => 1];
$obj = (object)$arr;
var_dump(
    $obj,
    $obj->{'0'}, // now accessible
    $obj->{0} // now accessible
);

PHP7.3

  • Added array_key_first() and array_key_last() to get the key names of the first and last elements of the array
  • Added fpm_get_status() method to get FPM status array,
  • Several FPM configuration items have been added to control the maximum number of characters in a single log line, log buffering, etc.: log_limit, log_buffering, decorate_workers_output
  • Now requires libcurl >= 7.15.5
  • curl adds a bunch of constants
  • json_decode adds a constant, JSON_THROW_ON_ERROR, if the parsing fails, an exception can be thrown instead of getting it through the previous method json_last_error()
  • spl autoloader: If one load fails, the rest will not be executed
  • Explains the results of some circular references
  • In heredoc/nowdoc, if it encounters the same string as the delimiter, it will be considered as the end, and the final real terminator will be considered as a syntax error;
  • In the case of the loop + switch-case statement, use the relay to call the police
  • Explain that when a static variable is inherited, if a circular reference occurs in the subclass, the static variable in the parent class will change accordingly.

Reference

  • http://php.net/manual/zh/migration70.new-features.php
  • http://php.net/manual/zh/migration71.new-features.php
  • http://php.net/manual/zh/migration72.new-features.php
  • http://php.net/manual/zh/migration73.new-features.php
whoami
Stefan Pejcic
Join the discussion

I enjoy constructive responses and professional comments to my posts, and invite anyone to comment or link to my site.