1

依存性注入に spl_autoload を使用しています。

spl_autoload_register(function ($class)
{
    $cFilePath = _CLASSLIB_ . "/class.$class.php";

    if(file_exists($cFilePath))
    {
        include($cFilePath);
    }
    else
    {
        die("Unable to include the $class class.");
    }
});

これはうまくいきます。ただし、これらが私のクラスだとしましょう:

class Test 
{ 
   public function foo() 
   { 
      echo "Here."; 
   } 
}  

class OtherTest 
{ 
   public function bar() 
   { 
      global $Test; 

      $Test->foo(); 
   } 
}  

だから、私の実行コードでは:

<?php
$OT = new OtherTest(); //Dependency Injection works and loads the file.
$OT->bar();
?>

bar() がテスト クラス (インスタンス化されていないため、オートロードされない) でグローバル化を試みるため、エラーが発生します。

すべてのメソッドで使用する前に $Test グローバルがオブジェクトであるかどうかを確認する以外に、これを実装する最良の方法は何ですか?

4

2 に答える 2

0

可能であれば、グローバルの使用は避けてください。コメントで Dependency Injection について言及しました。DI を使用してこの問題を解決できます。

OtherTest が Test のインスタンスに依存している場合、その Test のインスタンスは、構築時に OtherTest に提供する必要があります。

$T = new OtherTest($Test);

明らかに、OtherTest クラスを修正して、Test のインスタンスをプロパティとして持ち、Test を引数として受け取るコンストラクターを次のように変更する必要があります。

class OtherTest 
{

    protected $test = null;

    public function __construct(Test $test)
    {
        $this->test = $test;
    }

    public function bar()
    {
        return $this->test->foo();
    }

}

その後、次のことができます。

$test = new Test();
$otherTest = new OtherTest($test);
$otherTest->bar();
于 2013-02-22T19:34:41.397 に答える
0

依存性注入の意味を混乱させていると思います。クラスのオートローディングは依存性注入ではありません。依存性注入は、オブジェクトが持つ可能性のある依存性をオブジェクトに実際に注入して、それを操作できるようにする場所です。したがって、依存関係を受け取るオブジェクトは、その依存関係を作成する必要がまったくなくなります。

この場合、依存性注入を実現する最善の方法は、Test クラスへの依存性を、OtherTest のインスタンス化で OtherTest に実際に注入することです。したがって、Othertest は次のようになります。

class OtherTest 
{ 
   protected $test_object = NULL;

   public function __construct($test_obj) {
      if ($test_obj instanceof Test === false) {
          throw new Exception('I need a Test object');
      } 
      $this->test_obj = $test_obj;
   }

   public function bar() 
   { 
      $this->$test_obj->foo(); 
   } 
}

インスタンス化するコードは次のようになります。

$OT = new OtherTest(new Test()); // both OtherTest and Test would be autoloaded here if not previously loaded.

宣言されていない変数 ($Testあなたの例では) を参照しても、変数名自体にはクラスのコンテキストがないため、クラスが自動ロードされないことに注意してください。非オブジェクトでメソッドを呼び出そうとすると、エラーが発生するだけです。

于 2013-02-22T19:36:19.803 に答える