Константы в PHP — CONST и DEFINE()

Константы в 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 и чем они могут быть полезны!

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *