使用有什么好处吗 __construct() 而不是 PHP 中构造函数的类名?

例子 (__construct):

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

示例(已命名):

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

拥有 __construct 方法(第一个示例)从 PHP 5 起就可以使用。

从 PHP 版本 4 到版本 7,可以使用与类同名的方法作为构造函数(第二个示例)。

有帮助吗?

解决方案

我同意Gizmo,其优点是,如果您重命名课程,则无需重命名。 DRY。

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

parent::__construct()

调用父构造函数。如果在轨道的下方更改了子类继承的类,则不必将构造调用更改为父级。

这似乎是一件小事,但是缺少将构造函数调用名称更改为父类可能会产生微妙(而不是那么微妙)的错误。

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

另请注意

  

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

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

其他提示

在PHP5中引入了

__ construct 。这是你现在应该这样做的方式。不过,我本身并不知道的优点

从PHP手册:

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

如果您使用的是PHP5,我建议您使用 __ construct 来避免让PHP在其他地方使用。

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

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

重命名类是不好的做法:每次升级到新版本时,您都必须记住要重命名的内容和位置。有时(比如使用 反射 或复杂的依赖结构),如果不彻底重构,这是不可能的。这是 偶然的复杂性 你想避免。这就是为什么 命名空间 被引入到 PHP 中。Java、C++ 或 C# 不使用 __construct, ,他们使用命名构造函数,并且没有任何问题。

从 PHP 5.3.3 开始,与 a 的最后一个元素同名的方法 命名空间的 类名将不再被视为构造函数。这个改变 不影响非命名空间类.

例子

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

请注意,命名构造函数并未被弃用(现在的 PHP 5.5)。但是,您无法预测您的类不会在命名空间中使用, 所以 __construct 应该是首选。

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

您可以在代码中的某个位置使用 ReflectionClass::getName();当你重命名类时,你需要记住你在哪里使用了Reflection并检查是否 getName() 结果在您的应用程序中仍然一致。您越需要记住特定的内容,就越有可能忘记某些内容,从而导致应用程序中出现错误。

父母无法控制世界上所有依赖他们的课程。如果 允许 url_include 启用后,某些其他 Web 可能正在使用您服务器中的类,如果您重命名某些类,则可能会崩溃。在上面提到的编译语言中情况更糟:该库可以复制并捆绑到其他代码中。

没有理由重命名类:

  • 如果类名冲突,则使用命名空间
  • 如果类职责发生变化,则派生其他类

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

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

使用 __ contruct()而不是 ClassName()的最大好处是扩展类时。调用 parent :: __ construct()而不是 parent :: ClassName()要容易得多,因为它可以在类之间重用,父类可以轻松更改。 / p>

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

class Foo {
    // PHP 4 constructor
    function Foo(){
        //do stuff
    }
}
在PHP 7中,

PHP 4构造函数将被弃用但不会被删除。它们将不再存在在PHP 8的任何情况下都被视为构造函数。未来的兼容性肯定是不使用此功能的一个重要原因。

在PHP 5中,优势在于性能会更好。它将首先通过 __ construct 的名称查找构造函数,如果找不到,它将以 className 的名称查找构造函数。因此,如果它通过名称 __ construct 找到构造函数,则不需要通过名称 className 搜索构造函数。

自问这个问题以来已经过了几年了,但我想我还是要回答这个问题,因为事情已经发生了变化,未来的读者我希望保持信息的最新状态!

结果

因此在php-7中,他们将删除选项,将构造函数创建为与类同名的函数。如果您仍然这样做,您将获得 E_DEPRECATED

您可以在此处详细了解此提案(此提案已被接受):   https://wiki.php.net/rfc/remove_php4_constructors

从那里引用:

  每当 PHP 4构造函数定义时,

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

如果你定义一个与类和 __ construct()同名的方法,你也不会在php-7中得到 E_STRICT

你也可以在这里看到:

  当存在与该类名称相同的方法以及__construct时,

PHP 7 也将停止发出E_STRICT

结果

所以我建议你使用 __ construct(),因为将来你会遇到更少的问题。

向前兼容性。为了向后兼容而留下的遗留代码总是有可能在将来的版本中删除。

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

我认为主要原因是语言惯例。 您不需要强迫语言像其他人一样行事。

我的意思是,在Objective-C中,您可以使用-init为构造函数添加前缀。您可以使用您的类名创建自己的构造函数,但为什么?是否有理由使用此架构而不是语言约定?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top