Hướng dẫn dùng charcter types trong PHP

Như bạn có thể thấy từ các biểu đồ, PHP 7.0 là một cải tiến lớn về hiệu suất và việc sử dụng bộ nhớ. Đối với trang có các truy vấn cơ sở dữ liệu, phiên bản 7.0.0 nhanh hơn 3 lần so với 5.6 với opcache được bật và nhanh hơn 2,7 lần mà không cần opcache! Về mặt sử dụng bộ nhớ, sự khác biệt cũng rất đáng kể!


Throwable interface

Tái cấu trúc các exception class để có một naming scheme không trực quan và sẽ dẫn đến ít nhầm lẫn hơn, đặc biệt là đối với người dùng mới hơn.

interface A {
    static function make(): A;
}
class B implements A {
    static function make(): A {
        return new B();
    }
}
9 và
// Explicit use syntax:
 
use FooLibrary\Bar\Baz\ClassA;
use FooLibrary\Bar\Baz\ClassB;
use FooLibrary\Bar\Baz\ClassC;
use FooLibrary\Bar\Baz\ClassD as Fizbo;
// Grouped use syntax:
 
use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo };
0 bây giờ được implement
// Explicit use syntax:
 
use FooLibrary\Bar\Baz\ClassA;
use FooLibrary\Bar\Baz\ClassB;
use FooLibrary\Bar\Baz\ClassC;
use FooLibrary\Bar\Baz\ClassD as Fizbo;
// Grouped use syntax:
 
use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo };
1

Đây là hệ thống cấp bậc của

// Explicit use syntax:
 
use FooLibrary\Bar\Baz\ClassA;
use FooLibrary\Bar\Baz\ClassB;
use FooLibrary\Bar\Baz\ClassC;
use FooLibrary\Bar\Baz\ClassD as Fizbo;
// Grouped use syntax:
 
use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo };
1

interface Throwable
  |- Error implements Throwable
      |- ArithmeticError extends Error
          |- DivisionByZeroError extends ArithmeticError
      |- AssertionError extends Error
      |- ParseError extends Error
      |- TypeError extends Error
          |- ArgumentCountError extends TypeError
  |- Exception implements Throwable
      |- ClosedGeneratorException extends Exception
      |- DOMException extends Exception
      |- ErrorException extends Exception
      |- IntlException extends Exception
      |- LogicException extends Exception
          |- BadFunctionCallException extends LogicException
              |- BadMethodCallException extends BadFunctionCallException
          |- DomainException extends LogicException
          |- InvalidArgumentException extends LogicException
          |- LengthException extends LogicException
          |- OutOfRangeException extends LogicException
      |- PharException extends Exception
      |- ReflectionException extends Exception
      |- RuntimeException extends Exception
          |- OutOfBoundsException extends RuntimeException
          |- OverflowException extends RuntimeException
          |- PDOException extends RuntimeException
          |- RangeException extends RuntimeException
          |- UnderflowException extends RuntimeException
          |- UnexpectedValueException extends RuntimeException

Chú ý: bạn chỉ có thể implement

// Explicit use syntax:
 
use FooLibrary\Bar\Baz\ClassA;
use FooLibrary\Bar\Baz\ClassB;
use FooLibrary\Bar\Baz\ClassC;
use FooLibrary\Bar\Baz\ClassD as Fizbo;
// Grouped use syntax:
 
use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo };
1 thông qua
// Explicit use syntax:
 
use FooLibrary\Bar\Baz\ClassA;
use FooLibrary\Bar\Baz\ClassB;
use FooLibrary\Bar\Baz\ClassC;
use FooLibrary\Bar\Baz\ClassD as Fizbo;
// Grouped use syntax:
 
use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo };
4 và
// Explicit use syntax:
 
use FooLibrary\Bar\Baz\ClassA;
use FooLibrary\Bar\Baz\ClassB;
use FooLibrary\Bar\Baz\ClassC;
use FooLibrary\Bar\Baz\ClassD as Fizbo;
// Grouped use syntax:
 
use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo };
0.


Unicode Codepoint Escape Syntax — “\u{xxxxx}”

echo "\u{202E}Reversed text"; // outputs ‮Reversed text
echo "mañana"; // "ma\u{00F1}ana"
echo "mañana"; // "man\u{0303}ana" "n" with combining ~ character (U+0303)

Context Sensitive Lexer

Với những từ globally reserved nay đã trở thành semi-reserved:

intdiv(int $numerator, int $divisor)
0

Generator return expressions

Cú pháp biến đồng nhất

Mức hỗ trợ cho functions dirname()

PHP 7.1

Nullable Types

intdiv(int $numerator, int $divisor)
1

Void Returns

intdiv(int $numerator, int $divisor)
2

Không giống như các kiểu trả về khác được thi hành khi hàm được gọi, loại này được kiểm tra tại thời gian biên dịch, điều đó có nghĩa là một lỗi được tạo ra mà không cần gọi hàm.

Một hàm có kiểu trả về là

// Explicit use syntax:
 
use FooLibrary\Bar\Baz\ClassA;
use FooLibrary\Bar\Baz\ClassB;
use FooLibrary\Bar\Baz\ClassC;
use FooLibrary\Bar\Baz\ClassD as Fizbo;
// Grouped use syntax:
 
use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo };
6 hoặc hàm
// Explicit use syntax:
 
use FooLibrary\Bar\Baz\ClassA;
use FooLibrary\Bar\Baz\ClassB;
use FooLibrary\Bar\Baz\ClassC;
use FooLibrary\Bar\Baz\ClassD as Fizbo;
// Grouped use syntax:
 
use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo };
6, có thể trả về ngầm hoặc có câu lệnh return mà không có giá trị:

intdiv(int $numerator, int $divisor)
3

Iterable pseudo type

Thông thường, một hàm chấp nhận hoặc trả về một

// Explicit use syntax:
 
use FooLibrary\Bar\Baz\ClassA;
use FooLibrary\Bar\Baz\ClassB;
use FooLibrary\Bar\Baz\ClassC;
use FooLibrary\Bar\Baz\ClassD as Fizbo;
// Grouped use syntax:
 
use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo };
8 hoặc một object implementing
// Explicit use syntax:
 
use FooLibrary\Bar\Baz\ClassA;
use FooLibrary\Bar\Baz\ClassB;
use FooLibrary\Bar\Baz\ClassC;
use FooLibrary\Bar\Baz\ClassD as Fizbo;
// Grouped use syntax:
 
use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo };
9 sẽ được sử dụng với
yield from 
0. Tuy nhiên, vì mảng là kiểu nguyên thủy và
// Explicit use syntax:
 
use FooLibrary\Bar\Baz\ClassA;
use FooLibrary\Bar\Baz\ClassB;
use FooLibrary\Bar\Baz\ClassC;
use FooLibrary\Bar\Baz\ClassD as Fizbo;
// Grouped use syntax:
 
use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo };
9 là một interface, hiện tại không có cách nào để sử dụng khai báo kiểu trên tham số hoặc kiểu trả về để chỉ ra rằng giá trị có thể lặp lại được.

intdiv(int $numerator, int $divisor)
4

yield from 
2 cũng có thể được sử dụng như một kiểu trả về để chỉ ra một hàm sẽ trả về một giá trị lặp. Nếu giá trị được trả về không phải là một mảng hoặc instance của
// Explicit use syntax:
 
use FooLibrary\Bar\Baz\ClassA;
use FooLibrary\Bar\Baz\ClassB;
use FooLibrary\Bar\Baz\ClassC;
use FooLibrary\Bar\Baz\ClassD as Fizbo;
// Grouped use syntax:
 
use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo };
9,
yield from 
4 sẽ được throw.

intdiv(int $numerator, int $divisor)
5

Các tham số được khai báo với

yield from 
2 có thể sử dụng
yield from 
6 hoặc một mảng làm giá trị mặc định.

intdiv(int $numerator, int $divisor)
6

Closure from callable

intdiv(int $numerator, int $divisor)
7

Cú pháp dấu ngoặc vuông cho phép destructuring assignment mảng

intdiv(int $numerator, int $divisor)
8

Cú pháp dấu ngoặc vuông cho danh list()

intdiv(int $numerator, int $divisor)
9

Class constant visibility

$x = NULL;
$y = NULL;
$z = 3;
var_dump($x ?? $y ?? $z); // int(3)
 
$x = ["c" => "meaningful_value"];
var_dump($x["a"] ?? $x["b"] ?? $x["c"]); // string(16) "meaningful_value"
0

Catching Multiple Exception Types

$x = NULL;
$y = NULL;
$z = 3;
var_dump($x ?? $y ?? $z); // int(3)
 
$x = ["c" => "meaningful_value"];
var_dump($x["a"] ?? $x["b"] ?? $x["c"]); // string(16) "meaningful_value"
1

PHP 7.2

Mở rộng kiểu tham số

$x = NULL;
$y = NULL;
$z = 3;
var_dump($x ?? $y ?? $z); // int(3)
 
$x = ["c" => "meaningful_value"];
var_dump($x["a"] ?? $x["b"] ?? $x["c"]); // string(16) "meaningful_value"
2

Đếm các object không đếm được

Gọi

yield from 
7 trên một scalar hoặc object không implement Countable interface trả về 1 (phi logic).

Trong phiên bản này đã thêm một cảnh báo khi gọi

yield from 
7 với tham số là scalar, null hoặc một object không implement
yield from 
9.


Cú pháp dấu phảy được sử dụng trong namespace

$x = NULL;
$y = NULL;
$z = 3;
var_dump($x ?? $y ?? $z); // int(3)
 
$x = ["c" => "meaningful_value"];
var_dump($x["a"] ?? $x["b"] ?? $x["c"]); // string(16) "meaningful_value"
3

Argon2 Password Hash

Các hàm

interface Throwable
  |- Error implements Throwable
      |- ArithmeticError extends Error
          |- DivisionByZeroError extends ArithmeticError
      |- AssertionError extends Error
      |- ParseError extends Error
      |- TypeError extends Error
          |- ArgumentCountError extends TypeError
  |- Exception implements Throwable
      |- ClosedGeneratorException extends Exception
      |- DOMException extends Exception
      |- ErrorException extends Exception
      |- IntlException extends Exception
      |- LogicException extends Exception
          |- BadFunctionCallException extends LogicException
              |- BadMethodCallException extends BadFunctionCallException
          |- DomainException extends LogicException
          |- InvalidArgumentException extends LogicException
          |- LengthException extends LogicException
          |- OutOfRangeException extends LogicException
      |- PharException extends Exception
      |- ReflectionException extends Exception
      |- RuntimeException extends Exception
          |- OutOfBoundsException extends RuntimeException
          |- OverflowException extends RuntimeException
          |- PDOException extends RuntimeException
          |- RangeException extends RuntimeException
          |- UnderflowException extends RuntimeException
          |- UnexpectedValueException extends RuntimeException
0 hiện có cung cấp interface đơn giản để băm mật khẩu. RFC này đề xuất triển khai Argon2i (v1.3) trong các hàm
interface Throwable
  |- Error implements Throwable
      |- ArithmeticError extends Error
          |- DivisionByZeroError extends ArithmeticError
      |- AssertionError extends Error
      |- ParseError extends Error
      |- TypeError extends Error
          |- ArgumentCountError extends TypeError
  |- Exception implements Throwable
      |- ClosedGeneratorException extends Exception
      |- DOMException extends Exception
      |- ErrorException extends Exception
      |- IntlException extends Exception
      |- LogicException extends Exception
          |- BadFunctionCallException extends LogicException
              |- BadMethodCallException extends BadFunctionCallException
          |- DomainException extends LogicException
          |- InvalidArgumentException extends LogicException
          |- LengthException extends LogicException
          |- OutOfRangeException extends LogicException
      |- PharException extends Exception
      |- ReflectionException extends Exception
      |- RuntimeException extends Exception
          |- OutOfBoundsException extends RuntimeException
          |- OverflowException extends RuntimeException
          |- PDOException extends RuntimeException
          |- RangeException extends RuntimeException
          |- UnderflowException extends RuntimeException
          |- UnexpectedValueException extends RuntimeException
0 để sử dụng thay thế an toàn cho
interface Throwable
  |- Error implements Throwable
      |- ArithmeticError extends Error
          |- DivisionByZeroError extends ArithmeticError
      |- AssertionError extends Error
      |- ParseError extends Error
      |- TypeError extends Error
          |- ArgumentCountError extends TypeError
  |- Exception implements Throwable
      |- ClosedGeneratorException extends Exception
      |- DOMException extends Exception
      |- ErrorException extends Exception
      |- IntlException extends Exception
      |- LogicException extends Exception
          |- BadFunctionCallException extends LogicException
              |- BadMethodCallException extends BadFunctionCallException
          |- DomainException extends LogicException
          |- InvalidArgumentException extends LogicException
          |- LengthException extends LogicException
          |- OutOfRangeException extends LogicException
      |- PharException extends Exception
      |- ReflectionException extends Exception
      |- RuntimeException extends Exception
          |- OutOfBoundsException extends RuntimeException
          |- OverflowException extends RuntimeException
          |- PDOException extends RuntimeException
          |- RangeException extends RuntimeException
          |- UnderflowException extends RuntimeException
          |- UnexpectedValueException extends RuntimeException
2.


Debugging PDO Prepared Statement Emulation

$x = NULL;
$y = NULL;
$z = 3;
var_dump($x ?? $y ?? $z); // int(3)
 
$x = ["c" => "meaningful_value"];
var_dump($x["a"] ?? $x["b"] ?? $x["c"]); // string(16) "meaningful_value"
4

PHP 7.4 (In development)

Typed properties

$x = NULL;
$y = NULL;
$z = 3;
var_dump($x ?? $y ?? $z); // int(3)
 
$x = ["c" => "meaningful_value"];
var_dump($x["a"] ?? $x["b"] ?? $x["c"]); // string(16) "meaningful_value"
5

Foreign Function Interface

FFI là một trong những tính năng giúp Python và LuaJIT rất hữu ích cho việc tạo mẫu nhanh. Nó cho phép gọi các hàm C và sử dụng các kiểu dữ liệu C từ ngôn ngữ kịch bản thuần túy và do đó phát triển "system code" hiệu quả hơn. Đối với PHP, FFI mở ra một cách để viết các phần mở rộng và ràng buộc PHP vào các thư viện C trong PHP thuần.


Null Coalescing Assignment Operator

$x = NULL;
$y = NULL;
$z = 3;
var_dump($x ?? $y ?? $z); // int(3)
 
$x = ["c" => "meaningful_value"];
var_dump($x["a"] ?? $x["b"] ?? $x["c"]); // string(16) "meaningful_value"
6

Preloading

PHP đã sử dụng opcode caches từ lâu (APC, Turck MMCache, Zend OpCache). Họ đạt được hiệu suất tăng đáng kể bằng cách GẦN NHƯ loại bỏ hoàn toàn overhead của biên dịch lại PHP code. Preloading sẽ được kiểm soát chỉ bằng một chỉ thị

interface Throwable
  |- Error implements Throwable
      |- ArithmeticError extends Error
          |- DivisionByZeroError extends ArithmeticError
      |- AssertionError extends Error
      |- ParseError extends Error
      |- TypeError extends Error
          |- ArgumentCountError extends TypeError
  |- Exception implements Throwable
      |- ClosedGeneratorException extends Exception
      |- DOMException extends Exception
      |- ErrorException extends Exception
      |- IntlException extends Exception
      |- LogicException extends Exception
          |- BadFunctionCallException extends LogicException
              |- BadMethodCallException extends BadFunctionCallException
          |- DomainException extends LogicException
          |- InvalidArgumentException extends LogicException
          |- LengthException extends LogicException
          |- OutOfRangeException extends LogicException
      |- PharException extends Exception
      |- ReflectionException extends Exception
      |- RuntimeException extends Exception
          |- OutOfBoundsException extends RuntimeException
          |- OverflowException extends RuntimeException
          |- PDOException extends RuntimeException
          |- RangeException extends RuntimeException
          |- UnderflowException extends RuntimeException
          |- UnexpectedValueException extends RuntimeException
3 mới - opcache.preload. Sử dụng chỉ thị này, chúng ta sẽ chỉ định một file PHP - sẽ thực hiện nhiệm vụ tải trước. Sau khi tải, file này sau đó được thực thi đầy đủ - và có thể tải trước các file khác, bằng cách including chúng hoặc bằng cách sử dụng hàm
interface Throwable
  |- Error implements Throwable
      |- ArithmeticError extends Error
          |- DivisionByZeroError extends ArithmeticError
      |- AssertionError extends Error
      |- ParseError extends Error
      |- TypeError extends Error
          |- ArgumentCountError extends TypeError
  |- Exception implements Throwable
      |- ClosedGeneratorException extends Exception
      |- DOMException extends Exception
      |- ErrorException extends Exception
      |- IntlException extends Exception
      |- LogicException extends Exception
          |- BadFunctionCallException extends LogicException
              |- BadMethodCallException extends BadFunctionCallException
          |- DomainException extends LogicException
          |- InvalidArgumentException extends LogicException
          |- LengthException extends LogicException
          |- OutOfRangeException extends LogicException
      |- PharException extends Exception
      |- ReflectionException extends Exception
      |- RuntimeException extends Exception
          |- OutOfBoundsException extends RuntimeException
          |- OverflowException extends RuntimeException
          |- PDOException extends RuntimeException
          |- RangeException extends RuntimeException
          |- UnderflowException extends RuntimeException
          |- UnexpectedValueException extends RuntimeException
4.


Luôn có sẵn hash extention

Điều này sẽ làm cho hash extension (`ext / hash`) luôn có sẵn, tương tự như `date`. Phần hash extension cung cấp một tiện ích rất phong phú với nhiều thuật toán băm cực kỳ hữu ích trong các ứng dụng hiện đại, không chỉ trong code người dùng mà còn rất nhiều trong nội bộ.

On the way to PHP 8.0

JIT.

Nói ngắn gọn. Khi bạn khởi động một chương trình PHP, Zend Engine sẽ phân tích code thành một cây cú pháp trừu tượng (AST) và dịch nó sang opcodes. Các opcodes là các đơn vị thực thi cho Máy ảo Zend (Zend VM). Opcode là mức độ khá thấp, do đó dịch code sang máy nhanh hơn nhiều so với code PHP gốc. PHP có một phần mở rộng có tên OPcache trong lõi, để lưu trữ các opcodes này.

“JIT” is a technique that will compile parts of the code at runtime, so that the compiled version can be used instead.


Đây là một trong những chiến lược tối ưu hóa PHP cuối cùng và lớn nhất vẫn còn trên bàn. Các PHP engineers đang tìm kiếm để xem cách tiếp cận mới này có thể vượt qua các ứng dụng của họ. Thực sự quan tâm đến điều này.


Nhất quán loại errors cho internal function

Làm cho các API phân tích tham số nội bộ luôn tạo ra

yield from 
4 nếu parameter parsing không thành công. Cần lưu ý rằng điều này cũng bao gồm
interface Throwable
  |- Error implements Throwable
      |- ArithmeticError extends Error
          |- DivisionByZeroError extends ArithmeticError
      |- AssertionError extends Error
      |- ParseError extends Error
      |- TypeError extends Error
          |- ArgumentCountError extends TypeError
  |- Exception implements Throwable
      |- ClosedGeneratorException extends Exception
      |- DOMException extends Exception
      |- ErrorException extends Exception
      |- IntlException extends Exception
      |- LogicException extends Exception
          |- BadFunctionCallException extends LogicException
              |- BadMethodCallException extends BadFunctionCallException
          |- DomainException extends LogicException
          |- InvalidArgumentException extends LogicException
          |- LengthException extends LogicException
          |- OutOfRangeException extends LogicException
      |- PharException extends Exception
      |- ReflectionException extends Exception
      |- RuntimeException extends Exception
          |- OutOfBoundsException extends RuntimeException
          |- OverflowException extends RuntimeException
          |- PDOException extends RuntimeException
          |- RangeException extends RuntimeException
          |- UnderflowException extends RuntimeException
          |- UnexpectedValueException extends RuntimeException
6 (con của
yield from 
4) cho các trường hợp có quá ít/nhiều đối số được thông qua.

So sánh hiệu suất

Tôi đã soạn một bài test đơn giản để giúp dễ dàng so sánh hiệu suất của các phiên bản PHP khác nhau (sử dụng Docker). Điều này thậm chí sẽ cho phép dễ dàng kiểm tra hiệu năng của các phiên bản PHP mới chỉ bằng cách thêm tên container mới.

Chạy trên Macbook pro, 2,5 GHz Intel Core i7.

$x = NULL;
$y = NULL;
$z = 3;
var_dump($x ?? $y ?? $z); // int(3)
 
$x = ["c" => "meaningful_value"];
var_dump($x["a"] ?? $x["b"] ?? $x["c"]); // string(16) "meaningful_value"
7

Nếu muốn tự kiểm tra, bạn có thể tìm source code trong repository này.

Benchmarks từ PHP 5.6 trở lên

Tôi thực sự thích phần tổng hợp hiệu năng trực quan từ servbolt.com của tất cả các phiên bản chính từ 5.6 trở lên. Xem kết quả trong các bảng dưới đây.

Tóm lược hiệu năng

PHP 7.0.0 là một cột mốc quan trọng với hiệu suất được cải thiện đáng kể và sử dụng bộ nhớ thấp hơn nhưng các PHP maintainers chỉ đơn giản là hết ý tưởng để cải thiện nó. Một trong những điểm còn lại là biên dịch JIT (Just in time). Và nó đi kèm với PHP 8.0.

Hướng phát triển

Trong suốt các phiên bản PHP 7.x, có một path có thể nhìn thấy được nhắc tới nhiều hơn (và khách quan hơn một chút) và ngôn ngữ lập trình hiện đại. Tuy nhiên, PHP thích áp dụng các tính năng hữu ích và gọn gàng từ các ngôn ngữ lập trình khác.

Chúng ta sẽ sớm thấy một số tính năng hay hơn, như:

  • Named Arguments
  • Nullsafe Calls
  • Enumerated Types (ENUMs)
  • Arrow functions

Với những điều này, PHP developers sẽ tham gia nhóm những người áp dụng ngôn ngữ hiện đại. Không có ngôn ngữ nào là hoàn hảo, nhưng PHP đang mở đường cho tương lai.

TL;DR

Để rút ngắn hơn nữa, tôi đã chọn hầu hết các thay đổi quan trọng đối với ý kiến cá nhân của mình với phiên bản mới nhất của PHP 7.3. Chúng đây rồi:

  • Added new null coalesce operator
  • Scalar type declarations
  • Return type declarations
  • Throwable interface
  • Nullable Types
  • Void Returns
  • Square bracket syntax for array destructing
  • Class constant visibility

References:

https://wiki.php.net/rfc https://www.cloudways.com/blog/php-5-6-vs-php-7-symfony-benchmarks/ https://servebolt.com/articles/wordpress-5-0-php-7-2-vs-php-7-3-performance-and-speed-benchmark/