使用旧/新语法调用PHP父构造函数 [英] Calling PHP Parent Constructors With Old/New Syntax
问题描述
给定类Foo与旧式构造函数
class Foo
{
public function Foo()
{
//正在构建材料
}
}
b $ b
在调用父构造函数与新样式构造函数或旧样式构造函数之间是否有任何功能差异?
class Bar extends Foo
{
public function Bar()
{
//是否重要?
// parent :: __ construct();
// parent :: Foo();
}
}
换句话说,调用
parent :: __ construct()
$
在从一个构造函数创建的时候,
我会说两个语法做完全相同的事情...
编辑:写完其余的答案后,实际上,这不是完全正确的^^这取决于你宣布什么;请参阅以下两个示例:
如果您将 Foo
定义为构造函数,与 __构造
,它似乎它的工作;代码如下:
class Foo {
public function Foo(){
var_dump('blah' );
}
}
class Bar extends Foo {
public function Bar(){
parent :: __ construct();
}
}
$ a = new Bar();
输出
string'blah'(length = 4)
)
另一方面,如果您定义__construct,并调用Foo,如下所示:
class Foo {
public function __construct(){
var_dump('blah');
}
}
类Bar扩展Foo {
public function Bar(){
parent :: Foo();
}
}
$ a = new Bar();
它会给你一个致命错误:
致命错误:调用未定义的方法Foo :: foo()
$ b b
所以,如果你的类是用old-syntax声明的,你可以用两种方法来调用它。如果使用新的(PHP5)语法定义,则必须使用新的语法 - 这是有道理的: - )
,如果您想要某种真实证明,您可以尝试使用 Vulcan逻辑反汇编,
我已经使用两种语法上传了使用VLD的输出:
- vld-construct-new.txt :当声明__construct,并调用__construct。
- vld-construct-old.txt :当声明Foo和调用__construct。
在这两个文件之间做一个差异,这是我得到:
$ diff vld-construct-old.txt vld-construct-new.txt
25c25
<函数foo:
---
>函数__construct:
29c29
<函数名:Foo
---
>函数名:__construct
44c44
<函数结束foo。
---
>函数__construct结束。
71c71
<函数foo:
---
>函数__construct:
75c75
<函数名:Foo
---
>函数名:__construct
90c90
<函数结束foo。
---
>函数__construct结束。
(统一差异要长得多,所以我坚持使用默认格式diffhere)
因此,反汇编操作码的唯一区别是函数的名称;在 Foo
类和 Bar
类(继承 __ construct
/ Foo
方法 Foo
)。
我真正想说的是:
- 如果你正在编写PHP 5代码,希望你做^^),那么只需使用__construct语法
- 你必须维护一些旧的PHP 4代码,不能迁移到PHP 5 (您应该),然后使用Foo语法...
sidenote,文档说 (引用):
为了向后兼容,如果PHP 5
无法找到__ construct()
function
一个给定的类,它将搜索旧的构造函数
,
类的名称。
有效地,唯一的
情况下会有兼容性
问题是如果该类有一个名为__ construct()
的方法
使用$ b $
所以,我真的认为没有太大的区别: - )
您是否遇到某种奇怪的问题,您认为是由两种语法之间的差异引起的?
Given the class Foo with an old-style constructor
class Foo
{
public function Foo()
{
//does constructing stuff
}
}
Is there any functional difference between calling the parent constructor with a new style constructor or the old style constructor?
class Bar extends Foo
{
public function Bar()
{
//does it matter?
//parent::__construct();
//parent::Foo();
}
}
Put another way, is there anything special about the static call
parent::__construct()
when it's made from a constructor, or is it just a standard static call?
Before the Best Practices Flying Monkeys descend, I'm dealing with some legacy code and trying to understand the consequences of everything that's going on.
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 ?
这篇关于使用旧/新语法调用PHP父构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!