0

簡単にするために、Web アプリケーションで使用される User と UserStatus の 2 つのクラスがあるとします。

<?php

// library code:
class UserStatus {
  protected $_status = NULL;

  private function fetchDataFromDB() {
    // regular DB stuff
    $this->_status = ...
    // result will be something like 'online', 'away', etc. 
  }

  public function getIcon() {
    global $icon_array;

    if (is_null($this->_status)) {
      $this->fetchDataFromDB()
    }
    return $icon_array[$this->_status];
  }
}

class User {
  protected $user_id;
  public $user_name;
  protected $status;

  public function __construct() {}

  public static function getAll() {
    // some DB stuff
    return $users;
  }
}

// and now, in index.php:
$users = User::getAll();

// echoes the icon to use to reflect the current user status

foreach ($users as $user) {
  echo <img src="$user->status->getIcon()"/>;
}

?>

ほとんどの HTTP リクエストでは、ステータス オブジェクトは使用されないため、必要に応じてのみインスタンス化する方法を探しています (遅延読み込みと呼びます)。status->method()呼び出しをインターセプトしてそのオブジェクトをオンザフライで作成するにはどうすればよいですか?

重要な注意点は、 UserStatus クラスで利用できる必要$user_idがあることです。そうしないと、fetchDataFromDB()メソッドはどのユーザーにデータを取得する必要があるかわかりません。これはどのように行うべきですか?

Fabien Potencier のWhat is Dependency Injection?のようなこの問題に関する興味深いものを見てきました。Pimple - PHP 5.3 の依存性注入コンテナとProxy Patternに関するいくつかの記事がありますが、それらを実装するには、現在のコードをかなりいじる必要があるようです。もっと簡単な方法はありますか?

4

2 に答える 2

3

何かが足りないかもしれませんが、この場合の最も簡単な解決策は、ステータスのゲッターに、オブジェクトが存在しない場合に単純に作成させることです...

public function getStatus()
{
  if(!isset($this->status))
  {
     // or however you creat this object..
     $this->status = new UserStatus($this->user_id);
  }

  return $this->status;
}

public function __get($property)
{
   $method = 'get'.ucfirst($property); // getStatus
   if(method_exists($this, $method)) 
   {
      return $this->$method();
   }
}

__getいつでもマジックメソッドを使用する$user->statusことで、 が呼び出されます$user->getStatus()。もちろん、次のようにいつでもアクセスすることもできます$user->getStatus()->getIcon()

ただし、プロパティへのアクセスを設定することにした場合は、モデル全体で一貫した方法で行うことをお勧めします。

于 2011-02-06T04:58:46.680 に答える
1

ステータス クラスを別のファイルに配置してから、php のオートローディング メカニズムを活用できます。

http://php.net/manual/de/language.oop5.autoload.php

アクセスするまでそのファイルをロードしないようにします。

バイト コード キャッシュとオプティマイザーにとって、自動読み込み (または実際にはあらゆる種類の条件付き読み込み) が厄介であるという噂がありますが、残念ながらその影響についてはよくわかりません。

PS: この時点では、マニュアルには明示的に明示されていません。魔法の __autoload 関数を定義する代わりに、spl_autoload_register() を使用することもできます。これは少し強力です。

于 2011-02-06T04:57:07.083 に答える