Статические методы и свойства в PHP
Сегодня мы поговорим о статических свойствах и методах в PHP. Если коротко – то это свойства и методы, которые принадлежат классу целиком, а не созданным объектам этого класса. То есть использовать их можно даже без создания объектов. Иногда их называют просто свойствами и методами класса. Не путайте их со свойствами и методами объектов, которые мы изучали ранее!
Определяются статические свойства и методы с помощью ключевого свойства static.
Статические методы
Давайте рассмотрим самый простой пример статического метода.
class A {
public static function test(int $x)
{
return 'x = ' . $x;
}
}
Как мы уже сказали, статические свойства и методы принадлежат классу, а не объектам, и использовать мы их можем без создания объектов. Для этого используется имя класса и двойное двоеточие, вот так:
echo A::test(5);
Результат:
x = 5
Само собой, становится понятно, что статические свойства и методы нужны, либо когда нам не требуется объект как таковой, либо его пока нет, но мы хотим создать объект с какими-то значениями по-умолчанию. Давайте сразу приведем пример. Допустим, у нас есть класс User:
class User
{
private $role;
private $name;
public function __construct(string $role, string $name)
{
$this->role = $role;
$this->name = $name;
}
}
Мы с помощью конструктора можем создавать пользователей с разными ролями (модератор, администратор, простой пользователь) и именами.
Чтобы создать администратора, нам нужно сделать следующее:
$admin = new User('admin', 'Иван');
С помощью статического метода мы можем создать объекты этого класса, с указанием каких-либо значений по умолчанию. Например, можем сделать метод, который будет создавать администраторов, и ему на вход нужно будет только имя пользователя.
class User
{
private $role;
private $name;
public function __construct(string $role, string $name)
{
$this->role = $role;
$this->name = $name;
}
public static function createAdmin(string $name)
{
return new self('admin', $name);
}
}
Этот метод возвращает новый объект текущего класса (благодаря слову self), и передаёт ему всегда в аргумент $role значение ‘admin’. Использование такого метода будет выглядеть следующим образом.
$admin = User::createAdmin('Иван');
var_dump($admin);
Вывод будет следующим:
object(User)[1]
private 'role' => string 'admin' (length=5)
private 'name' => string 'Иван' (length=8)
Всё у нас успешно сработало. В данном упрощенном примере, может показаться, что такой метод мало чем полезен, однако представьте, как будет удобно, если таких параметров в конструкторе будет 5, и из них 4 можно будет сделать для какого-то рода объектов всегда одинаковыми. В таком случае статический метод, порождающий объекты, становится изящным способом упростить код.
Отличие от методов объектов
В отличие от методов объектов, в статических методах нет слова $this – оно указывает только на текущий объект. Если объекта нет – нет и $this!
Статические свойства
А что на счёт статических свойств? Для чего можно использовать их?
Давайте создадим класс со статическим свойством:
class A
{
public static $x;
}
Мы можем читать и писать в это свойство, не создавая объектов этого класса:
A::$x = 5;
var_dump(A::$x); // 5
Кроме того, эти же свойства будут доступны и у объектов этого класса:
A::$x = 5;
$a = new A();
var_dump($a::$x); // 5
И даже внутри этих объектов мы сможем достучаться до этих свойств, при помощи слова self::
class A
{
public static $x;
public function getX()
{
return self::$x;
}
}
A::$x = 5;
$a = new A();
var_dump($a->getX()); // 5
Ну и конечно же, так как статические свойства принадлежат классу, а не объектам, мы можем использовать их в статических методах.
class A
{
public static $x;
public static function getX()
{
return self::$x;
}
}
A::$x = 5;
$a = new A();
var_dump($a::getX());
Применение статических свойств
Порой приходится в классе хранить информацию, которая будет использоваться всеми объектами, или будет говорить что-то общее обо всех объектах. Например, можно сделать счётчик созданных объектов внутри класса. Давайте создадим в классе Human статическую переменную $count, и сделаем её приватной, чтобы изменять её можно было только внутри класса. И давайте сразу сделаем для неё геттер.
class Human
{
private static $count = 0;
public static function getCount()
{
return self::$count;
}
}
Давайте выведем значение этой переменной.
echo 'Людей уже ' . Human::getCount(); // 0
Что нужно сделать, чтобы при создании нового объекта класса Human, это число увеличивалось? Правильно, просто увеличивать это значение в конструкторе – он ведь вызывается каждый раз при создании объекта.
class Human
{
private static $count = 0;
public function __construct()
{
self::$count++;
}
public static function getCount()
{
return self::$count;
}
}
Давайте проверим, что всё работает:
$human1 = new Human();
$human2 = new Human();
$human3 = new Human();
echo 'Людей уже ' . Human::getCount(); // 3
Вот таким вот образом можно использовать статические свойста и методы классов. Есть и другие примеры их использования, но об этом мы поговорим в следующих уроках.
Комментарии