PHP74 新特性

2020-11-18 08:03 PHP在线

PHP 7.4.0 提供了许多改进和新特性,比如:

  • Typed Properties

  • Array Functions

  • Limited Return Type Convariance and Argument Type Contravariance

  • Unpacking Inside Arrays

  • Numeric Literal Separator

  • Weak References

  • Allow Exception from __toString()

  • Opcache Preloading

  • Several Deprecations

  • Extensions Removed from the Core


有类型的类属性

类属性现在支持类型声明。

<?php
class User{ public int $id; public string $name;}
$user = new User();$user->id = '123';$user->name = 123;
var_dump($user->id, $user->name);
// 结果int(123)string(3) "123"

箭头函数

箭头函数为使用隐式按值范围绑定定义函数提供了一种简写语法。

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

有限返回类型协变和参数类型逆变

<?php
class A{}
class B extends A{}
class Producer{ public function method(): A{ echo __METHOD__, PHP_EOL;
return new A(); }}
class ChildProducer extends Producer{ public function method(): B{ echo __METHOD__, PHP_EOL;
return new B(); }}
$producer = new Producer();$childProducer = new ChildProducer();
if ($producer->method() instanceof A) { var_dump('我特么就返回 A 的实例');}if ($childProducer->method() instanceof B) { var_dump('我特么就返回 B 的实例');}
// 结果Producer::methodstring(30) "我特么就返回 A 的实例"ChildProducer::methodstring(30) "我特么就返回 B 的实例"

Null 合并运算符

<?php
function defaultValue(): string{ return '';}
$array = $_REQUEST;
// PHP74 之前
if (! isset($array['key'])) { $array['key'] = defaultValue();}
// PHP74 开始$array['key'] ??= defaultValue();
// 虽然以下代码也可以,但是本人强烈反对这样写,不要问我为什么。代码块我总是用 {} 包起来if (! isset($array['key'])) $array['key'] = defaultValue();

在数组内部展开元素

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

数字字面量分隔符

人眼并未针对快速解析长数字序列进行优化。因此,缺少视觉分隔符会使读取和调试代码花费更长的时间,并可能导致意外错误。

所以 数字字面量分隔符 就是解决人眼快速识别而做出的优化,你看,代码的的确确是机器去执行的,但更重要的是 可读可写可赏可赞 😂。

6.674_083e-11; // float299_792_458;   // decimal0xCAFE_F00D;   // hexadecimal0b0101_1111;   // binary0137_041;      // octal
1_000_000; // versus 10000003.141_592; // versus 3.1415920x02_56_12; // versus 0x0256120b0010_1101; // versus 0b001011010267_3432; // versus 026734321_123.456_7e2 // versus 1123.4567e2
<?php
usleep(345126); // without separator
usleep(345_126); // with separator
if (12345678989876 === 12345678998876) { echo 'Equal';} else { echo 'Unequal';}
echo PHP_EOL;
if (12_345_678_989_876 === 12_345_678_998_876) { echo 'Equal';} else { echo 'Unequal';}

弱引用

允许来自 toString() 的异常

  • Request #53648 Allow __toString() to throw exceptions

<?php
class CustomException extends \Exception{}
class Foo{ public function __toString(){ throw new CustomException('Oops!'); }}
$foo = new Foo();
try { var_dump((string) $foo);} catch (CustomException $e) { var_dump($e);}
// 结果
// PHP56PHP Fatal error: Method Foo::__toString() must not throw an exception in /path/to/User.php on line 0
// PHP73PHP Fatal error: Method Foo::__toString() must not throw an exception, caught CustomException: Oops! in /path/to/a.php on line 0
// PHP74object(CustomException)#2 (7) { ["message":protected]=> string(5) "Oops!" ["string":"Exception":private]=> string(0) "" ["code":protected]=> int(0) ["file":protected]=> string(47) "/Users/xxx/Codes/example/untitled/User.php" ["line":protected]=> int(11) ["trace":"Exception":private]=> array(1) { [0]=> array(6) { ["file"]=> string(47) "/Users/xxx/Codes/example/untitled/User.php" ["line"]=> int(18) ["function"]=> string(10) "__toString" ["class"]=> string(3) "Foo" ["type"]=> string(2) "->" ["args"]=> array(0) { } } } ["previous":"Exception":private]=> NULL}

Opcache 预加载

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

本文章转载自公众号:phpdaily

首页 - PHP 相关的更多文章: