E_STRICT 有什么作用?
我实际上很想确保我们的代码库没有错误,PHP 的内置错误检查会警告这些错误,但我想确切地了解 E_STRICT 强制执行的内容.通过扩展,PHP 的严格标准"是什么?我查看了但找不到完整的列表.
I'm actually interested in making sure our codebase is free of errors that would be warned against by PHP's builtin error checking, but I'd like to see exactly what E_STRICT enforces. By extension, what are PHP's "strict standards"? I looked but couldn't find a comprehensive list.
我从经验中了解到的一些严格标准:
Some strict standards that I know offhand from experience:
- 警告不要静态调用非静态方法
- 警告不兼容的子类函数签名
- 警告不要通过引用分配值
我所知道的关于 E_STRICT 的全部内容是它对可能破坏向前兼容性的代码发出警告,但我不确定这具体意味着什么.
All I know about E_STRICT is that it warns against code which might break forward compatibility, but I'm not sure what that means concretely.
有没有关于这方面的信息的好资源?
Is there a good resource out there for information on this?
推荐答案
E_STRICT
和严格标准"是一回事.(并且 它们在 PHP 7 中被移除.)
E_STRICT
and "strict standards" are the same thing. (And they're removed in PHP 7.)
该文档目前没有 E_STRICT
特定警告的列表,但我们可以通过搜索 PHP 源代码.
The documentation presently has no list of E_STRICT
-specific warnings, but we can construct one reasonably easily by searching the PHP source.
以下列表(我认为自 PHP 5.6 起是准确的)是通过以下方法在 Unix 系统上形成的:
The list below (which I believe to be accurate as of PHP 5.6) was formed on a Unix system via the following methodology:
克隆 PHP Git 存储库:
Cloning the PHP Git repo:
git clone https://github.com/php/php-src
正在检查 5.6.0 版:
Checking out version 5.6.0:
cd php-src
git checkout PHP-5.6.0
搜索包含 E_STRICT
的所有 C 文件(带有 .h
和 .c
扩展名的文件):
Searching for all C files (ones with .h
and .c
extensions) containing E_STRICT
:
grep --include=*.[ch] -rl . -e E_STRICT
手动查看 (21) 个匹配文件中的每一个以查找发出 E_STRICT
警告的代码,尝试推断发出警告的情况(我不是 C程序员,但对这些东西做出很好的猜测并不太难,尤其是代码中的人类可读错误消息可以指导您)然后在交互式 PHP shell 中测试它们以确保我是对的.
Manually looking through each of the (21) matched files to find code emitting E_STRICT
warnings, attempting to deduce the circumstances in which the warning would be emitted (I'm not a C programmer, but it's not too hard to take a good guess at this stuff, especially with the human-readable error messages right there in the code to guide you) then testing them at the interactive PHP shell to make sure I was right.
鉴于上述方法略显粗糙,并且依赖于以下假设:E_STRICT
可以在源代码中所有发出 E_STRICT
警告的地方旁边找到,我可能遗漏了一些东西 - 但希望这至少接近成为一个全面的列表.
Given that the methodology described above is slightly crude and depends upon the assumption that E_STRICT
can be found in the source code next to all places where E_STRICT
warnings are emitted, it's possible I've missed some stuff - but this is hopefully at least close to being a comprehensive list.
调用
mktime()
没有参数
php > mktime();
PHP Strict Standards: mktime(): You should be using the time() function
instead in php shell code on line 1
使用资源作为数组索引>
Using a resource as an array index
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
方法和 旧式构造函数以类命名的函数
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_next_result
或 mysqli::next_result
在没有准备下一个结果的 Mysqli 连接对象上
Calling mysqli_next_result
or mysqli::next_result
on a Mysqli connection object that does not have a next result to prepare
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
覆盖子类中的方法以将不同数量的参数传递给其父类中的同一方法
Overriding a method in a subclass to take a different number of arguments to the same method in its parent
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
在特征和使用它的类中以兼容方式声明相同的属性.这个实际上很好文档化:
如果一个trait定义了一个属性,那么一个类就不能定义一个同名的属性,否则会报错.如果类定义兼容(相同的可见性和初始值),则为 E_STRICT
,否则为致命错误.
If a trait defines a property then a class can not define a property with the same name, otherwise an error is issued. It is an
E_STRICT
if the class definition is compatible (same visibility and initial value) or fatal error otherwise.
<?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
静态调用非静态方法
Calling a non-static method statically
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
非静态地引用静态属性
Referring to a static property non-statically
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
直接传递函数调用的结果通过引用.
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
Note that passing other non-variables by reference, like literals or constants, is a fatal error instead of an E_STRICT
相关文章