__construct()vs SameAsClassName()在PHP中的构造函数

使用__construct()代替PHP中的构造函数的类名是否有优势?

例:

 class Foo { function __construct(){ //do stuff } } 

要么

 class Foo { function Foo(){ //do stuff } } 

我同意gizmo,好处是你不必重命名它,如果你重新命名你的课堂。 干。

同样,如果你有一个孩子class,你可以打电话

 parent::__construct() 

调用父构造函数。 如果进一步沿着轨道更改子类inheritance的类,则不必将构造调用更改为父类。

这似乎是一个小东西,但遗漏改变构造函数调用名称到您的父母类可能会创build微妙(而不是微妙)的错误。

例如,如果您将类插入到heirachy中,但忘记更改构造函数调用,则可以开始调用祖父母的构造函数而不是父项。 这往往会导致可能难以注意的不良结果。

另请注意

从PHP 5.3.3开始,具有与名称空间类名的最后一个元素相同名称的方法将不再被视为构造函数。 此更改不会影响非命名空间类。

资料来源: http : //php.net/manual/en/language.oop5.decon.php

__construct是在PHP5中引入的。 这是你现在应该这样做的方式。 不过,我本身并没有意识到任何优势

从PHP手册:

为了向后兼容,如果PHP 5找不到给定类的__construct()函数,它将通过类的名称search旧式的构造函数。 实际上,这意味着唯一会遇到兼容性问题的情况是,如果类有一个名为__construct()的方法,这个方法被用于不同的语义

如果你在PHP5上,我会build议使用__construct来避免让PHP看看别的地方。

我看到__construct的主要优点是,如果更改类名,则不必重命名构造函数。

今天,接受的答案已经过时了。

重命名类是不好的做法:每次升级到新版本时,都必须记住重命名和重命名。 有时候(比如使用reflection或者复杂的依赖结构)没有激进的重构是不可能的。 这是你想避免的偶然的复杂性 。 这就是为什么名称空间被引入到PHP中的原因。 Java,C ++或C#不使用__construct ,它们使用命名构造函数,并没有问题。

从PHP 5.3.3开始,具有与名称空间类名的最后一个元素相同名称的方法将不再被视为构造函数。 此更改不会影响非命名空间类

 namespace Foo; class Test { var $a = 3; function Test($a) { $this->a = $a; } function getA() { return $this->a; } } $test = new Test(4); echo $test->getA(); // 3, Test is not a constructor, just ordinary function 

请注意,命名构造函数不被弃用(今天PHP5.5)。 但是,您无法预测您的类将不会在名称空间中使用, 因此__construct使用__construct

澄清上述不良做法 (丹尼斯)

在你的代码中的某处你可以使用ReflectionClass :: getName() ; 当你重命名这个类时,你需要记住你在哪里使用了Reflection,并且检查getName()结果在你的应用中是否一致。 您需要记住的东西越多,忘记的东西就越有可能导致应用程序中的错误。

父母无法控制世界上所有依赖他们的阶级。 如果启用了allow_url_include,则其他一些Web可能正在使用服务器中的类,如果您重命名某个类,则该类可能会崩溃。 上面提到的编译语言更糟糕的是,库可以被复制并捆绑在其他代码中。

没有理由重命名类:

  • 如果类名冲突,请使用名称空间
  • 如果class级职责转移,则派生一些其他class级

在命名空间中的PHP类中,无论如何都应避免使用同名的方法:直观上它应该产生一个创build类的对象; 如果它做了别的事,为什么要给它同名? 它应该是一个构造函数,而不是别的。 主要的问题是这种方法的行为取决于命名空间的使用。

PHP中的__construct构造函数没有问题。 但改变命名的构造函数并不是最聪明的想法。

使用__contruct()而不是ClassName()的最大优点是扩展类。 调用parent::__construct()而不是parent::ClassName()要容易得多,因为它可以在类中重用,并且可以方便地更改父对象。

在您的示例中, Foo::Foo有时被称为PHP 4或旧式构造函数,因为它来自PHP 4的日子:

 class Foo { // PHP 4 constructor function Foo(){ //do stuff } } 

PHP 4的构造函数将被弃用,但在PHP 7中不会被移除 。在PHP 8的任何情况下,它们将不再被视为构造函数。未来的兼容性绝对是不使用此function的一个重要原因。

在PHP 5中,优势是性能会更好。 它将首先通过__construct的名称查找构造函数,如果没有find,它将通过className的名称查找构造函数。 因此,如果它通过名称__constructfind构造函数,则不需要按名称classNamesearch构造函数。

向前兼容。 在将来的版本中,为了向下兼容而遗留在语言中的遗留代码总是会被删除。

这个问题已经过了几年了,但是我想我还是要回答这个问题,因为事情已经改变了,将来的读者我想保持信息的更新!

因此,在PHP-7中,他们将删除选项来创build构造函数作为与类相同的名称的函数。 如果你仍然这样做,你会得到一个E_DEPRECATED

你可以在这里阅读更多关于这个build议(接受build议): https : //wiki.php.net/rfc/remove_php4_constructors

并从那里引用:

每当PHP 4的构造函数被定义时, PHP 7将发出E_DEPRECATED 。 当方法名称与类名匹配时,该类不在名称空间中,并且不存在PHP 5构造函数(__construct),则会发出E_DEPRECATED。 PHP 8将停止发送E_DEPRECATED并且这些方法将不被识别为构造函数。

你也不会在php-7中得到一个E_STRICT ,如果你定义了一个名字相同的方法和一个__construct()

你也可以在这里看到:

如果存在与该类同名的方法以及__construct, PHP 7也将停止发送E_STRICT

所以我build议你使用__construct() ,因为将来你的问题会less一些。

如果有方法__construct和SameAsClassName方法,那么__construct将被执行,SameAsClassName方法将被跳过。

我认为主要的原因是语言习惯。 你不需要强迫一个语言像别人一样行事。

我的意思是,在Objective-C中,例如,用-init作为构造函数的前缀。 你可以使用你的类名创build自己的构造函数,但为什么? 还有一些原因是使用这个模式而不是语言约定吗?