PHP 7.3。 最新消息


句法


  1. 软化Heredoc和Nowdoc语法要求
  2. 支持函数和方法调用中的尾部逗号
  3. list()链接list()

不推荐使用的功能(不推荐使用)


  1. 不推荐使用image2wbmp()函数
  2. 使用FILTER_VALIDATE_URLFILTER_FLAG_HOST_REQUIRED使用标志FILTER_FLAG_SCHEME_REQUIREDFILTER_VALIDATE_URL
  3. 注册不赞成使用的独立常量

新功能


  1. 可选的json_decode json_encodejson_decode错误的异常
  2. 添加is_countable()函数
  3. 添加函数array_key_first()array_key_last()

变化


  1. 从PCRE迁移到PCRE2

软化Heredoc和Nowdoc语法要求


HeredocNowdoc要求将结束标识符放在新行的开头


一个例子:


 $foo = <<<IDENTIFIER the crazy dog jumps over the lazy fox "foo" bar; IDENTIFIER 

在这里,结束IDENTIFIER 必须是新行上的第一个字符,此功能才能起作用。 此外,在结束标识符之后不应有任何其他字符(;;;这是可选的)。


PHP 7.3的RFC建议删除这些要求以提高代码的可读性。 首先,在使用heredoc/nowdoc标识符时添加缩进。


heredoc/nowdoc语法更改的完整列表:


  1. 结束标识符不必是字符串中的第一个字符。
  2. 结束标识符以空格或制表符缩进。
  3. 缩进(空格或制表符)不应混用。 如果执行此操作,则会出现“ Parse error: Invalid indentation - tabs and spaces cannot be mixed in .. on line ..
  4. 在结束标识符之前使用的空格/制表符的确切数量将从heredoc/nowdoc表达式的每一行中删除。
  5. 如果在结束标识符之前使用的缩进字符数大于表达式的任何行,则将出现Parse error: Invalid body indentation level (expecting an indentation level of at least ..) in .. on line ..
  6. 结束符后的几个表达式将正常工作

这是一个在不破坏新规则的情况下利用新功能的代码段:


 $foo = ['foo', 'bar', <<<EOT baz - hello world! -- ahoy EOT, 'qux', 'quux' ]; var_dump($foo); 

输出将是:


 array(5) {        [0]=>           string(3) "foo" [1]=>           string(3) "bar" [2]=>           string(29) "baz - hello world! -- ahoy" [3]=> string(3) "qux" [4]=> string(4) "quux" }     ` 

注意,使用heredoc的声明中使用的缩进未显示在var_dump()的输出中,并且我们继续在EOT标识符之后列出数组的元素。


RFC 关于Externals.io的讨论 实现


向后兼容性影响


除非您使用一组相同的heredox/nowdoc字符标识符作为行的开头, heredox/nowdoc您将heredox/nowdoc


 $foo = <<<HELLO HELLO_WORLD <--         HELLOWORLD <--     HELLO WORLD <--    HELLO; 

如果您具有与上述类似的heredoc/nowdoc语法,请注意,在PHP 7.3中,PHP将接受第一个HELLO文字,并在下一行抛出错误。 在早期版本中, HELLO WORLD未被视为heredoc的结束标识符。 谢谢/ u /带有reddit的ImSuperObjective2 指出了这一点


支持函数和方法调用中的尾部逗号


这是一个简单的更改,允许在函数调用和方法中使用结尾逗号。 这不会影响声明。


例如,以下语法将变为可能:


 //  foo('bar', 'baz',); //        'baz' 

在PHP-7.3之前的版本中,上面的代码段引发PHP Parse error: syntax error, unexpected ')' in .. on line ..


末尾不能使用多个逗号,也不能使用逗号跳过参数。 这主要是对具有可变参数的函数的更改。 同样,通过新的编辑,数组语法将看起来更加一致。


注意,您不能在函数/方法声明中使用此功能; 这是错误的:


 function foo($bar, $baz, ) { // nah, you can't do this. } 

RFC 关于Externals.io的讨论 实现


向后兼容性影响


没事 现有代码将继续起作用。 如果您具有接受可变参数的函数调用,请在这些位置添加尾部逗号以方便使用。 但是到处使用它们显然太多了。


list()链接list()


list()函数对于将值快速分配给数组中的变量很有用。 在PHP 7.3之前,无法通过引用指定变量。 在PHP 7.3之前,以下代码段导致了致命错误:


 $arr = ['apple', 'orange']; list($a, &$b) = $arr; $b = 'banana'; echo $arr[1]; // Fatal error: [] and list() assignments cannot be by reference in .. on line .. 

不可能引用non-referencable变量: list($a, &$b) = [12, 14]; 会出现Fatal error: Cannot assign reference to non referencable value in .. on line ..


RFC 关于Externals.io的讨论 实现


向后兼容性影响


不行 建议您不要使用list()来填充多个变量,而建议您使用值对象使事情更简单。 它们仍将通过引用传递,但会使您的代码更清晰。


不推荐使用image2wbmp()函数


GD扩展中的image2wbmp()函数用于以WBMP(无线位图)格式输出图像。 在PHP 7.3中,不推荐使用imagewbmp()函数。


如果使用image2wbmp() ,则只需将函数名称替换为imagewbmp ,一切都会好起来! 在github上有超过5,500 image2wbmp() ,而有超过39,300 imagewbmp() 。 看起来PHP开发团队正在删除较少使用的功能,以最大程度地减少影响。


RFC 关于Externals.io的讨论 实现


向后兼容性影响


如果使用image2wbmp()函数,则将调用替换为imagewbmp 。 利用可以为您改变这一点的自动化。


使用FILTER_VALIDATE_URLFILTER_FLAG_HOST_REQUIRED使用标志FILTER_FLAG_SCHEME_REQUIREDFILTER_VALIDATE_URL


这是向前运动。 使用filter_var($var, FILTER_VALIDATE_URL) ,可以设置两个附加标志来确保严格的URL检查: FILTER_FLAG_SCHEME_REQUIREDFILTER_FLAG_HOST_REQUIRED
从PHP 5.2.1开始,无论是否设置,这两个标志都隐式应用。


如果您的代码使用这些标志,只需删除它们即可。 当前有超过5,000个使用它们的github搜索结果。


RFC 关于Externals.io的讨论 实现


向后兼容性影响


由于这两个标志均已弃用,因此您将看到类似以下的通知:


 Deprecated: filter_var(): explicit use of FILTER_FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED is deprecated in ... 

您所要做的就是删除两个标志,因为 使用FILTER_VALIDATE_URLFILTER_VALIDATE_URL暗含了它们。


注册不赞成使用的独立常量


define()函数允许您在不区分大小写的模式下声明一个常量。 您必须通过传递函数的第三个参数true来显式声明一个区分大小写的常量。 这不是默认行为,并且可能与通过const关键字声明常量的能力不一致。


 define('Foo', 'Bar', true); 

上面的代码将引发过时通知: Deprecated: define(): Declaration of case-insensitive constants is deprecated in ...


此外,当您尝试访问以Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "Foo"FOO )模式声明的常量时,您将看到一个非常有用的警告: Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "Foo" Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "Foo"


RFC 关于Externals.io的讨论 实现


向后兼容性影响


您将必须转到基本代码,在该代码中声明与寄存器无关的常量,然后对其进行更正。 这极不可能出现任何问题,因为要捕获所有用例相当费力,但是结果代码将变得更加清晰。


我没有在github上找到这种用法的任何示例,但是至少Drupal和WordPress(两个相当老而成熟的PHP项目)具有不区分大小写的常量。


可选的json_decode json_encodejson_decode错误的异常


我的最爱之一。 这些年来, json_encode()json_decode()对PHP变量或json字符串中的错误保持沉默,这些错误导致代码被标记。 甚至在著名的PHP批评中也是如此:糟糕的设计分形


json_decode对于无效输入返回null,而对于解码的JSON,null是绝对真实的对象。 除非您每次使用时都调用json_last_error ,否则此函数是完全不可靠的。

在那篇博客文章之后花了6年的时间,我们有机会对json失败提出了一个错误:


 try { json_decode("{", false, 512, JSON_THROW_ON_ERROR); } catch (\JsonException $exception) { echo $exception->getMessage(); //  "Syntax error" } 

新的\JsonException\Exception的后代,并且JSON_THROW_ON_ERROR常量和JsonException本身位于全局命名空间中。


我强烈建议您开始使用此功能。 有第三方库,例如daverandom / exception-json ,它们为PHP 7.2及更低版本实现了类似的功能。 随着此功能在PHP内核中的出现,您可以在使用json的每个位置使用json_last_error()调用删除此程序包和大量丑陋的模板代码。


RFC 关于Externals.io的讨论 实现


向后兼容性影响


如果您没有使用自己的具有相同名称的异常和/或常量,则什么也没有。


添加is_countable()函数


PHP 7.2具有许多过时和错误的功能。 如果您使用的是PHP 7.2。 使用不可countable变量调用count() ,则PHP将显示有关此警告。 在一般的编辑中,建议在使用count()之前检查结果变量是否countable count()


countable -variable是实现\Countable接口的数组或对象。 由于在验证过程中将使用大量样板代码,因此PHP 7.3引入了一个新函数is_countable() ,该函数检查变量...很好...使用count()的可能性。


如果您现在想开始使用此功能,我为is__countable()写了一个多文件


RFC 关于Externals.io的讨论 实现


向后兼容性影响


is_countable()自己的函数is_countable() ,不会有任何问题。


添加函数array_key_first()array_key_last()


PHP中有75种不同的函数可用于处理数组,但到目前为止,还没有一种简单的方法来获取数组的第一个键和最后一个键而不更改数组指针或枚举所有键(通过array_keys() )然后获取第一个/最后一个值。


array_key_first()两个新功能, array_key_first()array_key_last()允许您执行此操作。


RFC还建议添加array_value_first()array_value_last() ,但是这部分未通过投票。


RFC 关于Externals.io的讨论 实现


向后兼容性影响


如果您没有声明自己的array_key_first()array_key_last()函数,那么就没问题。


从PCRE迁移到PCRE2


PHP使用Perl兼容的正则表达式或库中不久的PCRE来处理正则表达式。 自PHP 7.2起,已使用PCRE旧版库的8.x版本,而在PHP 7.3中将使用PCRE2。 请注意,尽管PCRE2与PCRE(8.x)在很大程度上兼容,但它被视为一个新库。


新库在模式验证方面更具侵略性,并可能导致现有代码出错。 以下代码段对PHP 7.3无效:


 preg_match('/[\w-.]+/', ''); 

PHP将发出Warning: preg_match(): Compilation failed: invalid range in character class at offset 3
模式的问题:为使之起作用,必须将连字符移至末尾或转义。


 preg_match('/[\w\-.]+/', ''); 

上面的代码不仅适用于PHP 7.3,而且适用于旧版本。 在新模式中,连字符被转义为\- 。 解决兼容性问题时,这是最常见的问题。


这是一个很小的更改,但是有可能一切都会出错。 错误消息指示字符在正则表达式中的确切位置。 请务必仔细检查您的代码。 通过正则Regex Buddy或其他类似软件,检查您的正则表达式与PCRE2语法的兼容性。 有关更多信息,请参见PCRE2语法和传统PCRE语法的描述。


RFC 关于Externals.io的讨论 实现


向后兼容性影响


由于PCRE2对模板更加挑剔和严格,因此某些preg_match()和类似的调用可能无法正常工作。 解决方法从简单地更新模板(例如,转义连字符)到重写模板不等。 确保所有测试通过。

Source: https://habr.com/ru/post/zh-CN422507/


All Articles