Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
281 views
in Technique[技术] by (71.8m points)

php - What does E_STRICT do?

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:

  • Warn against calling non-static methods statically
  • Warn against incompatible subclass function signatures
  • Warn against assigning a value by reference

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

E_STRICT and "strict standards" are the same thing. (And they're removed in PHP 7.)

The documentation presently has no list of E_STRICT-specific warnings, but we can construct one reasonably easily by searching the PHP source.

The list below (which I believe to be accurate as of PHP 5.6) was formed on a Unix system via the following methodology:

  1. Cloning the PHP Git repo:

    git clone https://github.com/php/php-src
    
  2. Checking out version 5.6.0:

    cd php-src
    git checkout PHP-5.6.0
    
  3. Searching for all C files (ones with .h and .c extensions) containing E_STRICT:

    grep --include=*.[ch] -rl . -e E_STRICT
    
  4. 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.

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.

Things in PHP that cause E_STRICT warnings

  1. Calling mktime() with no arguments

    php > mktime();
    PHP Strict Standards:  mktime(): You should be using the time() function
    instead in php shell code on line 1
  2. 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
  3. Passing a multi-byte encoding other than UTF-8 to 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. Declaring an abstract static method

    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. Declaring a class with both a __construct method and an old-style constructor function named after the class

    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. 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
  7. 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
  8. Declaring, compatibly, the same property in a trait and a class that uses it. This one is actually nicely documented:

    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.

    Example #12 Conflict Resolution

    <?php
    trait PropertiesTrait {
        public $same = true;
        public $different = false;
    }
    
    class PropertiesExample {
        use PropertiesTrait;
        public $same = true; // Strict Standards
        public $different = true; // Fatal error
    }
    ?>
    

    An example of the strict mode warning:

    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. 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
  10. 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
  11. Directly passing the result of a function call 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

    Note that passing other non-variables by reference, like literals or constants, is a fatal error instead of an E_STRICT


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...