PHP 8.0.x 更新内容

193 阅读3分钟

新特性 ¶

PHP 核心中的新特性 ¶

命名参数 ¶

新增命名参数的功能。

注解(Attributes) ¶

新增注解的功能。

构造器属性提升(Constructor Property Promotion) ¶

新增构造器属性提升功能 在构造函数中声明类的属性)。

联合类型 ¶

新增 联合类型

Match 表达式 ¶

新增 match 表达式

Nullsafe 运算符 ¶

新增Nullsafe 运算符(?->)。

其他新特性 ¶

  • 新增 WeakMap 类。

  • 新增 ValueError 类。

  • 现在,只要类型兼容,任意数量的函数参数都可以用一个可变参数替换。 例如允许编写下面的代码:

    <?php class A { public function method(int $many, string $parameters, $here) {} } class B extends A { public function method(...$everything) {} } ?>

  • static ("后期静态绑定"中) 可以作为返回类型:

    <?php class Test { public function create(): static { return new static(); } } ?>

  • 现在可以通过 $object::class 获取类名,返回的结果和 get_class($object) 一致。

  • newinstanceof 可用于任何表达式, 用法为 new (expression)(...$args) 和 $obj instanceof (expression)

  • 添加对一些变量语法一致性的修复,例如现在能够编写 Foo::BAR::$baz

  • 添加 Stringable interface, 当一个类定义 __toString() 方法后会自动实现该接口。

  • Trait 可以定义私有抽象方法(abstract private method)。 类必须实现 trait 定义的该方法。

  • 可作为表达式使用 throw。 使得可以编写以下用法:

    <?php $fn = fn() => throw new Exception('Exception in arrow function'); $user = $session->user ?? throw new Exception('Must have user');

  • 参数列表中的末尾逗号为可选。

    <?php function functionWithLongSignature( Type1 $parameter1, Type2 $parameter2, // <-- 这个逗号也被允许了 ) { }

  • 现在允许 catch (Exception) 一个 exception 而无需捕获到变量中。

  • 支持 mixed 类型。

  • 父类中声明的私有方法不在对子类中的方法执行任何继承规则(final private 构造函数除外)。下列示例说明删除了那些限制:

    <?php class ParentClass { private function method1() {} private function method2() {} private static function method3() {} // 抛出警告,因为“final”不再有效: private final function method4() {} } class ChildClass extends ParentClass { // 现在允许以下所有内容,即使修饰符与父类中的私有方法不同。 public abstract function method1() {} public static function method2() {} public function method3() {} public function method4() {} } ?>

不向后兼容的变更 ¶

PHP 核心中不向后兼容的变更 ¶

字符串与数字的比较 ¶

数字与非数字形式的字符串之间的非严格比较现在将首先将数字转为字符串,然后比较这两个字符串。 数字与数字形式的字符串之间的比较仍然像之前那样进行。 请注意,这意味着 0 == "not-a-number" 现在将被认为是 false 。

ComparisonBeforeAfter
0 == "0"truetrue
0 == "0.0"truetrue
0 == "foo"truefalse
0 == ""truefalse
42 == " 42"truetrue
42 == "42foo"truefalse

其它不向后兼容的变更 ¶

  • match 现在是一个保留字。
  • 断言(Assertion)失败现在默认抛出异常。如果想要改回之前的行为,可以在 INI 设置中设置 assert.exception=0 。
  • mixed 现在是保留字,所以不能用于类,接口或者 trait,也禁止在命名空间中使用。
  • 与类名相同的方法名将不再被当做构造方法。应该使用__construct() 来取代它。
  • 不再允许通过静态调用的方式去调用非静态方法。因此is_callable()在检查一个类名与非静态方法 时将返回失败(应当检查一个类的实例)。
  • (real) 和 (unset) 转换已被移除。
  • 移除 track_errors 执行。这意味着不能再用 php_errormsg。可以改用 error_get_last() 函数。
  • 移除定义不区分大小写的常量功能。define() 的第三个参数可能不再为 true
  • 移除使用 __autoload() 函数指定自动加载器的功能。应该改用 spl_autoload_register()
  • errcontext 参数将不再传递给使用 set_error_handler() 设置的自定义错误处理程序。
  • 移除 create_function()。应该改用匿名函数。
  • 移除 each()。应该改用 foreach 或者 ArrayIterator
  • 移除在方法中使用 Closure::fromCallable() 或 ReflectionMethod::getClosure() 创建的匿名函数中解绑 this 的能力。
  • The ability to unbind this from proper closures that contain uses of this has also been removed.
  • 移除对对象使用 array_key_exists() 的能力。应该改用 isset() 或 property_exists()
  • array_key_exists() 中 key 参数类型的行为已经和 isset() 和正常数组访问一致。所有的 key 类型现在使用通用的强制转换,数组/对象 key 会抛出 TypeError
  • 任意一个数组,将数字 n 作为第一个数字 key,下一个隐式键将会是 n+1。即使 n 为负数也是如此。
  • error_reporting 默认级别现在是 E_ALL。之前排除 E_NOTICE 和 E_DEPRECATED
  • 现在默认启用 display_startup_errors
  • 在没有父级的类中使用 parent 将会导致 fatal compile-time 错误。
  • @ 操作将不再屏蔽 fatal 错误(E_ERRORE_CORE_ERRORE_COMPILE_ERRORE_USER_ERRORE_RECOVERABLE_ERRORE_PARSE)。当使用 @ 时,接受 error_reporting 为 0 的错误处理程序,应该调整为使用位掩码检查: