70

__construct()PHPのコンストラクタのクラス名の代わりに使用する利点はありますか?

例 ( __construct):

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

例 (名前付き):

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

メソッド (最初の例)を持つこと__constructは、PHP 5 以降で可能です。

PHP バージョン 4 からバージョン 7 までは、クラスと同じ名前のメソッドをコンストラクタとして持つことができます (2 番目の例)。

4

11 に答える 11

71

私はギズモに同意します。利点は、クラスの名前を変更する場合に名前を変更する必要がないことです。ドライ。

同様に、子クラスがある場合は、

parent::__construct()

親コンストラクターを呼び出します。子クラスが継承するクラスをさらに変更する場合は、親への構成呼び出しを変更する必要はありません。

小さなことのように思えますが、コンストラクターの呼び出し名を親クラスに変更しないと、微妙な(そしてそれほど微妙ではない)バグが発生する可能性があります。

たとえば、クラスをheirachyに挿入したが、コンストラクター呼び出しを変更するのを忘れた場合、親ではなく祖父母のコンストラクターの呼び出しを開始できます。これにより、多くの場合、気付くのが難しい望ましくない結果が生じる可能性があります。

また、注意してください

PHP 5.3.3以降、名前空間化されたクラス名の最後の要素と同じ名前のメソッドは、コンストラクターとして扱われなくなります。この変更は、名前空間のないクラスには影響しません。

ソース: http: //php.net/manual/en/language.oop5.decon.php

于 2008-10-20T09:25:22.893 に答える
20

__constructPHP5で導入されました。それがあなたが今やるべき方法です。ただし、それ自体の利点は認識していません。

PHPマニュアルから:

下位互換性のために、PHP 5 が特定のクラスの __construct() 関数を見つけられない場合、クラスの名前で古いスタイルのコンストラクター関数を検索します。事実上、互換性の問題が発生する唯一のケースは、異なるセマンティクスに使用される __construct() という名前のメソッドがクラスにある場合のみであることを意味します。

PHP5を使用している場合は__construct、PHPが他の場所に見えるのを避けるために使用することをお勧めします.

于 2008-10-20T05:57:11.673 に答える
16

__construct の主な利点は、クラス名を変更した場合にコンストラクターの名前を変更する必要がないことです。

于 2008-10-20T06:01:11.930 に答える
11

今日、受け入れられた答えは時代遅れです。

クラスの名前を変更することは悪い習慣です。新しいバージョンにアップグレードするたびに、何をどこで名前を変更するかを覚えておく必要があります。場合によっては (リフレクションや複雑な依存構造を使用する場合など)、根本的なリファクタリングなしでは不可能な場合があります。そして、これは回避したい偶発的な複雑さです。そのため、名前空間が 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

名前付きコンストラクターは廃止されていないことに注意してください (現在の PHP 5.5)。ただし、クラスが名前空間で使用されないことを予測することはできないため、優先する __construct必要があります。

上記の悪い慣行についての説明(Dennis 向け)

コードのどこかでReflectionClass::getName()を使用できます。クラスの名前を変更するときは、Reflection を使用した場所を覚えておいて、getName()結果がアプリ内で一貫しているかどうかを確認する必要があります。特定のことを覚える必要があるほど、何かを忘れる可能性が高くなり、アプリにバグが発生します。

親は、自分に依存する世界のすべてのクラスを制御することはできません。allow_url_includeが有効になっている場合、他の Web がサーバーのクラスを使用している可能性があり、一部のクラスの名前を変更するとクラッシュする可能性があります。上記のコンパイルされた言語ではさらに悪化します。ライブラリがコピーされ、他のコードにバンドルされる可能性があります。

クラスの名前を変更する理由はありません。

  • クラス名が競合する場合は、名前空間を使用してください
  • クラスの責任が変わる場合は、代わりに他のクラスを派生させます

名前空間の PHP クラスでは、とにかく同じ名前のメソッドを避ける必要があります。直観的に、クラスを作成したオブジェクトを生成する必要があります。それが何か他のことをするなら、なぜ同じ名前を付けるのですか? それはコンストラクタであり、それ以外のものではありません。主な問題は、そのようなメソッドの動作が名前空間の使用法に依存することです。

PHP の __construct コンストラクターには問題はありません。しかし、名前付きコンストラクターを変更するのは賢明なアイデアではありませんでした。

于 2013-06-16T09:14:03.653 に答える
8

__contruct()の代わりに使用する最大の利点はClassName()、クラスを拡張する場合です。クラス間で再利用可能であり、親を簡単に変更できるため、のparent::__construct()代わりに呼び出す方がはるかに簡単です。parent::ClassName()

于 2008-10-20T09:30:19.030 に答える
4

この質問が出されてから数年が経ちましたが、状況が変化し、将来の読者のために情報を最新に保ちたいので、私はまだこれに答える必要があると思います!


そのため、php-7 では、コンストラクターをクラスと同じ名前の関数として作成するオプションを削除します。それでもそれを行うと、 が得られますE_DEPRECATED

この提案の詳細については、 https ://wiki.php.net/rfc/remove_php4_constructors をご覧ください (提案は承認されています)。

そしてそこからの引用:

PHP 7は、 PHP 4 コンストラクターが定義されるたびにE_DEPRECATEDを発行します。メソッド名がクラス名と一致し、クラスが名前空間になく、PHP 5 コンストラクター (__construct) が存在しない場合、E_DEPRECATED が発行されます。PHP 8 は E_DEPRECATED の発行を停止し、メソッドはコンストラクターとして認識されなくなります。

またE_STRICT、クラスと同じ名前のメソッドを定義して a を定義すると、php-7 でa を取得できません__construct()

これはここでも見ることができます:

PHP 7は、クラスと同じ名前のメソッドと __construct が存在する場合にも、E_STRICT の発行を停止します


を使用することをお勧めします__construct()。将来的にはこれで問題が少なくなるからです。

于 2015-03-29T13:50:35.287 に答える
3

PHP 5 の利点は、パフォーマンスが向上することです。firstという名前でコンストラクター__constructを探し、それが見つからない場合は、 という名前でコンストラクターを探しますclassName。したがって、コンストラクターが名前で見つかった場合、コンストラクターを名前__constructで検索する必要はありませんclassName

于 2008-10-20T06:00:04.227 に答える
2

前方互換性。下位互換性のために言語に残されているレガシー コードが、将来のバージョンで削除される可能性は常にあります。

于 2008-10-20T09:14:50.277 に答える
0

主な理由は言語の慣習だと思います。言語を他人のように振る舞わせる必要はありません。

たとえば、Objective-C では、コンストラクターの前に -init を付けます。クラス名を使用して独自のコンストラクターを作成できますが、なぜですか? 言語規則の代わりにこのスキーマを使用する理由はありますか?

于 2013-06-06T00:44:25.240 に答える