2011-02-06 2 views
0

わかりやすくするために、Webアプリケーションで使用される2つのクラスUserとUserStatusがあるとします。私は、必要に応じてのみ、それをインスタンス化する方法を探していますので、ステータスオブジェクトは、(遅延読み込み、それを呼び出す)が使用されることはありませんHTTPリクエストのほとんどで必要に応じてPHPクラスのプロパティとして定義されたオブジェクトをインスタンス化します(遅延読み込み)

<?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()"/>; 
} 

?> 

status->method()コールを傍受し、そのオブジェクトをオンザフライで作成するにはどうすればよいですか?

重要な注意点は、私はUSERSTATUSクラスで利用可能な$user_id、そうでない場合fetchDataFromDB()方法は、それがデータをフェッチする必要のあるユーザーには分からないだろうが必要だということです。これはどのように行うべきですか?

私はファビアンPotencierのWhat is Dependency Injection?Pimple - a PHP 5.3 dependency injection containerのようにこの問題について、いくつかの興味深いものを見てもプロキシパターンに関するいくつかの記事が、私は現在のコードを台無しにたくさん持っているように見えるそれらを実装しました。もっと簡単な方法はありますか?

答えて

3

たぶん__get魔法のメソッドをいつでも使用することにより...

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(); 
    } 
} 

を何かが足りないイムが、この場合に最も簡単な解決策は、それが存在するdoesntの場合、単にオブジェクトを作成しますステータスのためのあなたのゲッターを持っているだろうと思われます$user->statusとすれば$user->getStatus()と呼びます。もちろん、あなたはいつも同じようにアクセスすることもできます:$user->getStatus()->getIcon()

あなたのプロパティにアクセスするように設定することを決めましたが、モデル全体で一貫した方法で行うことをお勧めします。

+0

それは本当にそれを行う方法ですが、 'UserStatus'クラスはいくつかのメソッドを提供しています。そのうちの1つは上記のような' getIcon() 'です。あなたの提案を使用して、私はアイコンメソッドを2つの手順で呼び出す必要があります: '$ user-> getStatus(); $ user-> status-> getIcon() 'となります。私はそれをもっと巧みにしようとしていましたが、ちょっと、うまくいきます。ありがとう。 – noisebleed

+0

あなたはmagit '__get'を使うことはできません。' status'は保護されていて公開されていないので、あなたはそれをやろうとしていました。そうでなければ、Userクラスの外から直接アクセスすることはできませんでした。 ..私の更新を見てください。 – prodigitalson

+0

これは '__get()'を使うことを目的としたもので、目的に応じて 'status'を保護していましたが、私は' __get() 'を単にコード化しませんでした。あなたのアップデートは私の疑問を解決する、それは本当に素晴らしいアプローチであり、私はそれを取ることを嬉しく思います。再度、感謝します。私は今、尊敬しているわけではありません:(私は、DependencyInjectionやEventDispatcherのようなSymfonyコンポーネントを使って自家製のフレームワークを書き直すことを検討していますが、まだ少しですそれらをレイアウトする方法を混乱させる。 – noisebleed

1

あなたは別のファイルにステータスクラスを配置し、PHPのオートローディングmechnism活用できます。あなたはそれにアクセスするまで、そのファイルをロードしないように

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

を。

バイトコードキャッシュとオプティマイザの自動ロード(または実際には条件付きロードのいずれか)が面倒であるという噂がありますが、残念ながら私はその影響についてあまり気付きません。

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

+0

私はいくつかの小さなクラスを持っていて、ファイルに入れていますが、それぞれは私がやりたいことではありません。私はこの問題をprodigitalsonが提案したラインの何かで解決しようとし、それがうまくいかなければここに戻ります。ありがとう。 – noisebleed

関連する問題