[英]Instantiate object defined as property in a PHP class as needed (lazy loading)
為簡單起見,假設我有2個類,即Web應用程序中使用的User和UserStatus。
<?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的《 什么是依賴注入? 和Pimple-一個PHP 5.3依賴項注入容器,以及一些有關Proxy Pattern的文章,但是要實現它們,看起來我不得不對當前的代碼感到困惑。 有沒有更簡單的方法?
也許我錯過了一些東西,但是在這種情況下,最簡單的解決方案似乎是讓Status的獲取者簡單地創建對象(如果不存在)...
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
時使用__get
magic方法,它將調用$user->getStatus()
。 當然,您也總是可以像這樣訪問它: $user->getStatus()->getIcon()
。
但是,您決定設置訪問屬性的權限,因此建議您在整個模型中以一致的方式進行操作。
您可以將狀態類放在其他文件中,然后利用php的自動加載機制:
http://php.net/manual/de/language.oop5.autoload.php
在您訪問該文件之前不要加載該文件。
有傳言說自動加載(或實際上只是任何一種條件加載)對於字節碼緩存和優化器來說都是麻煩的,盡管不幸的是,我對此影響不甚了解。
PS:手冊在這一點上並沒有明確指出:您還可以使用spl_autoload_register()而不是僅定義魔術__autoload函數。 這稍微更強大。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.