2011-02-06 34 views
0

爲了簡單起見,假設我在Web應用程序中使用了2個類User和UserStatus。根據需要將實例化對象定義爲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()"/>; 
} 

?> 

在大多數HTTP請求的狀態對象將不會被使用,因此我在尋找一種方式,需要的只是初始化它的(稱之爲延遲加載)。我應該如何攔截status->method()調用並即時創建該對象?

一個重要的注意的是,我需要$user_id可供UserStatus類,否則fetchDataFromDB()方法將不知道哪個用戶應該獲取數據。這應該怎麼做?

我看了一些有趣的東西,在這個問題上像小煜Potencier的What is Dependency Injection?Pimple - a PHP 5.3 dependency injection container,還有一些關於代理模式文章,但實現它們看起來像我有亂七八糟很多與當前的代碼。有一種更簡單的方法嗎?

回答

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

但是,您決定設置訪問您的屬性,我會建議在整個模型中以一致的方式進行。

+0

這確實是一種方法,但UserStatus類提供了幾種方法,其中之一是如上所示的getIcon()。使用你的建議,我必須在兩個步驟中調用圖標方法:`$ user-> getStatus(); $用戶>狀態 - >調用getIcon()`。我試圖讓它更聰明,但嘿,它很有用。謝謝。 – noisebleed 2011-02-06 14:33:54

1

你可以把狀態類在不同的文件中,然後利用PHP的自動加載mechnism:

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

,直到你訪問它不加載該文件。有傳言說,自動加載(或實際上只是任何一種條件加載)對於字節碼緩存和優化器來說是很麻煩的,但不幸的是我對這種影響並不知道太多。

P.S .:手冊在這一點上沒有說明rhis的明確性:您也可以使用spl_autoload_register()而不是僅僅定義magic __autoload函數。這稍微更強大。

+0

我有幾個小類,把它們放在一個文件中,每個都不是我想要做的事情。我會嘗試用什麼prodigitalson建議的東西來解決這個問題,然後如果它不起作用,就會復出。謝謝。 – noisebleed 2011-02-06 14:39:34