Для простоты предположим, что у меня есть 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, а также некоторые статьи о Proxy Pattern, но реализовать их, похоже, я возиться много с текущим кодом. Есть ли более простой способ?
Это действительно способ сделать это, но класс 'UserStatus' предоставляет несколько методов, один из которых является' getIcon() ', как показано выше. Используя ваше предложение, я должен вызвать метод значка в двухэтапной процедуре: '$ user-> getStatus(); $ User-> СТАТУС> getIcon() '. Я пытался сделать его более умным, но эй, он работает. Благодарю. – noisebleed
нет, вы не можете использовать magiv '__get', я предположил, что вы собираетесь это делать, поскольку« статус »был защищен, а не публичный, иначе вы не могли бы получить доступ к нему непосредственно из-за пределов своего класса пользователя ... поэтому я его не включил. .. см. мое обновление. – prodigitalson
Да, идея состояла в том, чтобы использовать '__get()', и я оставил «статус» с целью защиты, но я не кодировал '__get()' просто потому, что не знал наилучшего подхода к тому, как это сделать. Ваше обновление решает мои сомнения, это очень хороший подход, и я рад его принять. Еще раз спасибо.О том, как это сделать последовательным образом, это хороший совет, который я не уважаю прямо сейчас :(Я рассматриваю переписку своей домашней структуры с использованием компонентов Symfony, таких как DependencyInjection и EventDispatcher, но я все еще немного путают о том, как их расставить. – noisebleed