В предлагаемом материале освещаются вопросы использования ключевого слова static для объявления статических свойств и методов, а также использования констант класса.
Ключевое слово static
Ключевое слово static использовалось в PHP и раньше применительно к статическим переменным в функциях.
Пример 8.1. Рекурсия
<?php
function recursion()
{
static $level = 5;
if ($level > 0) {
print $level--;
recursion();
}
}
?>
<?php
recursion();
?>
54321
В отличие от обычных, статическая переменная инициализируется только один раз - при первом вызове функции в объявлении с ключевым словом static. В дальнейшем это объявление
игнорируется, а переменная сохраняет свое значение между вызовами функции.
Однако, в PHP 5 это ключевое слово стало возможным применять и по отношению к свойствам и методам класса. В данном контексте оно означает, что статическое свойство или метод принадлежит непосредственно классу, а не его объектам. Как следствие, становится возможным обращаться к этому свойству или методу без создания нового объекта (и, напротив,
становится невозможным обращаться к нему обычным способом).
Ключевое слово static употребляется в объявлении сразу после модификатора доступа, регулирующего видимость свойства или метода. Если видимость не указана, то по умолчанию свойство или метод считается публичным, а объявление начинается непосредственно с ключевого слова static.
Статические
свойства
Если обычные свойства принадлежат объектам, то статические свойства принадлежат всему классу и являются общими для всех его объектов. Рассмотрим это положение более подробно на следующем примере.
Пример 8.2. Класс Cat со статическим свойством
<?php
class Cat
{
private $name;
public static $numberOfCats = 0;
function __construct($name)
{
$this->name = $name;
self::$numberOfCats++;
}
function __destruct()
{
self::$numberOfCats--;
}
}
?>
<?php
$neko = new Cat('Neko');
$sindycat = new Cat('Sindycat');
print Cat::numberOfCats;
?>
2
Обычное свойство, принадлежащее объектам класса. У каждого объекта (кота) есть свое имя, отличающее его от остальных.
Статическое свойство, принадлежащее всему классу. В данном случе, это свойство является счетчиком и отражает общее число существующих котов. Оно не имеет смысла в контексте отдельно взятого объекта (кота). Более того, если бы это свойство принадлежало объектам, то при появлении нового (либо исчезновении существующего) кота пришлось бы обеспечивать синхронное его изменение у всех имеющихся
объектов.
Каждый объект отвечает за установку правильного значения своего свойства. Обращение к нему производится посредством псевдопеременной $this, обозначающей данный объект, и разделителя ->.
Обращение к статическому свойству класса из методов этого класса производится при помощи выражения self (без символа $ в начале!), которое соответствует текущему классу, и оператора контекста (::).
Каждый объект может увеличивать и уменьшать значение счетчика (статического свойства класса) на единицу.
Доступ к статическому свойству из глобального контекста производится по имени класса, которому оно принадлежит, и оператора контекста (::).
Статические методы
Отличие статических методов от обычных методов не столь выражено, как
отличие статических методов от обычных методов, так как и статические, и обычные методы принадлежат классу, а не объекту. Однако, статические методы, в отличие от обычных, не могут работать с текущим объектом (иными словами, в статических методах нельзя использовать псевдопеременную $this).
public static function count()
{
return self::$numberOfCats;
}
Обращаться к статическому методу из глобального контекста следует так же, как и к статическим свойствам: по названию класса и с использованием оператора контекста.
print Cat::count();
Константы класса
Близкими по своей сущности к статическим свойствам класса являются константы класса. Можно
сказать, что константы - это неизменяемые статические свойства класса.
Константы, как своего рода противоположность переменным, существовали и в более ранних версиях PHP (см. Константы). Однако, те константы (доступные, впрочем, и в PHP 5) определялись в глобальном контексте с помощью функции define().
В
PHP 5 с помощью специального ключевого слова const могут быть определены константы в контексте класса. Порядок их определения и последующего обращения к ним виден из следующего примера.
Пример 8.4. Константы класса
<?php
class Color
{
const RED = '#ff0000';
const GREEN = '#00ff00';
const BLUE = '#0000ff';
public $color;
function __construct($color)
{
$this->color = $color;
}
}
?>
<?php
$green = new Color(Color::GREEN);
?>
Контрольные вопросы и задания
Укажите причину сообщения о неопределенном свойстве.
<?php
class Foo
{
public static $foo = 'bar';
/* ... */
}
?>
<?php
$obj = new Foo;
print $obj->foo;
?>
PHP Notice: Undefined property: Foo::$foo
Объясните причину ошибки.
<?php
class Foo
{
public function foo()
{
// ...
}
}
?>
<?php
Foo::foo();
?>
PHP Fatal error: Non-static method Foo::foo() cannot be called statically
Исправьте ошибки и получите длину окружности с радиусом 5.
Замечание
Константа
класса PI используется здесь исключительно с учебной целью. На самом деле, вместо нее следовало бы использовать предопределенную константу языка M_PI.
<?php
class Circle
{
const PI = define(3.14);
public static function circumference($radius)
{
return 2 * self::$PI * $radius;
}
}
?>