PHP中的严格模式

69

像Perl这样具有自动变量声明的其他语言都有一个严格模式。

通过启用此严格模式,需要进行变量声明,当您尝试使用未声明的变量时,Perl会立即抛出错误。

PHP是否提供类似的功能?


3
自 PHP 7 版本起,就支持严格模式(strict mode),只需在每个脚本文件的命名空间声明之前添加 declare(strict_types=1); 即可。 - Code4R7
3
@Code4R7,这是不同于问题中所问的那种严格模式。 - Flimm
1
真。回到 error_reporting(E_STRICT); - Code4R7
13个回答

70

可以说是这样的。您可以在错误报告中激活E_NOTICE级别。(常量列表在此处。)

每当使用未声明的变量时,都会抛出一个E_NOTICE

E_STRICT错误级别也会抛出这些通知,以及有关如何优化代码的其他提示。

error_reporting(E_STRICT);

终止脚本

如果您真的很严肃,想要在遇到未声明的变量时使您的脚本终止,而不仅仅是输出通知,则可以构建一个自定义错误处理程序

下面是一个可工作的示例,它只处理包含“未定义变量”E_NOTICE并将其他所有内容传递给默认的PHP错误处理程序:

<?php

error_reporting(E_STRICT);

function terminate_missing_variables($errno, $errstr, $errfile, $errline)
{                               
  if (($errno == E_NOTICE) and (strstr($errstr, "Undefined variable")))
   die ("$errstr in $errfile line $errline");

  return false; // Let the PHP error handler handle all the rest  
}

$old_error_handler = set_error_handler("terminate_missing_variables"); 

echo $test; // Will throw custom error

xxxx();  // Will throw standard PHP error

 ?>

1
@sAc 是的,还有其他一些输出为提示的东西,所以当你打开它时,它们也会出现。(显然,它不像强类型语言那样严格。) - Pekka
error_reporting(E_STRICT) 只影响文件内的代码,还是会全局设置所有代码的设置? - Flimm
@Flimm 只在当前文件内生效(或者说,在运行的脚本中生效,这可能会分散在多个被 include() 的文件中)。 - Pekka
2
这只输出具有E_STRICT优先级的消息(请参阅PHP源代码)。正如@full所提到的,您仅标记了#php,自PHP 7.0或7.1以来(不确定!)已经有了真正的严格模式。有关详细信息,请参见他的答案。 - Roland
但仅在运行时而非解析时(如果有这样的事情)?也许要明确说明?Perl可以在编译时发出警告。 - Peter Mortensen
显示剩余5条评论

41

使用

error_reporting(-1);

为了显示包括E_STRICT在内的所有可能错误,甚至在未来的PHP版本中添加新级别和常量时也要显示。

(参考)


2
error_reporting(-1) 和 error_reporting(E_STRICT) 是一样的吗? - Pacerier
@Pacerier 不,-1 启用了所有当前和未来的错误报告。请参见 PHP 手册页面底部的 提示 - Gordon
5
常量E_STRICT等都是位掩码(bitmasks)。将它们与OR组合,即可设置位。-1将设置每个位。例如: A = 1; b(00000001) B = 2; b(00000010) A OR B = 3 (00000011); -1 = b(11111111) - Markus Zeller
这是因为它是负数,还是使用-1的二进制补码(需要多少位)? - Peter Mortensen
为什么不使用E_ALL?它似乎是十进制32767(0x7FFF,15个1-二进制111111111111111)。 - Peter Mortensen
@PeterMortensen 请参阅 https://www.php.net/manual/en/function.error-reporting.php。自 PHP 5.4 起,E_ALL 只包括 E_STRICT。因此,在2010年提出问题时,“all”并不意味着“全部”。 - Gordon

10

3
尽管它被称为“严格模式”,但它并不像Perl中的严格模式那样。它执行严格的类型检查,也就是说,如果函数期望一个字符串参数,但传递了一个整数参数,它不会进行静默转换,而是会抛出错误。所述的严格模式基本上要求在使用变量$var之前必须先声明$var = 1,因此您可以立即捕获变量名拼写错误,而不仅仅是在某些条件下运行具有拼写错误的代码时才发现。 - janh
1
新链接为https://www.php.net/manual/zh/language.types.declarations.php#language.types.declarations.strict - Roland
所有我的项目都可以在php.ini中完成吗? - Luis Alfredo Serrano Díaz

4

在您的脚本开头键入error_reporting(E_STRICT|E_ALL)


只有在PHP 5.4.0之前,您需要显式使用“E_STRICT”。请参阅http://php.net/manual/en/function.error-reporting.php,在那里“E_STRICT”自5.4.0以来已成为“E_ALL”的一部分。 - Roland
但是只有在运行时,而不是解析时(如果有这样的事情)? - Peter Mortensen
@PeterMortensen 是的,就像 PHP 中的大多数东西一样,它是在运行时进行的。error_reporting() 可以被多次调整,因此只有在设置了足够高的 error_reporting 级别时才会影响正在执行的内容。PHP 在运行时包括所有内容,常见的模板逻辑(即所有 PHP 代码)依赖于引用未设置的变量,然后通过另一个需要“模板”的脚本设置这些变量(这里使用了一些简化/临时术语,但您可以理解这个想法)。 - chelmertz

2

1

PHP默认会警告未声明的变量;您只需要将错误报告级别提高,这样您就可以看到通知了。请注意,由于在PHP中没有特殊的语法来声明变量,您只需通过赋值来声明变量,因此它只能在您尝试使用值的未声明变量时警告您。与其他语言不同,“分配给未声明变量”的情况不存在,因此PHP无法在那里警告您。


1

您可以使用 set_error_handler() 实现自己的错误处理函数。

然后,您可以根据需要对特定的错误级别做出反应。

例如,您可以在变量未正确声明或满足任何不喜欢的条件时终止脚本,而不仅仅是显示和记录错误消息。

这样,您就可以强制执行非常严格的策略,以便在 PHP 解释器实例上运行的任何代码都符合要求。


1

使用

error_reporting(E_ALL);

在你的 PHP 代码开头处添加。

或者在你的 php.ini 文件中设置 error_reporting 设置,以设置所有 PHP 文件的错误报告。


1

是的,从PHP 7.X版本开始,您可以这样做。

declare(strict_types=1);

这将强制所有标量类型声明严格遵循类型。

但是,如果您在全局范围内启用此功能,则可能会影响其他第三方模块(例如,PHP Composer 库),这些模块依赖于弱模式,请确保在相关的类/文件中强制执行它。


严格类型是在何时进行?在解析/编译时还是仅在运行时进行? - Peter Mortensen

0

1
只回答了一半,请查看其他答案。 - Roland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接