Кроме обычных методов и свойств с разными модификаторами доступа класс может содержать статические методы и свойства. Такие методы и свойства помечаются ключевым словом static. Статические методы и свойства создаются один раз для всего класса и относятся ко всему классу, тогда как для нестатических свойств и методов создается отдельная копия для каждого объекта.
<?php class Person { public $name, $age; static $retirenmentAge = 65; function __construct($name, $age) { $this->name = $name; $this->age = $age; } function sayHello() { echo "Привет, меня зовут $this->name<br>"; } static function printPerson($person) { echo "Имя: $person->name Возраст: $person->age<br>"; } } ?>
Здесь определено статическое свойство retirenmentAge
, которое хранит пенсионный возраст. Если возраст - это показатель конкретного человека и может отличаться
для разных людей, то пенсионный возраст, как правило, устанавливается общий для всех. Поэтому это свойство можно сделать статическим - оно относится ко всему
классу Person, а не устанавливается отдельно для каждого объекта. Для объявления статического свойства перед его именем ставится модификатор static:
static $retirenmentAge = 65;
Также в классе определен статический метод printPerson()
, который выводит информацию о человеке, который в качестве параметра передается в метод.
Этот метод также не зависит от конкретного объекта класса Person, а относится ко всему классу Person в целом. Чтобы объявить статический метод,
также перед словом function
ставится модификатор static:
static function printPerson($person) { echo "Имя: $person->name Возраст: $person->age<br>"; }
При обращении к статическим методам и свойствам используется имя класса и оператор ::
, вместо операции доступа ->
, так как статический
метод относится ко всему классу, а не к конкретному объекту этого класса.
<?php class Person { public $name, $age; static $retirenmentAge = 65; function __construct($name, $age) { $this->name = $name; $this->age = $age; } function sayHello() { echo "Привет, меня зовут $this->name<br>"; } static function printPerson($person) { echo "Имя: $person->name Возраст: $person->age<br>"; } } $tom = new Person("Tom", 36); // вызов нестатического метода $tom->sayHello(); // вызов статического метода Person::printPerson($tom); // обращение к статическому свойству echo "Пенсионный возраст: " . Person::$retirenmentAge . "<br>"; ?>
Вывод программы:
Привет, меня зовут Tom Имя: Tom Возраст: 36 Пенсионный возраст: 65
Для обращения к статическим свойствам и методам внутри класса вместо имени класса может применяться ключевое слово self. Например, добавим в класс человека метод, который будет вычислять, сколько человеку осталось до пенсии:
<?php class Person { public $name, $age; static $retirenmentAge = 65; function __construct($name, $age) { $this->name = $name; $this->age = $age; } function sayHello() { echo "Привет, меня зовут $this->name<br>"; } static function printPerson($person) { echo "Имя: $person->name Возраст: $person->age<br>"; } function checkAge() { if($this->age >= self::$retirenmentAge) echo "Пора на пенсию<br>"; else echo "До пенсии еще " . (Person::$retirenmentAge - $this->age) . " лет<br>"; } } $tom = new Person("Tom", 36); $tom->checkAge(); ?>
Вывод программы:
До пенсии еще 29 лет
Стоит отметить, что в статических методах мы можем обращаться только к статическим свойствам и методам. Но не можем обращаться к НЕстатическим
свойствам и методам через $this
. Например:
static function printPerson($person) { echo "Имя: $person->name Возраст: $person->age<br>"; // в статических методах можно обращаться к статическим методам и свойствам echo "Пенсионный возраст: " . self::$retirenmentAge . "<br>"; // но нельзя обращаться к нестатическим методам и свойствам // echo "Имя: " . $this->name . "<br>"; // так нельзя // $this->sayHello(); // так нельзя }
Здесь в статическом методе printPerson()
мы можем обратиться к статической переменной retirenmentAge
:
echo "Пенсионный возраст: " . self::$retirenmentAge . "<br>";
Но не можем обратиться к нестатическим свойствам и методам:
// echo "Имя: " . $this->name . "<br>"; // так нельзя // $this->sayHello(); // так нельзя
При этом статические методы и свойства также могут иметь модификаторы доступа. Например, изменим класс Person следующим образом:
<?php class Person { public $name; private $id; private static $counter=0; function __construct($name) { self::$counter++; $this->id = self::$counter; $this->name = $name; } static function getCounter() { return self::$counter; } function getId() { return $this->id; } } $tom = new Person("Tom"); $bob = new Person("Bob"); echo "$tom->name имеет id: " . $tom->getId() . "<br>"; echo "$bob->name имеет id: " . $bob->getId() . "<br>"; echo "Всего пользователей: " . Person::getCounter(); ?>
В классе Person определено свойство $id
, которое представляет идентификатор пользователя. И также определено приватное статическое свойство
$counter
, которое хранит общее количество созданных пользователей. В конструкторе мы увеличиваем статическую переменную на единицу, а затем устанавливаем ее значение для свойства $id.
Количество созданных пользователей - это атрибут, общий для всего класса, который независит от конкретного объекта. Однако в то же время нежелательно,
чтобы его извне могли произвольно изменить. Поэтому свойство $counter определено как приватное. А чтобы увидеть его значение, определен статический метод getCounter()
.
Вывод программы:
Tom имеет id: 1 Bob имеет id: 2 Всего пользователей: 2