PHP 8.2.0正式发布,支持分离范式类型,引入新的随机数扩展

6392864838b8ePHP8.2 是 PHP 语言现代化进程中的一个重要的里程碑。除了令人兴奋地新特性和改进之外,PHP8.2 还简化了语言,取消了对动态类属性的支持,在遇到某些非最优的 ini 配置时发出警告,并修复了一些影响 PHP 数组排序和某些类型的字符串转换 / 编码操作的遗留 PHP 行为。

系统改进

PHP8.2 解决了 PHP 类型系统的几个缺点和限制,允许 PHP 应用采用更好的类型安全。包括添加了 true 类型,允许 null 和 false 作为独立的类型使用,并支持 DNF 类型(泛型解析)。

PHP8.2 支持分离范式类型,现在可以进行组合联合类型和交际类型,这可以定义声明精确而富有表现力的参数、返回值和属性。

php8.2 之前

<span class="hljs-class"><span class="hljs-keyword">class</span></span> <span class="hljs-class"><span class="hljs-title">Foo</span></span> {
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span></span> <span class="hljs-function"><span class="hljs-title">bar</span></span><span class="hljs-function"><span class="hljs-params">(</span></span><span class="hljs-function"><span class="hljs-params">mixed</span></span> <span class="hljs-function"><span class="hljs-params">$entity</span></span><span class="hljs-function"><span class="hljs-params">)</span></span> {
        <span class="hljs-keyword">if</span> ((($entity <span class="hljs-keyword">instanceof</span> A) && ($entity <span class="hljs-keyword">instanceof</span> B)) || ($entity === <span class="hljs-keyword">null</span>)) {
            <span class="hljs-keyword">return</span> $entity;
        }

        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-keyword">Exception</span>(<span class="hljs-string">'Invalid entity'</span>);
    }
}

现在

<span class="hljs-class"><span class="hljs-keyword">class</span></span> <span class="hljs-class"><span class="hljs-title">Foo</span></span> {
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span></span> <span class="hljs-function"><span class="hljs-title">bar</span></span><span class="hljs-function"><span class="hljs-params">(</span></span><span class="hljs-function"><span class="hljs-params">(</span></span><span class="hljs-function"><span class="hljs-params">A</span></span><span class="hljs-function"><span class="hljs-params">&</span></span><span class="hljs-function"><span class="hljs-params">B</span></span><span class="hljs-function"><span class="hljs-params">)</span></span><span class="hljs-function"><span class="hljs-params">|</span></span><span class="hljs-function"><span class="hljs-params">null</span></span> <span class="hljs-function"><span class="hljs-params">$entity</span></span><span class="hljs-function"><span class="hljs-params">)</span></span> {
        <span class="hljs-keyword">return</span> $entity;
    }
}

支持 true 和 false 作为独立的类型,如果 bool 始终相同的时候可以用它来声明。

<span class="hljs-function"><span class="hljs-keyword">function</span></span> <span class="hljs-function"><span class="hljs-title">alwaysReturnsFalse</span></span><span class="hljs-function"><span class="hljs-params">(</span></span><span class="hljs-function"><span class="hljs-params">)</span></span>: <span class="hljs-literal">false</span> {}

<span class="hljs-function"><span class="hljs-keyword">function</span></span> <span class="hljs-function"><span class="hljs-title">alwaysReturnsNull</span></span><span class="hljs-function"><span class="hljs-params">(</span></span><span class="hljs-function"><span class="hljs-params">)</span></span>: null {}

<span class="hljs-function"><span class="hljs-keyword">function</span></span> <span class="hljs-function"><span class="hljs-title">alwaysReturnsTrue</span></span><span class="hljs-function"><span class="hljs-params">(</span></span><span class="hljs-function"><span class="hljs-params">)</span></span>: <span class="hljs-literal">true</span> {}

其中 null 的类型在之前的版本中就可以在联合类型声明中使用,现在可以独立使用了。

只读类

PHP8.1 增加了一个 readonly 的属性声明。一个 readonly 的属性只能设置一次,并且 PHP 会阻止任何作用域内的修改。

PHP8.2 对 readonly 声明进行更进一步的使用,可以将类声明为 readonly。当一个类被声明为 readonly,它的所有属性都会自动声明 readonly。此外,这个类不能使用动态属性,以确保所有的属性都是有定义的。

<span class="hljs-keyword">readonly</span> <span class="hljs-keyword">class</span> <span class="hljs-title">User</span> {
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> $username;
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> $uid;
}

所有的属性都会自动声明城 readonly。

新的随机数扩展

在 PHP 的历史发展中,它支持各种各样的随机数生成器,他们有不同程度的性能和不同的用例,并且适合安全应用程序。PHP8.2 更进一步,将所有与随机数相关的功能重构为一个名为 random 的扩展。新的扩展不会破坏任何现有的接口使用,因此现有的 rand,mt_rand 函数将继续工作,不需要任何更改。它还提供了一个对象接口,用可插拔的体系生成随机数,因此很容易模拟随机数生成器并提供新的随机数生成器,从而市 PHP 应用程序安全且易于测试。

trait 常量

在 PHP8.2 中,可以在 trait 中声明常量。trait 不能直接访问,但当类使用 trait 时,这些常量就变成了类的常量。

<span class="hljs-keyword">trait</span> Foo
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">const</span> CONSTANT = <span class="hljs-number">1</span>;
}

<span class="hljs-class"><span class="hljs-keyword">class</span></span> <span class="hljs-class"><span class="hljs-title">Bar</span></span>
{
    <span class="hljs-keyword">use</span> <span class="hljs-title">Foo</span>;
}

var_dump(Bar::CONSTANT); <span class="hljs-comment">// 1</span>
var_dump(Foo::CONSTANT); <span class="hljs-comment">// Error</span>

敏感参数支持

PHP8.2 新增了一个内置参数属性命名:#[\SensitiveParameter]。能够使 PHP 在堆栈跟踪和错误消息中隐藏掉实际值。

我们经常会在参数或属性中定义密码、秘钥或其他敏感信息。当 PHP 发生错误时,这些值会被记录下来。显示到屏幕上或者记录到日志中。这样人们就能通过这些方式得到敏感数据。

比如下面的例子:

<span class="hljs-function"><span class="hljs-keyword">function</span> </span><span class="hljs-function"><span class="hljs-title">passwordHash</span></span><span class="hljs-function"><span class="hljs-params">(</span></span><span class="hljs-function"><span class="hljs-params">#</span></span><span class="hljs-function"><span class="hljs-params">[</span></span><span class="hljs-function"><span class="hljs-params">\SensitiveParameter</span></span><span class="hljs-function"><span class="hljs-params">]</span></span><span class="hljs-function"><span class="hljs-params"> string $password</span></span><span class="hljs-function"><span class="hljs-params">)</span></span>  {

       debug_print_backtrace();

 }

 passwordHash(<span class="hljs-string">'hunter2'</span>);

打印的内容如下:

array(<span class="hljs-number">1</span>) {

[<span class="hljs-meta">0</span>]=> array(<span class="hljs-number">4</span>) {

  [<span class="hljs-meta"><span class="hljs-meta-string">"file"</span></span>]=> <span class="hljs-keyword">string</span>(<span class="hljs-number">38</span>) <span class="hljs-string">"..."</span>

  [<span class="hljs-meta"><span class="hljs-meta-string">"line"</span></span>]=> <span class="hljs-keyword">int</span>(<span class="hljs-number">9</span>)

  [<span class="hljs-meta"><span class="hljs-meta-string">"function"</span></span>]=> <span class="hljs-keyword">string</span>(<span class="hljs-number">3</span>) <span class="hljs-string">"foo"</span>

  [<span class="hljs-meta"><span class="hljs-meta-string">"args"</span></span>]=> array(<span class="hljs-number">1</span>) {

     <span class="hljs-comment">// [0]=> string(38) "hunter2" 这一行不会被打印出来</span>

     [<span class="hljs-meta">0</span>]=> <span class="hljs-keyword">object</span>(SensitiveParameterValue)<span class="hljs-meta">#1 (0) {}</span>

  }
 }
}

hunter2 不会被打印出来。

新的函数和类

解析 INI 数量值:ini_parse_quantity

将 PHP ini 值识别成字节。

<span class="hljs-selector-tag">ini_parse_quantity</span>(<span class="hljs-string">'256M'</span>); <span class="hljs-comment">// 268435456</span>

curl 维持活动:<strong>curl_upkeep</strong>

在 PHP8.2 中,curl 扩展会触发底层 curl 库来运行必要任务,以保持 curl 连接存活。最常见的用法就是定期调用 curl_upkeep 来实现 http 持久连接(keep-alive)。

检索密码长度:<strong>openssl_cipher_key_length</strong>

在 PHP8.2 OpenSSL 中,有一个名为 openssl_cipher_key_length 的函数,能够接受任何支持的密码所需的秘钥长度,在之前需要硬编码才能实现:

<span class="hljs-selector-tag">openssl_cipher_key_length</span>(<span class="hljs-string">"CHACHA20-POLY1305"</span>); <span class="hljs-comment">// 32</span>
<span class="hljs-selector-tag">openssl_cipher_key_length</span>(<span class="hljs-string">"AES-128-GCM"</span>); <span class="hljs-comment">// 16</span>
<span class="hljs-selector-tag">openssl_cipher_key_length</span>(<span class="hljs-string">"AES-256-GCM"</span>); <span class="hljs-comment">// 32</span>

重置记录的峰值内存使用量:<strong>memory_reset_peak_usage</strong>

这对于多次调用或迭代调用时很有用。

PHP8.2 中的弃用

PHP8.2 也带来了相当一部分的弃用。当语法、函数和特性被弃用时,PHP 会发起一个弃用通知,该通知不应该中断 PHP 程序,但会被记录到错误日志中。

注意:PHP8.0 以后,PHP 的默认错误报告行为是 E_ALL

已弃用动态属性

PHP8.2 中最值得注意的弃用之一就是弃用动态属性。如果一个类属性没有声明就被调用或赋值,就会退出程序。

<span class="hljs-class"><span class="hljs-keyword">class</span></span> <span class="hljs-class"><span class="hljs-title">User</span></span> {
    <span class="hljs-keyword">public</span> int $uid;
}

$user = <span class="hljs-keyword">new</span> User();
$user->name = <span class="hljs-string">'Foo'</span>;

这个可能会影响到很多的的 PHP 遗留程序,推荐的修复方法是在类型中声明属性。

对此也有例外用法,比如 stdClass 和它的子类将正常使用,__get 和__set 魔术方法将正常使用,或者声明 #AllowDynamicProperties。

其他一些弃用可以关注本站其他文章:

《PHP8.2 中字串变量解析的新用法》https://phpreturn.com/index/a628de16a2adf8.html

安装和升级到 PHP8.2

PHP 8.2 现在可以在所有常规源代码中下载 / 安装:

  • Windows: 编译后的二进制文件可在 windows.php.net
  • Ubuntu/Debian: PHP 8.2 可用 ondrej/phpPPA
  • Fedora/RHEL/CentOS/Alma/Rocky: 可以在 Remi 的源中获取
  • Mac OS: PHP 8.2 可以通过 Homebrew 安装 shivammathur/homebrew-php 利用.
  • Docker:可以通过 8.2 * 版本获取 PHP 8.2

639291da621fb639291db16522

更详细的变动,作者将持续跟进发布。欢迎关注收藏。

原文标题:PHP8.2 发布了!

原文地址:https://phpreturn.com/index/a639285aa925ed.html

原文平台:PHP 武器库

订阅评论
提醒
guest的头像

0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x