Calling PHP Parent Constructors With Old/New Syntax

后端 未结 2 935
孤独总比滥情好
孤独总比滥情好 2021-01-04 09:40

Given the class Foo with an old-style constructor

class Foo
{
    public function Foo()
    {
        //does constructing stuff
    }
}

Is

相关标签:
2条回答
  • 2021-01-04 09:58

    I would say both syntax do exactly the same thing...
    Edit : after writting the rest of the answer, actually, this is not entirely true ^^ It depends on what you declare ; see the two examples :


    If you define Foo as constructor, and call it with __construct, it seems it's working ; the following code :

    class Foo {
        public function Foo() {
            var_dump('blah');
        }
    }
    
    class Bar extends Foo {
        public function Bar() {
            parent::__construct();
        }
    }
    
    $a = new Bar();
    

    Outputs

    string 'blah' (length=4)
    

    So, all OK for now ;-)


    On the other way, if you define __construct, and call Foo, like this :

    class Foo {
        public function __construct() {
            var_dump('blah');
        }
    }
    
    class Bar extends Foo {
        public function Bar() {
            parent::Foo();
        }
    }
    
    $a = new Bar();
    

    It'll get you a Fatal Error :

    Fatal error: Call to undefined method Foo::foo()
    

    So, if your class is declared with old-syntax, you can call it both ways ; and if it's defined with new (PHP5) syntax, you must use that new syntax -- which makes sense, afterall :-)


    BTW, if you want some kind of "real proof", you can try using the Vulcan Logic Disassembler, that will give you the opcodes corresponding to a PHP script.


    EDIT after the comment

    I've uploaded the outputs of using VLD with both syntaxes : - vld-construct-new.txt : when declaring __construct, and calling __construct. - vld-construct-old.txt : when declaring Foo, and calling __construct.

    Doing a diff between the two files, this is what I get :

    $ diff vld-construct-old.txt vld-construct-new.txt
    25c25
    < Function foo:
    ---
    > Function __construct:
    29c29
    < function name:  Foo
    ---
    > function name:  __construct
    44c44
    < End of function foo.
    ---
    > End of function __construct.
    71c71
    < Function foo:
    ---
    > Function __construct:
    75c75
    < function name:  Foo
    ---
    > function name:  __construct
    90c90
    < End of function foo.
    ---
    > End of function __construct.
    

    (Unified diff is much longer, so I'll stick to using the default format of "diff" here)

    So, the only differences in the disassembled opcodes are the names of the functions ; both in the Foo class and in the Bar class (that inherits the __construct / Foo method of class Foo).

    What I would really say is :

    • If you are writting PHP 5 code (and, in 2009, I sincerely hope you do ^^ ), then, just use the __construct syntax
    • You you have to maintain some old PHP 4 code you can't migrate to PHP 5 (you should), then, use the Foo syntax...


    As the sidenote, the documentation says (quoting) :

    For backwards compatibility, if PHP 5 cannot find a __construct() function for a given class, it will search for the old-style constructor function, by the name of the class.

    Effectively, it means that the only case that would have compatibility issues is if the class had a method named __construct() which was used for different semantics.

    So, I really think there is not that much of a difference :-)


    Did you encounter some kind of strange problem, that you think is caused by something like a difference between the two syntaxes ?

    0 讨论(0)
  • 2021-01-04 10:14

    As of PHP 5.3.3 the old style ctor will not work when you are using namespaces.

    See http://www.php.net/archive/2010.php#id2010-07-22-2

    0 讨论(0)
提交回复
热议问题