Я делаю класс "Контейнер" для хранения всех экземпляров моей модели/сервиса, класс является одноэлементным.
Рассмотрим следующую часть кода (из проекта CodeIgniter):
public function getReviewModel()
{
static $loaded = false;
if (!$loaded)
{
$this->load->model('review_model');
$loaded = true;
}
return $this->review_model;
}
Мне интересно, можно ли по-прежнему использовать статический внутренний метод, подобный этому, или мне следует использовать только свойство класса (я имею в виду стандарт производительности и кодирования)?
Ответ 1 · рейтинг 1 · Elias Van Ootegem
Общее мнение относительно статики в PHP таково: Избегайте, если это вообще возможно. И да, в 99% случаев можно избежать статики.
Синглтонов следует избегать в 100% случаев. По причинам, которые вы можете найти здесь и практически везде в Интернете. Синглтоны похожи на коммунизм: звучит как хорошая идея, но когда ее реализуют на практике, оказывается, что есть одна или две вещи, которых вы не ожидали.
Основная цель синглтона - сохранять состояние, но сам PHP не имеет состояния. , так что приходит следующий запрос, синглтон все равно нужно повторно инициализировать.
Если я пишу геттеры, подобные вашим, я склонен создавать их с ленивой загрузкой:
class Example
{
private $reviewModel = null;//create property
public function getReviewModel()
{
if ($this->reviewModel === null)
{//load once the method is called, the first time
$this->reviewModel = $this->load->model('review_model');
}
return $this->reviewModel;
}
}
Это в основном делает то же самое, без использования статики. Поскольку я использую свойство, я по-прежнему сохраняю экземпляр, поэтому, если метод getReviewModel вызывается снова, вызов load->model пропускается, как и при использовании статического метода.
Однако, поскольку вы спрашиваете о производительности а также стандарты кодирования: статика немного медленнее, чем свойства экземпляра: у каждого экземпляра есть HashTable, содержащая его свойства, и указатель на его определение. Статические свойства находятся в последнем, поскольку они являются общими для всех экземпляров, поэтому статическое свойство требует дополнительной работы по поиску:
instance -> HashTable -> property
instance -> definition -> HashTable -> property
Это не полная история, проверьте ответ + ссылки здесь, но в основном: путь к статическому свойству длиннее.
Что касается стандартов кодирования: они существуют, хотя пока еще неофициальны, большинство крупных игроков подписываются на них, и вам следует: PHP -FIG
Такие вещи, как $this->_protectedProperty;, например, не соответствуют стандарту PSR-2, в котором совершенно недвусмысленно говорится:
Имена свойств НЕ ДОЛЖНЫ иметь префикс с одним подчеркиванием, чтобы указать защищенную или частную видимость.
Ответ 2 · рейтинг 2 · kuroi neko
В вашем примере ничто не мешает программисту создать экземпляр класса более одного раза (с ужасными результатами), поэтому это довольно запутанный фрагмент кода.
Статические переменные имеют свое применение, независимо от того, являются ли они локальными для функции или определены на уровне класса.
Особенно в PHP-скриптах, когда вывод часто представляет собой один фрагмент данных, который можно удобно обрабатывать как класс, определяющий только статические свойства и методы. .
Это был бы настоящий, надежный одноэлементный класс.
Так как спутать статическую переменную с динамической является распространенной ошибкой, я предпочитаю статические переменные класса, чтобы избежать путаницы (т. е. синтаксис self::$... выделяет их четко).