• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

PHP70、71、72、73、74版本新特性

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

 PHP 70 新特性

https://www.php.net/manual/zh/migration70.new-features.php
https://www.php.net/manual/en/migration70.new-features.php

标量类型声明扩充

类型声明(类型提示)在原先支持“类名,接口,数组和回调类型”的基础上新增:
1、字符串(string);  2、整数 (int);  3、浮点数 (float);  4、以及布尔值 (bool)

返回值类型声明

增加了对返回类型声明的支持

null合并运算符

添加了null合并运算符 (??) 这个语法糖

$username = $_GET['user'] ?? 'nobody'; 等效 $username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

太空船操作符(组合比较符)

太空船操作符用于比较两个表达式。当$a小于、等于或大于$b时它分别返回-1、0或1。

<?php
// 整数
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1

// 浮点数
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
 
// 字符串  比如:strcmp($str1, $str2) 就可以使用以下方式简写
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1 

通过 define() 定义常量数组

define('ANIMALS', ['dog', 'cat', 'bird']);

匿名类

支持通过new class 来实例化一个匿名类,用来替代一些“用后即焚”的完整类定义

interface A {
    public function log(string $msg);
}
class B {
}
// 实例化匿名类
var_dump(new class implements A {
    public function log(string $msg){}
});
var_dump(new class extends B{
});

Unicode codepoint 转译语法

接受一个以16进制形式的 Unicode codepoint,并用一个双引号或heredoc包围的 UTF-8 编码格式的字符串。 可以接受任何有效的 codepoint,并且开头的 0 是可以省略的

echo "\u{aa}";  // Output: a
echo "\u{0000aa}"; // Output: a
echo "\u{9999}"; // Output: 香
echo <<<EOF
  \u{9999}
EOF;         // Output:  香

Closure::call()

性能优化

unserialize()提供过滤

旨在提供更安全的方式解包不可靠的数据。它通过白名单的方式来防止潜在的代码注入

// 将所有的对象都转换为 __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]);

IntlChar

新增加的 IntlChar 类旨在暴露出更多的 ICU 功能。这个类自身定义了许多静态方法用于操作多字符集的 unicode 字符。

printf('%x', IntlChar::CODEPOINT_MAX); // Output: 10ffff
echo IntlChar::charName('@'); // Output: COMMERCIAL AT
var_dump(IntlChar::ispunct('!')); // Output: bool(true)
// 若要使用此类,请先安装Intl扩展

预期

预期是向后兼用并增强之前的 assert() 的方法。 它使得在生产环境中启用断言为零成本,并且提供当断言失败时抛出特定异常的能力。

老版本的API出于兼容目的将继续被维护,assert()现在是一个语言结构,它允许第一个参数是一个表达式,而不仅仅是一个待计算的 string或一个待测试的boolean

ini_set('assert.exception', 1);
class CustomError extends AssertionError {}
assert(false, new CustomError('Some error message'));
// Output:"Fatal error: Uncaught CustomError: Some error message"

PHP测试框架如:phpunit 中很常见

Group use declarations

从同一 namespace 导入的类、函数和常量现在可以通过单个 use 语句 一次性导入了。

// PHP 7 之前的代码
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+ 及更高版本的代码
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};

生成器可以返回表达式

此特性基于 PHP 5.5 版本中引入的生成器特性构建,它允许在生成器函数中通过使用 return 语法来返回一个表达式 (但是不允许返回引用值), 可以使用新方法 Generator::getReturn() 获取返回值,但该方法只能在生成器完成yielding values之后使用。

$gen = (function() {
    yield 1;
    yield 2;
    return 99;
})();
// echo $gen->getReturn(); 致命错误,因为Generator::getReturn()方法只能在生成器完成yielding values之后使用
foreach ($gen as $val) { // 生成器被迭代(yielding value)两次
    echo $val, PHP_EOL;
}

echo $gen->getReturn(), PHP_EOL;
//Output:
1
2
99

生成器委派

现在,只需在最外层生成器中使用 yield from,就可以把一个生成器自动委派给其他的生成器,Traversable 对象或 array

function gen()
{
    yield 1;
    yield 2;

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

整数除法函数 intdiv()

新加函数 intdiv() 用来进行整数的除法运算。

var_dump(intdiv(10, 3)); // Output: 3 其结果相当于 intval(10 / 3) Or (int)(10 / 3),但是性能肯定是intdiv更好

Session会话选项

session_start()可以接受一个 array 作为参数, 用来覆盖 php.ini 文件中设置的 会话配置选项。
These options have also been expanded to support session.lazy_write, which is on by default and causes PHP to only overwrite any session file if the session data has changed, and read_and_close, which is an option that can only be passed to session_start() to indicate that the session data should be read and then the session should immediately be closed unchanged.

session_start([
    'cache_limiter' => 'private',  // session在客户端的缓存方式,有nocache,private,private_no_expire,public;私有方式缓存 - private(比如:表单信息被保留,但在生存期内有效)
    'read_and_close' => true,      // 如果会话数据没有发生改变,那么 PHP 会在读取完session之后,立即关闭会话存储文件
]);

preg_replace_callback_array()优化

在 PHP 7 之前,当使用 preg_replace_callback() 函数的时候, 由于针对每个正则表达式都要执行回调函数,可能导致过多的分支代码。 而使用新加的 preg_replace_callback_array() 函数, 可以使得代码更加简洁。
现在,可以使用一个关联数组来对每个正则表达式注册回调函数, 正则表达式本身作为关联数组的键, 而对应的回调函数就是关联数组的值。

新增两个跨平台的随机函数

random_bytes() 用来产生高安全级别的随机字符串
random_int()      用来产生高安全级别的随机整数。 更早版本时只能使用相对较安全的过渡函数 mt_rand(),rand()就更不用说了。

list() 函数bug修复

在之前版本中,list() 不能保证正确展开实现了 ArrayAccess 接口的对象, 现在这个问题已修复。(list 不是真正的函数,而是语言结构)

其他特性

允许在克隆表达式上访问对象成员,例如: (clone $foo)->bar()。 不需要 $newFoo = clone  $foo; $newFoo->bar();分开两句来写

 

PHP 71 新特性

https://www.php.net/manual/zh/migration71.new-features.php
https://www.php.net/manual/en/migration71.new-features.php

可为空(Nullable)类型 

参数以及返回值的类型可以通过在类型前加上一个问号使之允许为空。 

function testReturn(): ?string  // 限定函数只能返回string or null
{
}

Void 函数

一个新的返回值类型void被引入。 返回值类型声明为 void 的方法要么没有 return 语句,要么 return 直接接分号 。(return null;不合法; return ;合法)

Symmetric array destructuring 对称数组分解

短数组语法([])现在作为list()语法的一个备选项,可以用于将数组的值赋给一些变量(包括在foreach中),且支持键名。

$data = [
    ["id" => 1, "name" => 'Tom'],
    ["id" => 2, "name" => 'Fred'],
];

// 等效,支持键名
list("id" => $id1, "name" => $name1) = $data[0];
["id" => $id1, "name" => $name1] = $data[0];

// 等效,支持键名
foreach ($data as list("id" => $id, "name" => $name)) {
    // logic here with $id and $name
}
foreach ($data as ["id" => $id, "name" => $name]) {
    // logic here with $id and $name
}

类常量可见性

 现在起支持设置类常量的可见性。 

class ConstDemo
{
    const PUBLIC_CONST_A = 1;
    public const PUBLIC_CONST_B = 2; // 关键字const之前可以指定 public、potected等
    protected const PROTECTED_CONST = 3;
    private const PRIVATE_CONST = 4;
}

引入iterable 伪类

引入了一个新的被称为 iterable 的伪类 (与callable类似)。 这可以被用在参数或者返回值类型中,它代表接受数组或者实现了Traversable接口的对象。 对于子类,当用作参数时子类的参数类型可以将父类的 array 或 Traversable 声明拓展到 iterable;对于返回值类型,子类可以将父类的返回类型 iterable 收紧到 array 或 实现 Traversable 的对象。

class A {
    function iterator(Traversable $iter): iterable
    {
        foreach ($iter as $val) {
            //
        }
    }
}
 // 合法的重写,编译通过
class B extends A {
    /**
     * @param iterable $iter 拓展参数类型 Traversable 到 iterable
     * @return array         收紧返回值类型 iterable 到 array
     */
    function iterator(iterable $iter): array
    {
        foreach ($iter as $val) {
            //
        }
    }
}

多异常捕获处理

一个catch语句块现在可以通过管道字符(|)来实现多个异常的捕获。 这对于需要同时处理来自不同类的不同异常时很有用。

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

支持为负的字符串偏移量

现在所有支持偏移量的字符串操作函数 都支持接受负数作为偏移量,包括通过[]{}操作字符串下标。在这种情况下,一个负数的偏移量会被理解为一个从字符串结尾开始的偏移量。

var_dump("abcdef"[-2]);              // Output: string (1) "e"
var_dump(strpos("aabbcc", "b", -3)); // Output: int(3)

$string = 'bar';
echo "The last character of '$string' is '$string[-1]'.\n"; // Output: The last character of 'bar' is 'r'.

ext/openssl 支持 AEAD模式

Support for AEAD (modes GCM and CCM) have been added by extending the openssl_encrypt() and openssl_decrypt() functions with additional parameters.

通过 Closure::fromCallable() 将callable转为闭包

Closure新增了一个静态方法,用于将callable快速转换为一个Closure 对象。

class Test
{
    /**
     * @return Closure
     * @internal 该函数把私有方法 privateFunction 暴露给了开发者
     */
    public function exposeFunction()
    {
        return Closure::fromCallable([$this, 'privateFunction']);
    }

    private function privateFunction($param)
    {
        var_dump($param);
    }
}

$closure = (new Test)->exposeFunction();
$closure('some value'); // Output: string(10) "some value"

异步信号处理(参见declare

一个新的名为 pcntl_async_signals() 的方法现在被引入, 用于启用无需 ticks (这会带来很多额外的开销)的异步信号处理。

pcntl_async_signals(true); // turn on async signals

pcntl_signal(SIGHUP,  function($sig) {
    echo "SIGHUP\n";
});

posix_kill(posix_getpid(), SIGHUP);
// Output: SIGHUP

 具体作用参考: https://www.gaojiufeng.cn/?id=238

HTTP/2 server push support in ext/curl

CURL扩展中增加了对服务器推送的支持(需要libcurl7.46及更高版本)。这可以通过 curl_multi_setopt() 函数和为常量 CURLMOPT_PUSHFUNCTION 选项设定一个推送回调(pushCallback)来激活该功能。

PHP71还新增了常量 CURL_PUSH_OK 和 CURL_PUSH_DENY ,用以表示批准或拒绝执行服务器推送的回调

Stream Context Options 

The tcp_nodelay stream context option has been added. 新增一个流上下文选项:tcp_nodelay

// connect to the internet using the '192.168.0.100' IP and port '7000'
$opts = array(
    'socket' => array(
        'bindto' => '192.168.0.100:7000',
    ),
    'tcp_nodelay' => true, // set SOL_TCP,NO_DELAY=1 appropriately, thus disabling the TCP Nagle algorithm. 设置SOL_TCP,NO_DELAY=1,从而禁用TCP Nagle算法
);

// create the context...
$context = stream_context_create($opts);

// ...and use it to fetch the data
echo file_get_contents('http://www.example.com', false, $context);

 

PHP 72 新特性

https://www.php.net/manual/zh/migration72.new-features.php
https://www.php.net/manual/en/migration72.new-features.php

新的对象类型

这种新的对象类型, object, 引进了可用于逆变(contravariant)参数输入和协变(covariant)返回任何对象类型。

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

test(new StdClass());

通过名称加载扩展

加载扩展时不再需要指定文件扩展名 (Unix下以.so为文件扩展名,在Windows下以 .dll 为文件扩展名) 。

比如:extension=mysqli 就可以了,而不用 extension=mysqli.so

允许重写抽象方法(Abstract method)

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;
}

使用Argon2算法生成密码散列

Argon2 已经被加入到密码散列(password hashing) API (这些函数以 password_ 开头), 以下是暴露出来的常量:

  • PASSWORD_ARGON2I
  • PASSWORD_ARGON2_DEFAULT_MEMORY_COST
  • PASSWORD_ARGON2_DEFAULT_TIME_COST
  • PASSWORD_ARGON2_DEFAULT_THREADS

新增 ext/PDO(PDO扩展) 字符串扩展类型

当你准备支持多语言字符集,PDO的字符串类型已经扩展支持国际化的字符集。以下是扩展的常量

  • PDO::PARAM_STR_NATL
  • PDO::PARAM_STR_CHAR
  • PDO::ATTR_DEFAULT_STR_PARAM
$db->quote('über', PDO::PARAM_STR | PDO::PARAM_STR_NATL); //这些常量通过 PDO::PARAM_STR 利用位运算OR进行计算

为 ext/PDO扩展新增额外的模拟调试信息

PDOStatement::debugDumpParams()方法已经更新,当发送SQL到数据库的时候,在一致性、行查询(包括替换绑定占位符)将会显示调试信息。这一特性已经加入到模拟调试中(在模拟准备打开时可用)。

ext/LDAP(LDAP扩展) 支持新的操作方式

LDAP 扩展已经新增了EXOP支持. 扩展暴露以下函数和常量:

ext/sockets(sockets扩展)添加了地址信息

sockets扩展现在具有查找地址信息的能力,且可以连接到这个地址,或者进行绑定和解析。为此添加了以下一些函数:

Parameter type widening

放宽参数类型限制:重写方法和接口实现的参数类型可以省略。不过这仍然是符合LSP,因为现在这种参数类型是逆变的。

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

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

允许使用逗号批量引入同一命名空间下的 trait 类

PHP 7中命名空间允许使用逗号进行分组引入。

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

其他特性

  • Windows下也支持 proc_nice()  函数
  • pack() 和 unpack() endian支持
  • 增强EXIF、ZIP扩展
  • SQLite3 allows writing BLOBs
  • ...

因为平时基本不会接触,所以具体参考英文文档

 

PHP 73 新特性

https://www.php.net/manual/zh/migration73.new-features.php
https://www.php.net/manual/en/migration73.new-features.php

更加灵活的Heredoc和Nowdoc语法

文档字符串的结束标记后面不再需要紧跟分号(;)或换行。另外,结束标记可以缩进,在这种情况下,缩进将从doc字符串中的每一行中删除。(可以使用空格或tab缩进,但是doc字符串和结束标记必须使用相同的缩进方式,要么都使用空格,要么都是tab,否则报错)

<?php
echo <<<'NOW'
    123
        456
    789
NOW // 此处可以省略分号,因为紧跟PHP结束标记 ?> // Output: (注意缩进:因为结束标记缩进了,所以doc字符串的每一行都删除相同的缩进)
123
456
789
<?php
$nowDoc = <<<'NOW'
123
456
789
NOW ; echo "ASD\n" . $nowDoc;
// Output:(注意缩进)
ASD
123
456
789

 对称数组分解支持引用赋值

 数组分解([])现在支持引用赋值,list() 也一样。

$d = ['I am A', ['bbb', 'I am C']];
[&$a, [$b, &$c]] = $d; // 变量$a, $c 是引用赋值

// [&$a, [$b, &$c]] =  ['I am A', ['bbb', 'I am C']]; 引用错误,编译不通过

Instanceof运算符接受字面量(Liters)

instanceof 现在允许字面量作为第一个操作数,在这种情况下,结果总是 FALSE。

PS:什么是字面量?

Value代表具体值,Literals则代表如何表达这个值。譬如说,15这是一个值,这个值是唯一的,但表达的方式有很多种:例如用阿拉伯数字写出来:15,用中文写出来:十五,用英文表达:fifteen,用16进制:0xF。15是value,后面的种种都是literal。

class A {
}
// 7.3之前前两个 var_dump 会编译错误
var_dump(A::class instanceof A); // Output: false
var_dump('A' instanceof A);      // Output: false 
var_dump(new A instanceof A);    // Output: true 
// 除了增强了 instanceof 容错性,暂时是没发现其他好处

异常类 CompileError 代替某些编译错误

A new CompileError exception has been added, from which ParseError inherits. A small number of compilation errors will now throw a CompileError instead of generating a fatal error. Currently this only affects compilation errors that may be thrown by token_get_all() in TOKEN_PARSE mode, but more errors may be converted in the future. 底层新增的一个 CompileError 异常类。少量编译错误的情况现在将引发CompileError,而不是抛出致命错误。目前,这只会影响在TOKEN_PARSE模式下token_get_all(),将来可能会转换更多错误。

Trailing Commas are allowed in Calls

允许调用方法、函数时使用逗号尾随。 官方文档中有人给出了这样的示例

// "Trailing commas in function and method calls are now allowed" means function parameters 尾随逗号,是针对函数或方法的参数而言的
function my1() {
    echo "xxxxxx\n";
}

function my2() {
    echo "yyyyyy\n";
}

my1(),my2(); // PHP Parse error:  syntax error

my1(,); // PHP Parse error:  syntax error

my1(1,); my2(2,); // OK

Argon2id 支持

The --with-password-argon2[=dir] configure argument now provides support for both Argon2i and Argon2id hashes in the password_hash()password_verify()password_get_info(), and password_needs_rehash() functions. Passwords may be hashed and verified using the PASSWORD_ARGON2ID constant. Support for both Argon2i and Argon2id in the password_*() functions now requires PHP be linked against libargon2 reference library ≥ 20161029.  大体就是新增了Argon2id哈希算法支持

FastCGI Process Manager(FPM)

添加了新选项以自定义FPM日志:

log_limit

此全局选项可用于设置日志行的日志限制,允许记录长度超过1024个字符的消息而不进行换行。它还修复了各种换行问题。

log_buffering

This global option allows an experimental logging without extra buffering. 此全局选项允许不借助其它缓冲的情况下进行experimental logging。

decorate_workers_output

This pool option allows to disable the output decoration for workers output when catch_workers_output is enabled.

BC Math 数学运算函数

bcscale() 现在也可以用作getter来检索当前使用的scale(之前只能设置不能检索,返回值是bool;现在既能设置又能检索,返回值是int)

bcscale(2) ;    // 设置所有bc数学函数的默认小数点保留2位小数
echo bcscale();  // 获取所有bc数学函数的默认小数点保留位数 Output: 2

Lightweight Directory Access Protocol

Full support for LDAP Controls has been added to the LDAP querying functions and ldap_parse_result():

Multibyte String Functions 多字节字符串函数

mbstring扩展库的一些函数得到增强,优化。

  1. 增加对 full case-mapping 和 full case-folding 的支持,与 simple case-mapping 不同,full case-mapping可能会更改字符串的长度。
    mb_strtoupper("Straße");
    // Produces STRAßE on PHP 7.2
    // Produces STRASSE on PHP 7.3
    mb_convert_case() 提供 casing mapping 和 case folding 两种不同的模式:
    • MB_CASE_LOWER (used by mb_strtolower())
    • MB_CASE_UPPER (used by mb_strtoupper())
    • MB_CASE_TITLE
    • MB_CASE_FOLD
    • MB_CASE_LOWER_SIMPLE
    • MB_CASE_UPPER_SIMPLE
    • MB_CASE_TITLE_SIMPLE
    • MB_CASE_FOLD_SIMPLE (used by case-insensitive operations)
    Only unconditional, language agnostic full case-mapping is performed. 【只有无条件的、语言无关的 full case-mapping 被执行?】
  2. 不区分大小写的字符串操作,现在比较时使用 case-folding 而不是 case-mapping。这意味着现在有更多的字符将被当成是相同的(大小写不敏感)。
  3. 使用 MB_CASE_TITLE 进行 mb_convert_case() 时,会基于大小写和大小写可忽略的派生Unicode属性执行 title-case(标题大小写)转换。特别是,这还改进了引号和撇号的处理。
  4. The Multibyte String data tables have been updated for Unicode 11.
  5. 现支持正确处理大于2GB的字符串。
  6. 性能改进提升,最大的改进是大小写转换函数。
  7. mb_ereg_x*函数现在支持命名捕获。匹配函数,如:mb_ereg() 现在将使用组号和组名返回命名捕获,类似于PCRE:
    mb_ereg('(?<word>\w+)', '国', $matches);
    // Output: [0 => "国", 1 => "国", "word" => "国"];
    
    // 另外, 在字符串替换时 mb_ereg_replace() 现支持用 \k<> and \k'' 符号来引用命名捕获: 
    mb_ereg_replace('\s*(?<word>\w+)\s*', "_\k<word>_\k'word'_", ' foo ');
    // Output: "_foo_foo_"

    \k<> and \k'' can also be used for numbered references, whi


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap