define() vs const в PHP: что выбрать и почему это важно

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

define() vs const в PHP: битва титанов объявления констант

Вы когда-нибудь задумывались, почему в PHP есть целых два способа объявить константу? Казалось бы, зачем плодить сущности? Но дьявол, как всегда, кроется в деталях. Этот вопрос на Stack Overflow собрал тысячи просмотров, и неспроста — разница между define() и const может серьёзно повлиять на архитектуру вашего кода.

Сегодня мы раз и навсегда разберёмся, что к чему. Вы узнаете не только синтаксические отличия, но и когда какой инструмент даёт реальное преимущество. Поехали!

Краткий экскурс: что такое константа в PHP?

Константа — это идентификатор для простого значения. Её главная фишка: значение не может быть изменено во время выполнения скрипта (в отличие от переменной). По умолчанию константы чувствительны к регистру, но это можно настроить (спойлер: с define()).

Пример классической константы:

<?php
define("MAX_UPLOAD_SIZE", 10485760); // 10 MB в байтах
echo MAX_UPLOAD_SIZE; // 10485760
?>

То же самое, но с const:

<?php
const MAX_UPLOAD_SIZE = 10485760;
echo MAX_UPLOAD_SIZE;
?>

Вроде бы одинаково. Но копнём глубже.

Главные отличия define() от const

Давайте разложим всё по полочкам. Вот ключевые различия, которые нужно знать каждому PHP-разработчику.

1. Время объявления: компиляция vs выполнение

Это самое фундаментальное отличие.

  • const — объявляется на этапе компиляции. Это значит, что вы не можете использовать const внутри циклов, условий или функций. Он должен быть объявлен в «теле» класса (для констант классов) или в глобальной области видимости.
  • define() — выполняется в рантайме. Вы можете поместить его куда угодно: внутрь if, for, while, даже в функцию (хотя это плохая практика).

Пример, который не сработает с const:

<?php
if (PHP_OS === 'WINNT') {
    const PLATFORM = 'Windows';
    // Fatal error: Cannot use const in control structure
}
?>

А с define() — пожалуйста:

<?php
if (PHP_OS === 'WINNT') {
    define('PLATFORM', 'Windows');
    echo PLATFORM; // Windows
}
?>

2. Типы данных: массивы и объекты

Долгое время define() поддерживал только скалярные типы (строки, числа, булевы значения). Начиная с PHP 7, define() научился работать с массивами.

const тоже поддерживает массивы (начиная с PHP 5.6), но не поддерживает объекты или выражения:

<?php
// Работает с PHP 7+
define('FRUITS', ['apple', 'banana', 'cherry']);
echo FRUITS[1]; // banana

// Тоже работает (PHP 5.6+)
const COLORS = ['red', 'green', 'blue'];

// А вот так — ошибка!
// const RESULT = 2 + 3; // Работает, это константное выражение
// const DYNAMIC = rand(1, 10); // Ошибка! Не константное выражение
?>

Важно: define() может использовать результат функций (define('SITE_NAME', get_site_name())), а const — только константные выражения (числа, строки, другие константы).

3. Пространство имён и область видимости

Тут есть тонкий, но важный нюанс.

  • define() — всегда создаёт глобальную константу. Даже если вы вызываете его внутри пространства имён, константа будет доступна отовсюду.
  • const — подчиняется правилам пространства имён. Константа, объявленная в неймспейсе MyApp\Config, будет называться MyApp\Config\DB_HOST.

Пример:

<?php
namespace MyApp\Config;

// define — глобальная
define('GLOBAL_DB', 'localhost');

// const — в неймспейсе
const LOCAL_DB = '127.0.0.1';

// Где-то в другом файле:
echo \GLOBAL_DB; // localhost
echo \MyApp\Config\LOCAL_DB; // 127.0.0.1
?>

4. Чувствительность к регистру

define() принимает третий необязательный параметр case_insensitive (до PHP 7.3). Если передать true, константу можно будет вызывать без учёта регистра. В PHP 8.0 этот параметр удалён.

<?php
// До PHP 7.3
define('SITE', 'PythonLib', true);
echo site; // PythonLib (работало)
?>

const — всегда чувствителен к регистру. SITE и site — разные вещи.

5. Константы классов

Это отдельная песня. Внутри классов можно использовать только const. define() там не работает.

<?php
class Database {
    const HOST = 'localhost';
    const PORT = 3306;
    
    // Так нельзя:
    // define('DB_NAME', 'test'); // Ошибка!
}
?>

Производительность: кто быстрее?

Короткий ответ: разница незначительна, но const чуть быстрее при чтении.

  • const — объявляется на этапе компиляции, поэтому доступ к нему — это просто подстановка значения.
  • define() — требует вызова функции при объявлении, хотя после объявления разница в скорости доступа минимальна.

В реальных проектах вы не заметите разницы, если не объявляете миллионы констант. Но если вы перфекционист — используйте const для статических значений.

Когда что использовать? Практические рекомендации

Давайте сведём всё в чёткие правила.

Используйте const, если:

  • Вы объявляете константу внутри класса (это единственный вариант).
  • Значение известно на этапе написания кода (например, PI = 3.14).
  • Вы хотите чётко следовать правилам пространства имён.

Блоги

Рекомендаций по книгам