質問

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

例( __ construct ):

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

例(名前付き):

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

PHP 5以降、 __ construct メソッド(最初の例)を使用できます。

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

役に立ちましたか?

解決

ギズモに同意します。クラスの名前を変更しても、名前を変更する必要がないという利点があります。乾燥。

同様に、子クラスがある場合は呼び出すことができます

parent::__construct()

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

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

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

また注意してください

  

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

出典: http://php.net/manual/en/language。 oop5.decon.php

他のヒント

__ construct はPHP5で導入されました。それはあなたが今それをすることになっている方法です。ただし、利点自体は認識していません。

PHPマニュアルから:

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

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

__ constructの主な利点は、クラス名を変更してもコンストラクタの名前を変更する必要がないことです。

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

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

上記の悪い習慣に関する説明(デニスの場合)

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

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

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

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

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

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

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

例では、 Foo :: Foo はPHP 4の時代に由来するため、PHP 4または古いスタイルのコンストラクターと呼ばれることもあります。

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

PHP 4のコンストラクターは廃止されますが、削除されません。PHP7では廃止されます。 PHP 8では、どのような状況でもコンストラクターと見なされます。将来の互換性は、この機能を使用しない大きな理由です。

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

まあ、この質問が出されてから数年が経ちましたが、物事は変わったので、この質問にまだ答えなければならないと思います。読者のために、情報を最新に保ちたいです!


したがって、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の発行を停止し、メソッドはコンストラクターとして認識されません。

クラスと同じ名前のメソッドと __ construct()を定義した場合、php-7では E_STRICT も取得されません。

>

こちらでも確認できます:

  

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


したがって、今後この問題が少なくなるため、 __ construct()を使用することをお勧めします。

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

メソッド__constructおよびSameAsClassNameメソッドがある場合、__ constructが実行され、SameAsClassNameメソッドはスキップされます。

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top