7.3是一个bug修复版本 7.0是5.6版速度的2倍,7.3比7.0快22%(反正我没测过)
PHP 7.3正在敲响我们的大门,它带来了新的实用功能,并弃用大量的错误和修复旧有BUG,目前的Beta 2版本于8月16日发布。
您可以下载当前的PHP 7.3版本以进行开发和测试,但请记住,目前这不应该在生产环境中使用。
在这篇文章中,我们将概述我认为最相关的功能和变化。但是,您可以随时查看PHP 7.3升级说明和PHP 7.3请求注释中的功能,更改和错误修复的完整列表。
这可能是PHP 7.3中最相关的改进之一,我认为值得更多关注。因此,在深入研究PHP 7.3 heredoc / nowdoc之前,我们将快速概述这个有用的核心功能。
heredoc语法提供了一种添加大量文本的方法,而无需像双引号那样转义。一个heredoc开始<<<后跟一个标记,并以相同的标记结束,然后是分号。这是一个例子:
print <<
nowdoc的行为很像heredoc,但有一些例外:
标识符用单引号括起来(<<<‘EOT’)
在nowdoc内部没有解析
这是nowdoc的一个例子:
print <<<'EOT'
Nowdocs are to single-quoted strings what heredocs are to double-quoted strings.
EOT;
Heredocs和nowdocs共享相同的规则来规范结束标记的使用:
结束标记必须从该行的第一列开始
标记必须遵循与PHP中任何其他标签相同的命名规则:它必须仅包含字母数字字符和下划线,并且必须以非数字字符或下划线开头。
PHP手册警告:
请注意,除了分号(;)之外,具有结束标识符的行必须不包含其他字符,这一点非常重要。这尤其意味着标识符可能不会缩进,并且在分号之前或之后可能没有任何空格或制表符。同样重要的是要意识到结束标识符之前的第一个字符必须是本地操作系统定义的换行符。这是\n在UNIX系统上,包括macOS。结束分隔符也必须后跟换行符。
PHP 7.2语法无效:
class foo {
public $bar = <<
PHP 7.2有效语法:
class foo {
public $bar = <<
为了简短起见,在PHP 7.2中:
结束标记可能不会缩进
带有结束标记的行可能不包含空格或制表符等字符
结束标记之前的第一个字符必须是换行符
结束标记必须后跟换行符
很明显,heredoc和nowdoc语法是相当严格的,但PHP 7.3可能会通过以下改进稍微改变一下。
使用PHP 7.3,我们可以缩进结束标记,我们可以安全地编写以下代码:
class foo {
public $bar = <<
结束标记的缩进设置将从主体的每一行剥离的空白(或制表符)的数量。但要小心:关闭标记不应该比身体的任何其他线进一步缩进。
请参阅以下代码:
class foo {
public $bar = <<
上面的代码会发出以下解析错误:
解析错误:行%d上的%s中的体缩进级别(期望至少缩进…)无效
剥离制表符和空格允许我们将heredoc / nowdoc的主体缩进到周围代码的相同级别,并且在主体的每一行之前没有不必要的空格。
我们可以使用制表符和空格来缩进,但我们不允许混合使用它们。这意味着我们必须对结束标记和正文的任何行使用相同的缩进字符。如果有不同的缩进字符,我们会期望一种不同类型的解析错误(无效缩进)。
目前,新行必须遵循标记才能终止heredoc / nowdoc。PHP 7.3会改变这一点,并允许我们在同一行终止heredoc / nowdoc。这是RFC的一个例子:
PHP 7.2有效语法:
$values = [<<
PHP 7.3有效语法:
$values = [<<
无论如何,在选择标记的名称时要小心,因为“偶尔”如果它与你在heredoc / nowdoc主体中使用的单词相匹配,你可能会遇到错误。
尾随逗号(或“最终逗号”)是附加到元素,参数或属性列表的逗号,它们在频繁附加新值的上下文中派上用场,因为它们可以防止由于缺少逗号而导致的错误。在PHP中,允许在数组中使用尾随逗号,从PHP 7.2开始,它们在分组命名空间中是允许的。
从PHP 7.3开始,函数声明中将允许使用尾随逗号。变量函数提供了一个上下文示例,其中尾随逗号非常有用:
foo(
$bar,
$baz,
);
我们在创建数组时可以使用尾随逗号compact(),以便返回格式化字符串sprintf(),或者合并数组时:
$newArray = array_merge(
$arrayOne,
$arrayTwo,
['foo', 'bar'],
);
此外,尾随逗号对调试很有用:
var_dump(
$foo,
$bar,
$baz,
);
强大
unset()和isset():
unset(
$foo,
$bar,
$baz,
);
isset(
$foo,
$bar,
$baz,
);
方法调用和附件中也允许使用尾随逗号。
注意:此更改仅影响函数调用。函数声明语法不会改变。此外,不允许使用独立逗号,多个尾随逗号和引号。
PHP 7.3带来的最受欢迎的功能之一提供了一种处理JSON错误的新方法。这不是核心功能,而是JSON扩展的一个补充,它将改变json_decode()和json_encode()的错误行为。
目前,json_decode()返回null错误,但null也可以是有效的结果。这可能令人困惑,因为
只能通过调用json_last_error()或者知道是否发生错误json_last_error_msg(),它分别以机器可读和人类可读的形式返回全局错误状态。- PHP RFC
json_encode()返回FALSE错误。这更清楚,因为存在特定的错误值。无论如何,这两个函数既不会在出错时停止程序执行,也不会抛出任何警告。
PHP 7.3的提议:
该RFC而是提出了添加新的选项标志值json_decode()和json_encode(),JSON_THROW_ON_ERROR。传递此标志时,会更改这些函数的错误行为。全局错误状态保持不变,如果发生错误,否则将设置它,这些函数将抛出一个JsonException消息和代码设置为任何json_last_error()和json_last_error_msg()否则将分别。
下面是一个显示抛出JSON错误的简单方法的示例:
try {
json_decode("{", false, 512, JSON_THROW_ON_ERROR);
}
catch (\JsonException $exception) {
echo $exception->getMessage(); // echoes "Syntax error"
}
在出错时抛出异常将带来您在RFC上列出的几个优点。
注意:传递的无效深度参数json_decode()输出警告并返回NULL。此行为不会受到影响JSON_THROW_ON_ERROR。同样,参数解析错误不会受到影响JSON_THROW_ON_ERROR并继续产生警告。
请考虑以下行:
$b = &$a;
这里$b获取值$a,但该值不会从中复制$a到$b。在PHP中,我们可以通过引用分配值,这意味着两个变量可以指向相同的数据,并且对任何变量的每个更改都会影响原始数据。以下是PHP手册中的一个示例:
现在,让我们改变以下的值$a:
$a = 4; // change $a
print "$a\n"; // prints 4
print "$b\n"; // prints 4 as well, since $b is a reference to $a, which has been changed
列表()语言结构可以用来“就像它们是在一个数组指派变量”,但与list()我们目前不允许通过参考分配变量值。
PHP 7.3应该改变这一点,允许我们通过引用也使用list()构造来分配变量,如以下示例所示:
$array = [1, 2];
list($a, &$b) = $array;
这与:
$array = [1, 2];
$a = $array[0];
$b =& $array[1];
PHP 7.3附带的另一个功能是is_countable()功能。我们在尝试count()不可数的东西时会收到错误。出于这个原因,为了避免警告,我们被迫添加以下代码:
if (is_array($foo) || $foo instanceof Countable) {
// $foo is countable
}
这个RFC提出了函数is_countable(),true如果给定变量是一个数组,它返回,false否则它是一个可数变量。因此,上面的代码可以更改如下:
if (is_countable($foo)) {
// $foo is countable
}
目前,我们可以使用reset(),end()和key()函数检索数组的第一个和最后一个键。不幸的是,使用这些函数,无法在不更改其内部状态的情况下收集数组的第一个或最后一个索引。其他选项通常会降低代码的可读性和性能。
此提议将通过向PHP核心添加两个新函数来更改此方案:
array_key_first()
array_key_last()
在PHP 7.3中,array_key_first()并array_key_last()允许取回第一和给定数组的最后一个关键,而不会影响内部数组指针。这些新功能允许我们编写不太
注意:最初的RFC提出了另外两个函数,array_value_first()并且array_value_last()这些函数在不同的投票中投票,但尚未获得批准,也不会成为PHP核心的参与者。
Argon2是在PHP 7.2中实现的散列算法,作为Bcrypt算法的替代算法。PHP 7.2引入了PASSWORD_ARGON2I常量,可用于password_*函数:
password_hash('password', PASSWORD_ARGON2I);
自第一次实现以来,添加了一个新的Argon2变体,因此,在撰写本文时,Argon2有三种变体:
Argon2d最大限度地抵御GPU破解攻击。它更快,并使用依赖于数据的内存访问。
Argon2i使用与数据无关的内存访问,这是密码散列的首选。它更慢,因为它通过内存更多的通过,以防止权衡攻击。
Argon2id是一个混合版本,它结合了第一次通过内存的Argon2i方法和后续通过的Argon2d方法。
建议在Internet上使用Argon2id,除非有充分理由特别喜欢其他变体。
新RFC建议在password_ *函数中使用新PASSWORD_ARGON2ID常量实现Argon2id :
password_hash('password', PASSWORD_ARGON2ID);
实现与Argon2i实现相同,并且将接受相同的成本因素:
甲存储器成本它定义了应散列期间被消耗KIB的数(默认值是1 << 10,或1024 KIB,或1 MIB)
甲时间成本定义散列算法的迭代次数(默认为2)
甲并行因子,它设置散列(默认为2)时,将用于并行线程的数目
请参阅以下代码:
$options = ['memory_cost' => 1<<11, 'time_cost' => 4, 'threads' => 2];
password_hash('password', PASSWORD_ARGON2ID, $options);
以下函数/功能将在PHP 7.3中弃用,并且不会晚于PHP 8.0删除。
所述image2wbmp()函数输出或保存WBMP给定图像的版本。此函数有三个参数:图像资源,文件名(保存文件的路径)和前景色。
从PHP 5.0开始,它与imagewbmp()完全相同,因此该RFC建议弃用并删除它。
从PHP 7.3开始,每次调用image2wbmp()都会发出弃用警告。删除后,每次调用都会引发致命错误。
弃用和删除不区分大小写的常量
PHP目前支持区分大小写和不区分大小写的常量。无论如何,支持不区分大小写的常量,但被认为是功能上的不一致,并且使用起来很复杂。
该提案从以下前提开始:
类常量始终区分大小写
声明的全局常量const始终区分大小写
define()默认情况下,定义的常量区分大小写
此外,PHP语言参考明确指出:
默认情况下,常量区分大小写。按照惯例,常量标识符总是大写的。
话虽这么说,这个RFC提出了以下变化:
使用define()第三个参数设置为true- PHP 7.3 弃用调用
使用与声明不同的大小写(不包括true,false和null)来弃用不区分大小写的常量- PHP 7.3
删除声明不区分大小写的常量的可能性 – PHP 8.0
转换true,false并null从特例,常数为保留关键字- PHP 8.0
以下是PHP 7.3中不推荐使用的功能的快速列表。它并非详尽无遗,它们只是我个人认为更具相关性的弃用提案。有关建议的弃用的完整列表,请参阅PHP 7.3的弃用。
未记录的mbstring函数别名:有许多未记录的mbstring函数别名,它们是使用mb_前缀的等效函数的重复。例如,mbereg是别名mb_ereg。
所有这些函数都将被标记为已弃用,并且在编译期间遇到它们时将抛出弃用通知。
带整数针的字符串搜索功能:这些功能通常在字符串针上运行。如果给出非字符串指针,则将其转换为整数并作为字符的序数值应用(请参阅PHP手册中的更多内容)。这是RFC的一个例子:
$str = "There are 10 apples";
var_dump(strpos($str, "10")); // int(10)
var_dump(strpos($str, 10)); // bool(false)
这被认为是混乱并导致不可预测的问题,因为类型可能随用户数据源而改变。因此,如果将非字符串针传递给以下函数之一,则RFC建议发出弃用警告:
strpos
strrpos
stripos
strripos
strstr
strchr
strrchr
stristr
在PHP 8.0中,应删除弃用警告,并且针应自动转换为字符串。
正在寻找改进WordPress开发工作流程的方法?
Kinsta的托管解决方案是由开发人员为开发人员构建的。Git,PHP 7,SSH和WP-CLI,以及强大的登台和克隆环境为您提供了更快地构建网站所需的工具!
查看我们的高级功能
fgetss()功能和string.strip_tags流过滤器:fgetss()与string.strip_tags从流条标签,因为它们读取它。函数和过滤器都暴露了strip_tags()功能,使得实现strip_tags()更加复杂,因为需要流式状态机。此外,RFC指出了这些功能的另一个缺点:
另一方面,这些功能似乎没什么用处。strip_tags()由于其局限性和已知错误,本身已经很少有合法的应用程序。除此之外,无需为流应用程序提供本机支持。
因此RFC建议标记fgetss(),gzgetss()并SplFileObject::fgetss()弃用。
在撰写本文时,PHP 7.3处于Beta 2阶段,根据准备任务时间表,它将于12月中旬正式发布。它将带给我们如灵活的heredocs和nowdocs,函数调用中的尾随逗号,list()参考分配等等。