E_STRICT做什么?

Ant*_*ric 6 php error-handling

我真的很想确保我们的代码库没有错误,这些错误会被PHP的内置错误检查所警告,但我想确切地看到E_STRICT强制执行的操作.通过扩展,什么是PHP的"严格标准"?我看了,但找不到一份全面的清单.

我从经验中得知的一些严格的标准:

  • 警告静态调用非静态方法
  • 警告不兼容的子类函数签名
  • 警告不要通过引用分配值

我所知道的关于E_STRICT的是它警告可能会破坏兼容性的代码,但我不确定具体是什么意思.

有没有关于此信息的好资源?

Mar*_*ery 9

E_STRICT和"严格的标准"是一回事.(它们在PHP 7中删除了.)

该文档目前没有E_STRICT特定的警告列表,但我们可以通过搜索PHP源来合理地构建一个.

下面的列表(我认为从PHP 5.6开始就是准确的)是在Unix系统上通过以下方法形成的:

  1. 克隆PHP Git repo:

    git clone https://github.com/php/php-src
    
    Run Code Online (Sandbox Code Playgroud)
  2. 签出版本5.6.0:

    cd php-src
    git checkout PHP-5.6.0
    
    Run Code Online (Sandbox Code Playgroud)
  3. 搜索包含以下内容的所有C文件(带有.h.c扩展名的文件)E_STRICT:

    grep --include=*.[ch] -rl . -e E_STRICT
    
    Run Code Online (Sandbox Code Playgroud)
  4. 手动查看每个(21)匹配的文件,找到发出E_STRICT警告的代码,试图推断出发出警告的情况(我不是C程序员,但要对此进行好的猜测并不难东西,尤其是代码中的人类可读错误消息,以指导您)然后在交互式PHP shell中测试它们以确保我是对的.

鉴于上述方法略有粗糙,取决于这一假设E_STRICT可以在明年到所有地方的源代码中找到E_STRICT警告发出的,这是可能的,我错过了一些东西-但这是希望至少接近到是一综合清单.

PHP中导致E_STRICT警告的事情

  1. mktime()没有参数调用

    php > mktime();
    PHP Strict Standards:  mktime(): You should be using the time() function
    instead in php shell code on line 1
  2. 使用资源作为数组索引

    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
  3. 将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
  4. 声明一个抽象的 静态方法

    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
  5. 使用__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
  6. 调用mysqli_next_resultmysqli::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];
    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
  7. 覆盖子类中的方法,以便为其父级中的同一方法获取不同数量的参数

    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
  8. 相应地,声明特征和使用它的类中的相同属性.这个实际上很好地记录了:

    如果特征定义了属性,则类无法定义具有相同名称的属性,否则将发出错误.这是一个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
    }
    ?>
    
    Run Code Online (Sandbox Code Playgroud)

    严格模式警告的示例:

    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
  9. 静态调用非静态方法

    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
  10. 非静态地引用静态属性

    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
  11. 通过引用直接传递函数调用的结果.

    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