Константы в PHP — CONST и DEFINE()
В этой статье мы разберемся с различиями в объявлении констант PHP с использованием ключевого слова const и функции define().
Константы в PHP — это "неизменяемые" значения, которые задаются один раз и не могут быть изменены в дальнейшем. Если вы попытаетесь изменить значение, оно не изменится, и вы получите предупреждение: "Константа уже ��пределена":
define('FOO', 'val');
define('FOO', 'val2'); // Notice: Constant already defined
echo FOO; // > val
Константы в PHP можно объявлять двумя способами:
// 1
define('NAME', 'VALUE');
// 2
const NAME = 'VALUE';
Каждый метод имеет свои особенности. Давайте рассмотрим их подробнее, шаг за шагом, и что изменилось в каждой версии PHP.
Содержание:
- Как создать константы
- Отличия между define() и const
- Константы классов PHP
- "Магические" константы
Как создать константы
PHP менее 5.3
До версии 5.3 в PHP константы можно было определять только с помощью define(). Ключевое слово const появилось в версии 5.3.
Константы могут хранить только скалярные значения. Скалярные значения — это простые типы: целое число, число с плавающей запятой, строка и булево значение. Типы массив, объект, ресурс и т.д. не являются скалярными.
// скаляры
define('FOO', 10);
define('FOO', 10.9);
define('FOO', 'val');
define('FOO', true);
// не скаляры
define('FOO', array(1)); // константа не будет установлена, и мы получим предупреждение
define('FOO', (object) array(1)); // константа не будет установлена, и мы получим предупреждение
С версии PHP 5.3
Появилось ключевое слово const, которое также позволяет определять константы. Однако, в const нельзя использовать выражения: переменные, функции, конкатенацию, и нужно указывать только скалярные значения:
const FOO = 'val'; // без ошибок
const FOO = $var; // Ошибка синтаксиса
const FOO = home_url(); // Ошибка синтаксиса
const FOO = 5 + 10; // Ошибка синтаксиса
const FOO = 'foo' . 'bar'; // Ошибка синтаксиса
Для define() таких ограничений нет:
define('FOO', 'val'); // без ошибок
define('FOO', $var); // без ошибок
define('FOO', home_url()); // без ошибок
define('FOO', 5 + 10); // без ошибок
define('FOO', 'foo' . 'bar'); // без ошибок
PHP 5.6
Стало возможным использовать примитивные выражения в значениях const:
const FOO = 1 + 2;
const FOO = 'foo' . 'bar';
Также стало возможно хранить массивы в константах:
const FOO = [1, 2, 3]; // работает
define('FOO', [1, 2, 3]); // не работает в PHP 5.6, работает в PHP 7.0
Отличия между DEFINE() и CONST
1. CONST ДОЛЖЕН БЫТЬ ОБЪЯВЛЕН В ГЛОБАЛЬНОМ КОНТЕКСТЕ
Константы определяются во время компиляции скрипта. Это значит, что const нельзя использовать внутри функций, циклов или блоков try/catch.
if (1) {
const NAME = 'VALUE'; // не работает
}
// а так работает
if (1) {
define('NAME', 'VALUE'); // работает
}
2. CONST ВСЕГДА РЕГИСТРОЧУВСТВИТЕЛЕН
В то время как define() позволяет создавать константы, не обращая внимания на регистр:
define('NAME', 'VALUE', true);
echo NAME; // VALUE
echo name; // VALUE
3. CONST ПОНИМАЕТ ТОЛЬКО СКАЛЯРЫ, МАССИВЫ И ПРИМИТИВНЫЕ ВЫРАЖЕНИЯ
Вы не можете передавать переменные, функции и выражения в const, но можете в define():
const FOO = $var; // Ошибка синтаксиса
const FOO = home_url(); // Ошибка синтаксиса
define('FOO', $var); // без ошибок
define('FOO', home_url()); // без ошибок
С версии PHP 5.6 в const также можно указывать примитивные выражения и массивы, а не только скаляры.
4. CONST МОЖЕТ ХРАНИТЬ МАССИВЫ С PHP 5.6, WHILE DEFINE — С PHP 7.0
const FOO = [1, 2, 3]; // работает в PHP 5.6
define('FOO', [1, 2, 3]); // работает в PHP 7.0
5. CONST ЗАВИСИТ ОТ НАЗВАНИЙ ПРЕДЕЛОВ, WHILE DEFINE — НЕТ
Если мы создадим константу в пространстве имен, тогда:
- Когда мы используем
const, константа будет в этом пространстве имен и не будет доступна извне. - Когда используем
define(), константа регистрируется как глобальная и доступна извне.
namespace MySpace;
const FOO = 'bar';
define('FOO', 'baz');
// Теперь чтобы обратиться к этим константам вне пространства имен, нужно написать так:
echo MySpaceFOO; // bar
echo FOO; // baz
Сравнение
Практически всегда лучше определять константу с помощью define(), так как так больше возможностей и меньше вероятности "поймать" ошибку. Исключения:
- Если у вас версия PHP 5.6 и нужно хранить массив в константе,
constвам поможет. - Если вам нужна константа, которая не будет доступна глобально, а только в пределах пространства имен.
Константы классов PHP
Константы классов объявляются только с помощью const. Правила для них такие же, как описано выше: принимаются только скалярные значения, они не понимают переменные, функции и выражения.
Объявленная константа принадлежит классу, она не принадлежит никакому объекту и общая для всех объектов (экземпляров) класса.
class My_Class {
const NAME = 'VALUE';
// начиная с PHP 5.6, можно использовать математические выражения
const SEC_PER_DAY = 60 * 60 * 24;
function print_name() {
// доступ к константе класса внутри метода
echo self::NAME;
}
}
// доступ к константе извне класса
echo My_Class::NAME;
До PHP 7.1 константы классов всегда публичные — у них нет статуса private или protected. Но начиная с PHP 7.1, классовым константам можно добавить модификатор:
class Foo {
// Начиная с PHP 7.1.0
public const BAR = 'bar';
private const BAZ = 'baz';
}
Константы классов похожи на статические свойства класса, но без подробностей: константу нельзя изменить.
class My_Class {
const NAME = 'VALUE';
static $name = 'VALUE';
}
echo My_Class::NAME;
echo My_Class::$name;
"Магические" константы
И наконец, давайте вспомним о специальных константах в PHP.
В PHP есть девять "магических" констант, которые меняют свое значение в зависимости от контекста использования. Например, значение __LINE__ зависит от строки в скрипте, где указана эта константа.
Все "магические" константы разрешаются во время компиляции, в отличие от обычных констант, которые разрешаются во время выполнения. Специальные константы нечувствительны к регистру, и ниже приведен их список:
__LINE__— Текущий номер строки в файле.__FILE__— Полный путь и имя файла, в котором используется константа.__DIR__— Директория файла, в котором она используется. То же самое, что иdirname(__FILE__). Не имеет завершающего слэша, кроме корневого каталога.__FUNCTION__— Имя функции.__CLASS__— Имя класса. Это имя включает пространство имен, в котором класс был объявлен (например, FooBar). Также работает в трейтах. Когда используется в методах трейтов, это имя класса, в котором используются эти методы.__TRAIT__— Имя трейта. Это имя включает пространство имен, в котором был объявлен трейт (например, FooBar).__METHOD__— Имя метода класса.__NAMESPACE__— Текущее имя пространства имен.ClassName::class— Полное имя класса (включая пространство имен).
Теперь вы знаете, как использовать константы в PHP и чем они могут быть полезны!