Статические static методы и свойства
При работе с классами можно делать методы и свойства, которые для своего вызова не требуют создания объекта. Такие методы и свойства помечаются ключевым словом static
. Статические методы и свойства содаются один раз для всего класса и относятся ко всему классу, тогда для нестатических свойств и методов создается отдельная копия для каждого объекта.
<?
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>";
}
При обращении к статическим методам и свойствам используется имя класса и оператор ::
, вместо операции доступа ->
, так как статический метод относится ко всему классу, а не к конкретному объекту этого класса.
<?
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
. Например, добавим в класс человека метод, который будет вычислять, сколько человеку осталось до пенсии:
<?
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
следующим образом:
<?
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