Ngày nay, có nhiều ngôn ngữ lập trình mới ra đời, ngôn ngữ mới thường kế thừa những ưu điểm của các ngôn ngữ đàn anh, code ít làm nhiều,... Anh em coder cũng từ đó mà nhảy sang code ngôn ngữ mới cho nó sướng. Vì thế mà nhiều ngôn ngữ đàn anh càng ít được dân coder quan tâm. Ngôn ngữ PHP cũng không ngoại lệ, tuy vậy nó vẫn chiếm một vị trí nhất định, đặc biệt trong Web development. Để bắt kịp với xu hướng code ngày nay, bộ phận phát triển của PHP đã cho ra đời PHP 7 với nhiều tính năng, đặc biệt là trong cú pháp giúp code gọn hơn, trong sáng hơn,... Bài viết này sẽ tóm tắt những tính năng mới của PHP 7.

Giới thiệu tổng quan

PHP 7.0 được release vào 03/12/2015 và hiện tại version mới nhất là 7.4.6 release ngày 14/05/2020. Ngoài ra theo roadmap của đội ngũ phát triển PHP thì phiên bản PHP 8 hiện tại đang được phát triển và dự định sẽ được phát hành vào cuối năm 2020. Phiên bản 8 sẽ có thêm các tính năng như Just In Time compilation (JIT), negative index arrays,... Nếu bạn quan tâm có thể xem thêm tại đây. Trong bài viết này chỉ giới thiệu đến những điểm mới trong PHP từ phiên bản 7.0 đến 7.4 mà thôi.

PHP 7.0

Khai báo scalar type và Coercive mode / Strict mode

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

var_dump(sumOfInts(2, '3', 4.1)); // 9
<?php
// Strict mode
declare(strict_types = 1);

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

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

Khai báo trả về type

<?php

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

var_dump(arraysSum([1, 2, 3], [4, 5, 6], [7, 8, '9.9'])); // [6, 15, 24]

Toán tử null coalescing ??

<?php
$username = $_GET['user'] ?? 'nobody';
// Tương đương với
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

Toán tử Spaceship <=>

<?php
// 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

Define constant arrays sử dụng define()

<?php
define('ANIMALS', [
    'dog',
    'cat',
    'bird'
]); // In PHP 5.6, they could only be defined with `const`.

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

Anonymous classes

<?php
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;
// Anonymous class
$app->setLogger(new class implements Logger {
    public function log(string $msg) {
        echo $msg;
    }
});

var_dump($app->getLogger());

Cú pháp với Unicode

echo "\u{aa}";  // ª
echo "\u{0000aa}";  // ª (same as before but with optional leading 0's)
echo "\u{9999}"; // 香

Closure::call()

<?php
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);

Nhóm khái báo use

<?php
// 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};

Hàm chia nguyên intdiv()

<?php
var_dump(intdiv(10, 3));  // 3

PHP 7.1

Kiểu Nullable

<?php

function testReturn(): ?string
{
    // or return null;
    return 'elePHPant';
}

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

test('elePHPant'); // elePHPant
test(null); // NULL
test(); // throw ArgumentCountError

Void functions

<?php
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 2 1

Symmetric array destructuring

<?php
$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
}

Hỗ trợ key trong hàm list()

<?php
$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
}

Class constant visibility

<?php
class ConstDemo
{
    const PUBLIC_CONST_A = 1;
    public const PUBLIC_CONST_B = 2;
    protected const PROTECTED_CONST = 3;
    private const PRIVATE_CONST = 4;
}

Multi catch exception handling

<?php
try {
    // some code
} catch (FirstException | SecondException $e) {
    // handle first and second exceptions
}

Negative offset cho string

<?php
var_dump("abcdef"[-2]);  // string (1) "e"
var_dump(strpos("aabbcc", "b", -3)); // int(3)
$string = 'bar';
echo "The last character of '$string' is '$string[-1]'.\n";
// The last character of 'bar' is 'r'.

PHP 7.2

Kiểu object

<?php

function test(object $obj) : object
{
    var_dump($obj);
    return new DateTime($obj->birthdate);
}

// Object-styled definition
$person = new StdClass();
$person->name = 'A Unknown';
$person->birthdate = '1991-01-01 01:01:01';
test($person);

$person_array = [
    'name' => 'B Unknown',
    'age' => '1999-09-09 09:09:09',
];
// Type casting from array to object
$person2 = (object)$person_array;
test($person2);

Abstract method overriding

<?php

abstract class A
{
    abstract function test(string $s);
}
abstract class B extends A
{
    // overridden - $s vẫn là kiểu string
    abstract function test($s) : int;
}

Parameter type widening

<?php

interface A
{
    public function Test(array $input);
}

class B implements A
{
    public function Test($input){} // type omitted for $input
}

Cho phép trailing comma trong grouped namespaces

<?php

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

PHP 7.3

Nâng cấp cú pháp Heredoc/Nowdoc

<?php
function test()
{
    $str = <<<EOD
    Example of string
    spanning multiple lines
    using heredoc syntax.
    EOD; // can not on pre 7.3

    var_dump($str);
}

test();
/*
string(65) "Example of string
spanning multiple lines
using heredoc syntax."
*/

Pre 7.3

<?php
function test()
{
    $str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;

    var_dump($str);
}

test();

Hỗ trợ Reference Assignments trong Array Destructuring

<?php
[&$a, [$b, &$c]] = $d

Example

<?php
$d = ['a', ['b', 'c']];
[&$a, [$b, &$c]] = $d;

$a = 'ar'; $b = 'br'; $c = 'cr';

var_dump($d);
/*
array(2) {
  [0]=> &string(2) "ar"
  [1]=> array(2) {
    [0]=> string(1) "b"
    [1]=> &string(2) "cr"
  }
}
*/

Cho phép trailing comma in calls

<?php
array_uintersect(
    [1, 2, 3],
    [2, 3, 4], // Trailing comma
)

PHP 7.4

Typed properties

<?php
class User {
    public int $id; // Typed property
    public string $name; // Typed property
}

Arrow functions

<?php
$factor = 10;
$nums = array_map(fn($n) => $n * $factor, [1, 2, 3, 4]);
// $nums = array(10, 20, 30, 40);

Toán tử Null coalescing assignment

<?php
$array['key'] ??= computeDefault();
// is roughly equivalent to
if (!isset($array['key'])) {
    $array['key'] = computeDefault();
}

Unpacking inside arrays

<?php
$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];

Viết số dễ đọc hơn

<?php
// Có thể sử dụng _ trong số để dễ đọc hơn
6.674_083e-11; // float
299_792_458; // decimal
0xCAFE_F00D; // hexadecimal
0b0101_1111; // binary

Tham khảo

https://en.wikipedia.org/wiki/PHP
https://www.php.net/manual/en/migration70.new-features.php
https://www.php.net/manual/en/migration71.new-features.php
https://www.php.net/manual/en/migration72.new-features.php
https://www.php.net/manual/en/migration73.new-features.php
https://www.php.net/manual/en/migration74.new-features.php