E_STRICT做什么?

时间:2013-01-09 20:27:35

标签: php error-handling

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

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

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

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

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

1 个答案:

答案 0 :(得分:9)

E_STRICT和"严格标准"是一回事。 (和they're removed in PHP 7。)

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

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

  1. 克隆PHP Git repo:

    git clone https://github.com/php/php-src
    
  2. 签出版本5.6.0:

    cd php-src
    git checkout PHP-5.6.0
    
  3. 搜索包含.h的所有C文件(包含.cE_STRICT扩展名的文件):

    grep --include=*.[ch] -rl . -e E_STRICT
    
  4. 手动浏览每个(21)匹配的文件,找到发出E_STRICT警告的代码,试图推断出发出警告的情况(我不是C程序员但是,对这些东西进行很好的猜测并不是很难,特别是在代码中引用你的人类可读错误消息,然后在交互式PHP shell中测试它们以确保我是对的

  5. 鉴于上述方法略显粗糙,并且取决于在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. 使用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
    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. 声明abstract static方法

      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方法和以类命名的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
    6. 在没有下一个结果准备的Mysqli连接对象上调用mysqli_next_resultmysqli::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
    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. 相应地声明特征和使用它的类中的相同属性。这个实际上很好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
    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. 直接传递函数调用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