php7.4 更新特性

Posted 行云

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php7.4 更新特性相关的知识,希望对你有一定的参考价值。

php 7.4.0 Released!

The PHP development team announces the immediate availability of PHP 7.4.0. This release marks the fourth feature update to the PHP 7 series.
PHP 7.4.0 comes with numerous improvements and new features such as:
Typed Properties
Arrow Functions
Limited Return Type Covariance and Argument Type Contravariance
Unpacking Inside Arrays
Numeric Literal Separator
Weak References
Allow Exceptions from __toString()
Opcache Preloading
Several Deprecations
Extensions Removed from the Core

1.Typed Properties 强类型

Class中预定义变量后, 只能赋值相应的数据类型

All types are supported, with the exception of void and callable:
class User {
public int $id;
public string $name;
}

They are also allowed with the var notation:
var bool $flag;
The same type applies to all properties in a single declaration:
public float $x, $y;

What happens if we make an error on the property type? Consider the following code:
class User {
public int $id;
public string $name;
}

$user = new User;
$user->id = 10;
$user->name = [];

Fatal error:
Fatal error: Uncaught TypeError: Typed property User::$name must be string, array used in /app/types.php:9

2.Arrow Function 箭头函数(简短闭包)
箭头函数为了闭包内只有一行代码的闭包函数提供了更简洁的方式

7.4.0之前
array_map(function (User $user) {
return $user->id;
}, $users)
之后
array_map(fn (User $user) => $user->id, $users)

function cube($n){
return ($n * $n * $n);
}
$a = [1, 2, 3, 4, 5];
$b = array_map(‘cube‘, $a);
print_r($b);
之后
$a = [1, 2, 3, 4, 5];
$b = array_map(fn($n) => $n * $n * $n, $a);
print_r($b);

$factor = 10;
$calc = function($num) use($factor){
return $num * $factor;
};
之后
$factor = 10;
$calc = fn($num) => $num * $factor;

3.Limited return type covariance and argument type contravariance 协变返回和逆变参数

子类和父类
协变返回
interface Factory {
function make(): object;
}

class UserFactory implements Factory {
// 将比较泛的 object 类型,具体到 User 类型
function make(): User;
}

逆变参数
interface Concatable {
function concat(Iterator $input);
}

class Collection implements Concatable {
// 将比较具体的 Iterator参数类型,逆变成接受所有的 iterable类型
function concat(iterable $input) {/* . . . */}
}

4.Unpacking Inside Arrays 数组内解包
三个点...叫做Spread运算符, 第一个好处是性能
Spread 运算符应该比 array_merge 拥有更好的性能。这不仅仅是 Spread 运算符是一个语法结构,而 array_merge 是一个方法。还是在编译时,优化了高效率的常量数组

$parts = [‘apple‘, ‘pear‘];
$fruits = [‘banana‘, ‘orange‘, ...$parts, ‘watermelon‘];
var_dump($fruits);


array(5) { [0]=> string(6) "banana" [1]=> string(6) "orange" [2]=> string(5) "apple" [3]=> string(4) "pear" [4]=> string(10) "watermelon" }

RFC 声明我们可以多次扩展同一个数组。而且,我们可以在数组中的任何地方使用扩展运算符语法,因为可以在扩展运算符之前或之后添加普通元素。所以,就像下面代码所示的那样:
$arr1 = [1, 2, 3];
$arr2 = [4, 5, 6];
$arr3 = [...$arr1, ...$arr2];
$arr4 = [...$arr1, ...$arr3, 7, 8, 9];

也可以将函数返回的数组直接合并到另一个数组:
function buildArray(){
return [‘red‘, ‘green‘, ‘blue‘];
}
$arr1 = [...buildArray(), ‘pink‘, ‘violet‘, ‘yellow‘];

也可以写成生成器
function generator() {
for ($i = 3; $i <= 5; $i++) {
yield $i;
}
}
$arr1 = [0, 1, 2, ...generator()];

但是我们不允许合并通过引用传递的数组。 考虑以下的例子:
$arr1 = [‘red‘, ‘green‘, ‘blue‘];
$arr2 = [...&$arr1];

无论如何,如果第一个数组的元素是通过引用存储的,则它们也将通过引用存储在第二个数组中。 这是一个例子:
$arr0 = ‘red‘;
$arr1 = [&$arr0, ‘green‘, ‘blue‘];
$arr2 = [‘white‘, ...$arr1, ‘black‘];
上面这个是OK的

5.Numeric Literal Separator

数字字符间可以插入分隔符号
<?php
6.674_083e-11; // float
299_792_458; // decimal
0xCAFE_F00D; // hexadecimal
0b0101_1111; // binary
?>

Null Coalescing Assignment Operator
Added with PHP 7, the coalesce operator (??) comes in handy when we need to use a ternary operator in conjunction with isset(). It returns the first operand if it exists and is not NULL. Otherwise, it returns the second operand. Here is an example:

$username = $_GET[‘user‘] ?? ‘nobody‘;
What this code does is pretty straightforward: it fetches the request parameter and sets a default value if it doesn’t exist. The meaning of that line is clear, but what if we had much longer variable names as in this example from the RFC?

$this->request->data[‘comments‘][‘user_id‘] = $this->request->data[‘comments‘][‘user_id‘] ?? ‘value‘;
In the long run, this code could be a bit difficult to maintain. So, aiming to help developers to write more intuitive code, this RFC proposes the introduction of the null coalescing assignment operator (??=). So, instead of writing the previous code, we could write the following:

$this->request->data[‘comments‘][‘user_id‘] ??= ‘value’;
If the value of the left-hand parameter is null, then the value of the right-hand parameter is used. Note that, while the coalesce operator is a comparison operator, ??= is an assignment operator.

This proposal has been approved with 37 to 4 votes.

6.Weak References
弱引用使程序员可以保留对对象的引用,不会阻止对象被销毁。
$object = new stdClass;
$weakRef = WeakReference::create($object);

var_dump($weakRef->get());
unset($object);
var_dump($weakRef->get());

The first var_dump prints object(stdClass)#1 (0) {}, while the second var_dump prints NULL, as the referenced object has been destroyed.
object(stdClass)#1 (0) {
}
NULL

7.Allow Exceptions from __toString()
现在允许从 __toString() 引发异常,以往这会导致致命错误,字符串转换中现有的可恢复致命错误已转换为 Error 异常。
<?php
// Declare a simple class
class TestClass
{
public $foo;

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


public function __toString() {
    return $this->foo;
}

}

$class = new TestClass(‘Hello‘);
echo $class;
?>
输出Hello

8.Opcache Preloading 预加载
指定要在服务器启动时期进行编译和缓存的 PHP 脚本文件, 这些文件也可能通过 include 或者 opcache_compile_file() 函数 来预加载其他文件。 所有这些文件中包含的实体,包括函数、类等,在服务器启动的时候就被加载和缓存, 对于用户代码来讲是“开箱可用”的。

php.ini
opcache.preload

On server startup – before any application code is run – we may load a certain set of PHP files into memory – and make their contents “permanently available” to all subsequent requests that will be served by that server. All the functions and classes defined in these files will be available to requests out of the box, exactly like internal entities.

9.Several Deprecations 废弃的

Nested ternary operators without explicit parentheses ?

Nested ternary operations must explicitly use parentheses to dictate the order of the operations. Previously, when used without parentheses, the left-associativity would not result in the expected behaviour in most cases.
<?php
1 ? 2 : 3 ? 4 : 5; // deprecated
(1 ? 2 : 3) ? 4 : 5; // ok
1 ? 2 : (3 ? 4 : 5); // ok
?>
Array and string offset access using curly braces ?

The array and string offset access syntax using curly braces is deprecated. Use $var[$idx] instead of $var{$idx}.
(real) cast and is_real() function ?

The (real) cast is deprecated, use (float) instead.
The is_real() function is also deprecated, use is_float() instead.
Unbinding $this when $this is used ?

Unbinding $this of a non-static closure that uses $this is deprecated.
parent keyword without parent class ?

Using parent inside a class without a parent is deprecated, and will throw a compile-time error in the future. Currently an error will only be generated if/when the parent is accessed at run-time.
allow_url_include INI option ?

The allow_url_include ini directive is deprecated. Enabling it will generate a deprecation notice at startup.
Invalid characters in base conversion functions ?

Passing invalid characters to base_convert(), bindec(), octdec() and hexdec() will now generate a deprecation notice. The result will still be computed as if the invalid characters did not exist. Leading and trailing whitespace, as well as prefixes of type 0x (depending on base) continue to be allowed.
Using array_key_exists() on objects ?

Using array_key_exists() on objects is deprecated. Instead either isset() or property_exists() should be used.
Magic quotes functions ?

The get_magic_quotes_gpc() and get_magic_quotes_runtime() functions are deprecated. They always return FALSE.
hebrevc() function ?

The hebrevc() function is deprecated. It can be replaced with nl2br(hebrev($str)) or, preferably, the use of Unicode RTL support.
convert_cyr_string() function ?

The convert_cyr_string() function is deprecated. It can be replaced by one of mb_convert_string(), iconv() or UConverter.
money_format() function ?

The money_format() function is deprecated. It can be replaced by the intl NumberFormatter functionality.
ezmlm_hash() function ?

The ezmlm_hash() function is deprecated.
restore_include_path() function ?

The restore_include_path() function is deprecated. It can be replaced by ini_restore(‘include_path‘).
Implode with historical parameter order ?

Passing parameters to implode() in reverse order is deprecated, use implode($glue, $parts) instead of implode($parts, $glue).
COM ?

Importing type libraries with case-insensitive constant registering has been deprecated.
Filter ?

FILTER_SANITIZE_MAGIC_QUOTES is deprecated, use FILTER_SANITIZE_ADD_SLASHES instead.
Multibyte String ?

Passing a non-string pattern to mb_ereg_replace() is deprecated. Currently, non-string patterns are interpreted as ASCII codepoints. In PHP 8, the pattern will be interpreted as a string instead.
Passing the encoding as 3rd parameter to mb_strrpos() is deprecated. Instead pass a 0 offset, and encoding as 4th parameter.
Lightweight Directory Access Protocol ?

ldap_control_paged_result_response() and ldap_control_paged_result() are deprecated. Pagination controls can be sent along with ldap_search() instead.
Reflection ?

Calls to ReflectionType::__toString() now generate a deprecation notice. This method has been deprecated in favor of ReflectionNamedType::getName() in the documentation since PHP 7.1, but did not throw a deprecation notice for technical reasons.
The export() methods on all Reflection classes are deprecated. Construct a Reflection object and convert it to string instead:
<?php
// ReflectionClass::export(Foo::class, false) is:
echo new ReflectionClass(Foo::class), " ";

// $str = ReflectionClass::export(Foo::class, true) is:
$str = (string) new ReflectionClass(Foo::class);
?>
Socket ?

The AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULES flags for socket_addrinfo_lookup() are deprecated, due to an upstream deprecation in glibc.

10.Extensions Removed from the Core
These extensions have been moved to PECL and are no longer part of the PHP distribution. The PECL package versions of these extensions will be created according to user demand.

  • Firebird/Interbase - access to an InterBase and/or Firebird based database is still available with the PDO Firebird driver.
  • Recode
  • WDDX

更多详情可见RFC文档 https://wiki.php.net/rfc

以上是关于php7.4 更新特性的主要内容,如果未能解决你的问题,请参考以下文章

PHP 7.4 有什么新功能?你必须掌握的 10 大特性

如何在 PHP7.4 中使用 inotify

译ECMAScript 2016, 2017, 2018 新特性之必读篇

PHP 7.4 新特性

PHPPHP 7.4 新特性

js常用代码片段(更新中)