Статические методы — это почти то же самое, что и статические свойства, только методы.
<?php
class User
{
private static $table = 'users';
public static function getTable()
{
return self::$table;
}
}
User::getTable(); // users
Статические методы, как и свойства, не принадлежат объектам, они — часть класса. Следовательно, из статического метода невозможно получить доступ к объекту (ведь нет никакого объекта) через $this
. Внутри него $this
просто не существует. Статические методы могут обращаться к другим статическим методам, статическим свойствам или константам, используя self
.
Как я уже упоминал в предыдущем уроке, статические методы часто используют для доступа к приватным статическим свойствам. Причём, как геттеры, так и сеттеры, которые нужны редко, но все же бывают нужны.
Но есть ещё один способ использования статических методов, не связанный со статическими свойствами. Их используют как способ создать объект вместо прямого вызова конструктора через оператор new
.
Как вы помните, PHP (как, впрочем, и любой динамический язык) позволяет иметь ровно один конструктор для класса. В случае таких данных, как время, это — серьёзное ограничение, потому, что нельзя одним конструктором описать все возможные способы создания дат, которые используются в коде.
<?php
$date = new DateTime('2000-01-01');
В стандартной библиотеке PHP есть класс DateTime
, который принимает на вход строчку определённого формата и возвращает соответствующий объект. А что, если в нашей программе формат времени другой? А если у нас вообще нет строчки, а есть отдельные числа? Естественным желанием было бы иметь разные конструкторы под разные задачи. Их у нас нет, но зато есть статические методы, которых можно создать столько, сколько нужно.
<?php
// Специальная библиотека для работы с датами будет рассматриваться в следующем курсе
$vancouverTimeRightNow = Carbon::now('America/Vancouver'); //implicit __toString()
$noonTodayLondonTime = Carbon::createFromTime(12, 0, 0, 'Europe/London');
$internetWillBlowUpOn = Carbon::create(2038, 01, 19, 3, 14, 7, 'GMT');
Как видно из кода выше, статические методы имеют разные сигнатуры, но внутри они, так или иначе, вызывают конструктор, передавая туда уже подготовленные параметры. Конструктор можно вызывать двумя способами: первый — использовать полное имя класса, второй — через self
. Второй способ предпочтительнее просто потому, что позволяет не дублировать имя класса.
<?php
class Carbon
{
public static function now($timezone = '')
{
return new self(date("Y-m-d H:i:s"), $timezone);
}
}
Подводя итог, можно сказать, что статические методы используют как фабрику объектов в случаях, когда создание объекта достаточно сложное и требует некоторых манипуляций.
Ещё есть третий способ использования статических методов — глобальные функции пространств имён. Такой способ особенно популярен в языках типа Java, где физически невозможно создать функцию вне класса. В PHP очень похожая модель, и, хотя создавать функции можно в обычных пространствах имён, по факту делают так редко. Одна из причин связана с наличием автозагрузки классов, такой способ банально удобнее с точки зрения лени. С точки зрения "правильности" такой код скорее "неправильный". Если статическая функция не порождает объектов данного типа, или хотя бы не использует статические свойства, то непонятно, почему она вообще оказалась в этом классе. Но это в теории. На практике есть устоявшиеся нормы и традиции. В своей практике, работая в проектах, построенных на классовой модели (не все проекты в PHP разрабатываются именно так), вы будете встречать код, который почти всегда принадлежит тому или иному классу.
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.