我真的很想确保我们的代码库没有错误,这些错误会被PHP的内置错误检查所警告,但我想确切地看到E_STRICT强制执行的操作。通过扩展,什么是PHP的“严格标准”?我看了,但找不到一份全面的清单。
我从经验中得知的一些严格标准:
我所知道的关于E_STRICT的是它警告可能会破坏兼容性的代码,但我不确定具体是什么意思。
有没有关于此的信息的好资源?
答案 0 :(得分:9)
E_STRICT
和"严格标准"是一回事。 (和they're removed in PHP 7。)
该文档目前没有E_STRICT
特定警告列表,但我们可以通过搜索the PHP source来合理地构建一个警告。
下面的列表(我认为从PHP 5.6开始就是准确的)是在Unix系统上通过以下方法形成的:
克隆PHP Git repo:
git clone https://github.com/php/php-src
签出版本5.6.0:
cd php-src
git checkout PHP-5.6.0
搜索包含.h
的所有C文件(包含.c
和E_STRICT
扩展名的文件):
grep --include=*.[ch] -rl . -e E_STRICT
手动浏览每个(21)匹配的文件,找到发出E_STRICT
警告的代码,试图推断出发出警告的情况(我不是C程序员但是,对这些东西进行很好的猜测并不是很难,特别是在代码中引用你的人类可读错误消息,然后在交互式PHP shell中测试它们以确保我是对的
鉴于上述方法略显粗糙,并且取决于在E_STRICT
警告发出的所有地方旁边的源代码中可以找到E_STRICT
的假设,它是可能的我错过了一些东西 - 但希望至少关闭成为一个全面的列表。
在没有参数的情况下调用mktime()
php > mktime(); PHP Strict Standards: mktime(): You should be using the time() function instead in php shell code on line 1
使用resource作为数组索引
php > $file_pointer = fopen('/dev/null', 'r'); php > $array = [3,4,5,6]; php > $array[$file_pointer]; PHP Strict Standards: Resource ID#2 used as offset, casting to integer (2) in php shell code on line 1
将UTF-8以外的多字节编码传递给htmlentities
php > htmlentities('qwertyuiop', 0, 'BIG5'); PHP Strict Standards: htmlentities(): Only basic entities substitution is supported for multi-byte encodings other than UTF-8; functionality is equivalent to htmlspecialchars in php shell code on line 1
php > abstract class Foo { static abstract function bar(); } PHP Strict Standards: Static function Foo::bar() should not be abstract in php shell code on line 1
使用__construct
方法和以类命名的old-style constructor函数声明一个类
php > class MyClass { php { function MyClass () {} php { function __construct () {} php { } PHP Strict Standards: Redefining already defined constructor for class MyClass in php shell code on line 3
在没有下一个结果准备的Mysqli连接对象上调用mysqli_next_result
或mysqli::next_result
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]; first php > mysqli_next_result($conn); php > echo mysqli_use_result($conn)->fetch_row()[0]; second php > mysqli_next_result($conn); PHP Strict Standards: mysqli_next_result(): There is no next result set. Please, call mysqli_more_results()/mysqli::more_results() to check whether to call this function/method in php shell code on line 1
覆盖子类中的方法,为其父级中的同一方法获取不同数量的参数
php > class A { public function foo ($x) {} } php > class B extends A { public function foo () {} } PHP Strict Standards: Declaration of B::foo() should be compatible with A::foo($x) in php shell code on line 1 php > class C extends A { public function foo ($x, $y) {} } PHP Strict Standards: Declaration of C::foo() should be compatible with A::foo($x) in php shell code on line 1
相应地声明特征和使用它的类中的相同属性。这个实际上很好documented:
如果特征定义了属性,则类无法定义具有相同名称的属性,否则会发出错误。如果类定义兼容(相同的可见性和初始值)或其他致命错误,则为
E_STRICT
。示例#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 > class PropertiesExample { php { use PropertiesTrait; php { public $same = true; php { } PHP Strict Standards: PropertiesExample and PropertiesTrait define the same property ($same) in the composition of PropertiesExample. This might be incompatible, to improve maintainability consider using accessor methods in traits instead. Class was composed in php shell code on line 4
静态调用非静态方法
php > class Foo { function bar() {} } php > Foo::bar(); PHP Strict Standards: Non-static method Foo::bar() should not be called statically in php shell code on line 1
非静态地引用静态属性
php > class Cow { static public $noise = 'moo'; } php > $cow = new Cow; php > $cow->noise = "MOOOOO"; PHP Strict Standards: Accessing static property Cow::$noise as non static in php shell code on line 1
直接传递函数调用by reference的结果。
php > function foo () { return 1; } php > function bar (&$some_arg) {} php > bar(foo()); PHP Strict Standards: Only variables should be passed by reference in php shell code on line 1 php > $var = &foo(); PHP Strict Standards: Only variables should be assigned by reference in php shell code on line 1
请注意,通过引用传递其他非变量(如文字或常量)是致命错误,而不是E_STRICT