我实际上有兴趣确保我们的代码库没有错误,这些错误会被 PHP 的内置错误检查警告,但我想看看 E_STRICT 究竟执行了什么。推而广之,什么是 PHP 的“严格标准”?我查看了但找不到完整的列表。
我从经验中了解到的一些严格标准:
- 警告不要静态调用非静态方法
- 警告不兼容的子类函数签名
- 警告不要通过引用分配值
我所知道的关于 E_STRICT 的唯一信息是它会警告可能破坏前向兼容性的代码,但我不确定这具体意味着什么。
有没有很好的资源来提供这方面的信息?
我实际上有兴趣确保我们的代码库没有错误,这些错误会被 PHP 的内置错误检查警告,但我想看看 E_STRICT 究竟执行了什么。推而广之,什么是 PHP 的“严格标准”?我查看了但找不到完整的列表。
我从经验中了解到的一些严格标准:
我所知道的关于 E_STRICT 的唯一信息是它会警告可能破坏前向兼容性的代码,但我不确定这具体意味着什么。
有没有很好的资源来提供这方面的信息?
E_STRICT
和“严格标准”是一回事。(并且它们在 PHP 7 中被删除。)
该文档目前没有特定警告列表,但我们可以通过搜索PHP 源代码E_STRICT
轻松构建一个。
下面的列表(我认为在 PHP 5.6 中是准确的)是通过以下方法在 Unix 系统上形成的:
克隆 PHP Git 存储库:
git clone https://github.com/php/php-src
签出版本 5.6.0:
cd php-src
git checkout PHP-5.6.0
搜索包含以下内容的所有 C 文件(带有.h
和.c
扩展名的文件)E_STRICT
:
grep --include=*.[ch] -rl . -e E_STRICT
手动查看 (21) 个匹配的文件中的每一个以查找发出E_STRICT
警告的代码,尝试推断发出警告的情况(我不是 C 程序员,但对此并不难猜测东西,尤其是代码中的人类可读错误消息来指导你)然后在交互式 PHP shell 中测试它们以确保我是对的。
鉴于上述方法略显粗糙,并且取决于E_STRICT
可以在所有发出警告的位置旁边的源代码中找到的假设,我可能错过了一些东西 - 但希望这E_STRICT
至少接近于综合清单。
mktime()
不带参数调用
php > mktime(); PHP 严格标准:mktime():您应该使用 time() 函数 而是在第 1 行的 php shell 代码中
使用资源作为数组索引
php > $file_pointer = fopen('/dev/null', 'r'); php > $array = [3,4,5,6]; php > $array[$file_pointer]; PHP 严格标准:资源 ID#2 用作偏移量,转换为整数 (2) 在第 1 行的 php shell 代码中
将 UTF-8 以外的多字节编码传递给htmlentities
php > htmlentities('qwertyuiop', 0, 'BIG5'); PHP 严格标准:htmlentities():只有基本的实体替换是 支持 UTF-8 以外的多字节编码;功能是 相当于第 1 行 php shell 代码中的 htmlspecialchars
php >抽象类 Foo { 静态抽象函数 bar(); } PHP 严格标准:静态函数 Foo::bar() 不应该是抽象的 第 1 行的 php shell 代码
__construct
用一个方法和一个以该类命名的旧式构造函数声明一个类
php > class MyClass { php { function MyClass () {} php { function __construct () {} php { } PHP 严格标准:为类重新定义已定义的构造函数 第 3 行 php shell 代码中的 MyClass
调用mysqli_next_result
或mysqli::next_result
在没有准备下一个结果的 Mysqli 连接对象上
php > $conn = mysqli_connect('127.0.0.1', 'root'); php > mysqli_multi_query($conn, "SELECT 'first'; SELECT 'second';"); php > echo mysqli_use_result($conn)->fetch_row()[0]; 第一的 php > mysqli_next_result($conn); php > echo mysqli_use_result($conn)->fetch_row()[0]; 第二 php > mysqli_next_result($conn); PHP 严格标准:mysqli_next_result():没有下一个结果集。 请调用 mysqli_more_results()/mysqli::more_results() 检查是否 在第 1 行的 php shell 代码中调用此函数/方法
覆盖子类中的方法以将不同数量的参数传递给其父类中的同一方法
php > class A { public function foo ($x) {} } php > class B extends A { public function foo () {} } PHP 严格标准:B::foo() 的声明应与 A::foo($x) 在第 1 行的 php shell 代码中 php >类 C 扩展 A { public function foo ($x, $y) {} } PHP 严格标准:C::foo() 的声明应与 A::foo($x) 在第 1 行的 php shell 代码中
在 trait 和使用它的类中以兼容的方式声明相同的属性。这个实际上有很好的记录:
如果一个 trait 定义了一个属性,那么一个类不能定义一个同名的属性,否则会发出错误。
E_STRICT
如果类定义兼容(相同的可见性和初始值),则为致命错误,否则为致命错误。Example #12 冲突解决
<?php trait PropertiesTrait { public $same = true; public $different = false; } class PropertiesExample { use PropertiesTrait; public $same = true; // Strict Standards public $different = true; // Fatal error } ?>
严格模式警告的示例:
php > trait PropertiesTrait { php { public $same = true; php { } php >类 PropertiesExample { php { 使用 PropertiesTrait; php { 公共$相同=真; php { } PHP 严格标准:PropertiesExample 和 PropertiesTrait 定义 PropertiesExample 的组成中的相同属性 ($same)。这有可能 不兼容,为了提高可维护性考虑使用访问器 而是使用特征中的方法。类是在第 4 行的 php shell 代码中组成的
静态调用非静态方法
php > class Foo { function bar() {} } php > Foo::bar(); PHP 严格标准:不应调用非静态方法 Foo::bar() 静态地在第 1 行的 php shell 代码中
非静态地引用静态属性
php > class Cow { static public $noise = 'moo'; } php > $cow = 新牛; php > $cow->noise = "MOOOOO"; PHP 严格标准:将静态属性 Cow::$noise 作为非静态访问 在第 1 行的 php shell 代码中
通过引用直接传递函数调用的结果。
php >函数 foo () { 返回 1; } php >函数 bar (&$some_arg) {} php > bar(foo()); PHP 严格标准:在 php 中只能通过引用传递变量 第 1 行的 shell 代码 php > $var = &foo(); PHP 严格标准:只能通过引用分配变量 第 1 行的 php shell 代码
请注意,通过引用传递其他非变量,如文字或常量,是一个致命错误,而不是E_STRICT