PHP: полный мануал с примерами, функциями и ООП
Практический мануал PHP: от переменных и читаемого кода до безопасных форм, интеграций, базы данных и ООП на примере магазина. Учебный маршрут, поиск функций, подробные примеры, разбор ошибок и исходники для скачивания.

Дерево руководства
Глава 9 · С нуля
Константы: одно имя для неизменного правила
От объявления и чтения правила до const/define, пространства имён, специальных имён, массивов и версионных особенностей. Четыре подробные карточки функций.
Первое действие: объявить правило и прочитать его
Одно правило читают два расчёта
Размер страницы объявлен один раз. Количество записей отличается, а правило для обеих страниц одинаковое.
- PAGE_SIZE = 3
Имя константы ведёт к неизменному значению 3.
- Каталог: 7 записей
Расчёт читает PAGE_SIZE и получает 3 страницы.
- Архив: 4 записи
Тот же размер страницы даёт 2 страницы.
Две подписи ниже показывают потребителей одного правила, а не ссылки PHP через &. Размер и количество записей — разные данные.
Рядом с ценами магазина нужно показывать обозначение валюты. Чтобы не перепечатывать его в каждом месте, дадим значению одно имя. Константа похожа на подписанное правило: имя связано с одним значением в текущем выполнении программы. Это не запись в базе и не настройка, которая сама сохранится после остановки PHP.
const SHOP_CURRENCY = 'RUB';— связываем имя со строкойecho SHOP_CURRENCY;— читаем значение- В вывод попадают три буквы
RUB
const начинает объявление; SHOP_CURRENCY — выбранное имя без знака $; = связывает его с начальным значением; кавычки ограничивают текст, а ; завершает инструкцию. echo отправляет прочитанное значение в вывод. Тег <?php начинает участок PHP-кода.
<?php
const SHOP_CURRENCY = 'RUB';
echo SHOP_CURRENCY;
Ожидаемый результат
RUBИмя после echo записано без кавычек: PHP находит связанную с ним строку. Запись echo 'SHOP_CURRENCY' напечатала бы название, а не RUB. Сохраните пример как example.php и выполните php example.php.
Попробуйте. Поменяйте валюту на EUR, оставив echo прежним.
Разбор
Измените значение в объявлении и запустите файл снова. Это изменение исходника до следующего запуска, а не переназначение константы внутри уже работающего скрипта.
Подписать две цены одним правилом
Теперь обозначение валюты участвует в двух ценниках. Значения цен различаются; правило подписи одно. Запятые в echo выводят части по очереди, пробел внутри кавычек отделяет число от обозначения. В примере цены заранее заданы целыми рублями.
<?php
const SHOP_CURRENCY = 'RUB';
$teaPrice = 150;
$cupPrice = 200;
echo 'Чай: ', $teaPrice, ' ', SHOP_CURRENCY, "\n";
echo 'Чашка: ', $cupPrice, ' ', SHOP_CURRENCY, "\n";
Ожидаемый результат
Чай: 150 RUB
Чашка: 200 RUB
Первый echo читает 150 и RUB, второй — 200 и то же RUB. Изменение объявления перед новым запуском изменит обе подписи. Переменная teaPrice по-прежнему может меняться в ходе расчёта. Замена RUB на EUR здесь меняет только надпись: пересчёта валют программа не делает.
- SHOP_CURRENCY хранит RUB.
- teaPrice=150 → «Чай: 150 RUB».
- cupPrice=200 → «Чашка: 200 RUB».
Попробуйте добавить стоимость тарелки 300 тем же способом. Получится «Тарелка: 300 RUB». Для денег с копейками сначала задайте единицы и правило форматирования; константа сама этого не решает.
Разбираем const PAGE_SIZE = 3 по частям
const PAGE_SIZE = 3;
echo PAGE_SIZE;| Часть записи | Что она означает |
|---|---|
| const | Объявить константу в этой области имён. Здесь объявление находится на верхнем уровне файла. |
| PAGE_SIZE | Наше имя правила. Знака $ нет; верхний регистр — договорённость об оформлении. |
| = 3 | Значение при объявлении. Это не разрешение присваивать константе новые значения позже. |
| ; | Конец инструкции. |
| PAGE_SIZE в echo | Прочитать значение. Строка "PAGE_SIZE" напечатала бы само имя. |
Объявите правило до места его использования. Для другого количества записей нужна переменная, для фиксированного размера страницы подходит константа. Названия чувствительны к регистру. Неизвестное имя в PHP 8 вызывает Error; кавычки вокруг ключей массива от этого не становятся необязательными.
Понятное имя без $ и единица измерения
Обычное переносимое имя начинайте с буквы A–Z/a–z или подчёркивания; дальше допустимы также цифры. Пробелы и дефисы не подходят для обычного обращения. PHP допускает некоторые дополнительные байты в идентификаторах, но это не проверка правильности Unicode-слова. Для общего проекта проще согласовать ASCII-имена. Верхний регистр — соглашение, а не требование языка.
| Запись | Как её читать |
|---|---|
| DELIVERY_PRICE_KOPECKS | Назначение и единица: 29900 нельзя принять за рубли. |
| PAGE_SIZE | Правило размера страницы. |
| 2_PAGES / page-size | Не обычные допустимые имена: цифра в начале или дефис. |
| __CUSTOM__ | Не занимайте форму имён, зарезервированную для специальных возможностей. |
<?php
const DELIVERY_LIMIT = 3;
const delivery_limit = 7;
echo DELIVERY_LIMIT, "\n";
echo delivery_limit, "\n";
Ожидаемый результат
3
7
Это две разные константы. В рабочем коде такая пара неудобна: выбирайте содержательно разные имена. Встроенные true, false и null имеют особые правила; не выводите из них правило для пользовательских имён. Запятые в echo выводят части по очереди, "\n" означает перевод строки.
Изменяемые данные и неизменное правило
Текущий номер страницы меняется, размер страницы обычно задан настройкой. Переменная хранит меняющееся значение; константа выражает правило. Слово «глобальная» не делает переменную константой.
<?php
const PAGE_SIZE = 12;
$page = 1;
echo $page, ': ', PAGE_SIZE, "\n";
$page = 2;
echo $page, ': ', PAGE_SIZE, "\n";
Ожидаемый результат
1: 12
2: 12
Присваивание меняет page, оба чтения PAGE_SIZE дают 12. У константы нет обычного переназначения через = и удаления через unset. Для следующей страницы меняется переменная, а не правило размера.
<?php
const LIMIT = 12;
$LIMIT = 5;
echo LIMIT, "\n";
echo $LIMIT, "\n";
Ожидаемый результат
12
5
Переменная $LIMIT не заменяет константу LIMIT. Технически допустимо, но лучше назвать её $requestedCount, чтобы различие было видно по смыслу.
Начальное значение из других правил
Правило задано в минутах, а операция принимает секунды. Сохраним обе единицы под ясными именами. Знак * умножает числа. В const допустимы константные выражения — особый набор разрешённых операций. Обычное чтение переменной и произвольный вызов вроде getenv сюда не подходят; набор возможностей расширяется с версиями.
<?php
const MINUTES_PER_RUN = 5;
const SECONDS_PER_MINUTE = 60;
const RUN_TIMEOUT_SECONDS = MINUTES_PER_RUN * SECONDS_PER_MINUTE;
echo RUN_TIMEOUT_SECONDS;
Ожидаемый результат
300Вычисляется произведение, после чего читается значение правила. Скрипт от этого сам не остановится через 300 секунд: число ещё нужно передать инструменту, который ограничивает операцию.
Обычные значения констант — числа, строки, bool, null и массивы. Современный PHP допускает также объекты в определённых объявлениях; ниже показаны условия. Ресурс открытого файла не используйте как глобальное правило: у него меняющееся время жизни. Выбирайте const/define по происхождению значения, а не по обещанию микроскопического ускорения.
define: значение сначала получили, затем объявили
define — встроенная функция. Круглые скобки содержат аргументы: первый — строковое имя, второй — значение. Запятая их разделяет. Она подходит, когда настройка вычисляется во время работы.
<?php
$configuredPageSize = 15;
define('CONFIGURED_PAGE_SIZE', $configuredPageSize);
echo CONFIGURED_PAGE_SIZE;
Ожидаемый результат
15Имя в кавычках нужно для аргумента define; чтение результата опять записано без кавычек. Настройка здесь заведомо корректна. Внешний ввод сначала нужно проверить, поскольку define не знает допустимый размер страницы.
| Потребность | Подход |
|---|---|
| Правило буквально записано в исходнике | const NAME = значение; |
| Значение вычислено по данным | define('NAME', $checkedValue); |
| Два клиента требуют разных настроек одновременно | Массивы конфигурации или отдельные объекты. |
| Значение меняется по ходу сценария | Переменная. |
Зачем давать правилу отдельное имя
В каталоге и архиве нужно показывать одинаковое число карточек. Если написать 3 в двух местах, при изменении одного места страницы начнут вести себя по-разному. Назовём правило PAGE_SIZE и будем читать его в обоих расчётах. Константа — имя значения, которое после объявления нельзя переназначить в этом выполнении программы.
Результат главы: вы объявите правило, прочитаете его в функции и построите путь к файлу через __DIR__. Для следующей ступени понадобятся функции; первая программа выше уже работает без них.
Каждый пример запускается отдельно. Скачайте его архив, распакуйте целиком, откройте терминал в этом каталоге и выполните php example.php. Сравните вывод с блоком «Ожидаемый результат». Не объединяйте примеры в один файл: некоторые намеренно повторяют имена функций и классов.
Минимальная программа: два списка, одно правило
Здесь результат — нужное число страниц, которое затем можно использовать в навигации. При семи товарах и размере 3 страницы содержат 3, 3 и 1 товар. Вызов intdiv(9, 3) получает два целых аргумента и возвращает частное 3 без дроби; echo сразу печатает этот возврат. Прибавление размера минус один позволяет учесть неполную последнюю страницу: 7 + 3 − 1 = 9, затем 9 / 3 = 3. Для четырёх записей 4 + 3 − 1 = 6, затем 6 / 3 = 2. Это формула для неотрицательного количества и положительного размера.
<?php
declare(strict_types=1);
const PAGE_SIZE = 3;
$catalogCount = 7;
$archiveCount = 4;
echo 'Каталог: ', intdiv($catalogCount + PAGE_SIZE - 1, PAGE_SIZE), " страницы\n";
echo 'Архив: ', intdiv($archiveCount + PAGE_SIZE - 1, PAGE_SIZE), " страницы\n";
Ожидаемый результат
Каталог: 3 страницы
Архив: 2 страницы
Оба расчёта читают одно PAGE_SIZE. Число записей меняется, правило размера страницы — нет. intdiv делит целые числа без дробной части; прибавление PAGE_SIZE − 1 округляет число страниц вверх. Поменяйте PAGE_SIZE на 4: каталог даст 2, архив — 1. Здесь размеры известны и положительны.
От числа страниц к содержимому каждой страницы
Один расчёт числа страниц ещё не выбирает товары. Следующая ступень использует обычный массив и foreach: список хранит названия, array_chunk возвращает массив страниц, а каждый внутренний массив содержит не более PAGE_SIZE названий. Первый foreach получает номер и страницу, второй читает товары этой страницы. Нумерация массива начинается с 0, человеку показываем номер плюс один.
<?php
const PAGE_SIZE = 3;
$products = ['Чай', 'Кофе', 'Кружка', 'Тарелка', 'Ложка', 'Сахар', 'Мёд'];
$pages = array_chunk($products, PAGE_SIZE);
foreach ($pages as $index => $items) {
echo 'Страница ', $index + 1, ":\n";
foreach ($items as $title) {
echo '- ', $title, "\n";
}
}
Ожидаемый результат
Страница 1:
- Чай
- Кофе
- Кружка
Страница 2:
- Тарелка
- Ложка
- Сахар
Страница 3:
- Мёд
Array_chunk получает семь названий и размер 3; возвращает три вложенных списка. Внешний foreach последовательно получает items из трёх, трёх и одного названия. Каждый внутренний echo читает реальный товар. При PAGE_SIZE=4 получатся страницы из четырёх и трёх товаров. Пустой products даёт пустой pages: цикл ничего не выводит. Здесь весь список уже в памяти; большие выборки из базы обычно ограничивают на стороне запроса.
Параметры и сохранение исходных ключей подробно разобраны у array_chunk. Это вывод в терминал; HTML-ссылки и чтение выбранного номера страницы относятся к следующему веб-проекту.
const и define внутри реального сценария
Этот объединённый пример выполняйте после параметров и return и try/catch. Сначала инициализация выбирает формат; затем функция получает число строк и возвращает текстовый план. JSON здесь пока только название формата, декодирование или создание файла не используется.
const подходит для заранее записанного правила. В обычном файле его объявление не помещают внутрь if или функции. define — вызов функции; он может выполняться после условия и проверки полученной настройки. Имя передают строкой, вторым аргументом — значение. Для этого вводим ещё две записи: defined("ИМЯ") возвращает bool, а !defined(...) означает «ещё не объявлено».
<?php
declare(strict_types=1);
const EXPORT_PAGE_SIZE = 3;
// Учебное значение. В приложении настройку сначала читают и проверяют.
$configuredFormat = 'json';
if (!in_array($configuredFormat, ['json', 'csv'], true)) {
throw new InvalidArgumentException('Неподдерживаемый формат');
}
if (!defined('BRIDGE_EXPORT_FORMAT')) {
define('BRIDGE_EXPORT_FORMAT', $configuredFormat);
}
function exportPlan(int $itemCount): string
{
if ($itemCount < 0) {
throw new InvalidArgumentException('Отрицательное число записей');
}
$pages = intdiv($itemCount + EXPORT_PAGE_SIZE - 1, EXPORT_PAGE_SIZE);
return BRIDGE_EXPORT_FORMAT . ': ' . $pages . ' страниц';
}
echo exportPlan(7), "\n";
echo exportPlan(0), "\n";
try {
exportPlan(-1);
} catch (InvalidArgumentException) {
echo "Неверное количество отклонено\n";
}
Ожидаемый результат
json: 3 страниц
json: 0 страниц
Неверное количество отклонено
defined получает имя строкой и проверяет существование; define объявляет значение во время выполнения. Функция читает уже объявленные константы без global. Это только план: ни JSON-файл, ни сетевой запрос здесь не создаются. Проверка defined полезна для необязательной настройки, но не должна скрывать конфликт двух разных конфигураций.
Константа не обновляет настройки между HTTP-запросами и не заменяет хранилище. Если разным клиентам нужны разные лимиты, передайте лимит аргументом или настройкой объекта. Глобальная константа с одним значением не выразит два разных режима одновременно. Константы класса вида Product::TYPE разобраны рядом с классами.
Внутри namespace строки для define и defined не дополняются пространством имён автоматически. Для именованной константы передают полное строковое имя, например Bridge\Catalog\PAGE_SIZE. Псевдонимы use также не применяются к таким строкам.
| Место / вход | Действие и точный результат |
|---|---|
in_array($configuredFormat, ['json', 'csv'], true) | Получает строку json и разрешённый список; строгая проверка возвращает true. Отрицание ! даёт false, исключение не выбрасывается. |
defined('BRIDGE_EXPORT_FORMAT') | В самостоятельном файле имя ещё отсутствует: false. ! делает условие истинным, define объявляет json. |
exportPlan(7) | Локальный itemCount=7. Проверка отрицательного числа не срабатывает. intdiv(7+3−1,3) возвращает 3 в pages. Return возвращает строку json: 3 страниц прямо в echo. |
exportPlan(0) | Новый локальный itemCount=0; intdiv(2,3) даёт 0. Return возвращает json: 0 страниц; это план пустого набора. |
exportPlan(-1) | itemCount=-1; throw прерывает вызов, строки из return нет. Catch выбирает сообщение об отклонении. |
| Дальнейшее применение | Сохраните $message = exportPlan(7); затем echo $message. Для фактического разбиения списка выше показан array_chunk; текстовый план сам не экспортирует данные. |
Специальные имена: где находится этот код
PHP подставляет в специальные имена сведения о месте кода. __DIR__ — каталог исходника, __FILE__ — его полный путь, __LINE__ — строка, __FUNCTION__ — имя функции. Это не ваши настройки. Они не объявляются через define и не проверяются через defined.
Рядом со скачанным example.php лежит fixtures/stock.txt с числом 12. File_get_contents получает полный путь и возвращает содержимое строкой либо false при отказе. Trim удаляет завершающий перевод строки; basename оставляет только имя файла из полного пути. Эти функции обслуживают путь и вывод, а сведения о месте кода дают сами специальные имена.
<?php
function readStock(): string {
$path = __DIR__ . '/fixtures/stock.txt';
$body = file_get_contents($path);
if ($body === false) { throw new RuntimeException('Учебный файл недоступен'); }
return __FUNCTION__ . ': ' . trim($body);
}
echo readStock(), "\n";
echo 'Исходный файл: ', basename(__FILE__), "\n";
echo 'Метка строки: ', __LINE__, "\n";
Ожидаемый результат
readStock: 12
Исходный файл: example.php
Метка строки: 10
Вызов readStock() получает текст 12 из приложенного файла. __FUNCTION__ добавляет имя readStock, return передаёт готовую строку внешнему echo. __DIR__ привязывает путь к папке программы независимо от каталога запуска терминала. __FILE__ содержит полный путь; basename делает подпись переносимой. __LINE__ показывает настоящий номер строки в этом файле, а не проверку «номер больше нуля». При добавлении строк номер закономерно изменится; при переименовании example.php изменится имя. Файл запаса читается, но не изменяется.
__CLASS__, __METHOD__, __TRAIT__ и __NAMESPACE__ дают соответствующий контекст класса, метода, трейта и пространства имён. Не путайте __CLASS__ с классом объекта, который вызвал унаследованный метод: первый относится к месту объявления. __PROPERTY__ появился в PHP 8.4; ниже приведён отдельный пример с указанной версией.
Проверить наличие и обнаружить опечатку
В PHP 8 неизвестное имя не превращается в текст. Для необязательного правила defined проверяет существование по строковому имени. Возвращает bool: да/нет. if выбирает ветку, ! переворачивает ответ. Обязательную настройку проверяйте на старте и сообщайте об ошибке.
<?php
if (!defined('EXPORT_BATCH_SIZE')) {
define('EXPORT_BATCH_SIZE', 20);
}
echo EXPORT_BATCH_SIZE;
Ожидаемый результат
20Guard подходит для документированной возможности переопределения. При случайном конфликте двух файлов он скрывает проблему: останется значение первого. Для строгой конфигурации конфликт нужно обнаруживать.
Следующий пример использует try/catch и Error: try содержит чтение, catch перехватывает объект ошибки. Это наблюдение диагностики, а не привычный поиск настроек через исключения.
<?php
try {
echo UNKNOWN_DELIVERY_RULE;
} catch (Error $error) {
echo "Нет объявления константы\n";
}
Ожидаемый результат
Нет объявления константы
На старых PHP встречалось предупреждение и использование неизвестного имени как строки. В PHP 8 проверьте имя, порядок подключений и namespace.
Константа-массив и отдельный рабочий список
Форма экспорта предлагает поддержанные форматы. Массив объединяет значения; [0] читает первый элемент, [] = добавляет в конец изменяемого массива. Набор в константе менять нельзя, но можно получить рабочую копию.
<?php
const EXPORT_FORMATS = ['csv', 'json'];
$formatsForReport = EXPORT_FORMATS;
$formatsForReport[] = 'txt';
echo "Общее правило:\n";
foreach (EXPORT_FORMATS as $format) { echo '- ', $format, "\n"; }
echo "Этот отчёт:\n";
foreach ($formatsForReport as $format) { echo '- ', $format, "\n"; }
Ожидаемый результат
Общее правило:
- csv
- json
Этот отчёт:
- csv
- json
- txt
Присваивание копирует значение массива в formatsForReport. Запись [] добавляет txt в изменяемую копию. Два foreach показывают сами элементы: исходное правило по-прежнему csv/json, рабочий список csv/json/txt. Это ещё перечень разрешённых названий, а не реализация кодирования этих форматов. Запись EXPORT_FORMATS[] = ... запрещена. Если массив содержит объекты, их внутреннее состояние требует отдельного разбора: копирование массива не клонирует объекты.
Чтение в функции без global
Функция читает уже объявленное глобальное правило напрямую. Константа не становится её локальной переменной и не требует global. define внутри функции тоже не создаёт локальную переменную: объявленное имя остаётся доступным после вызова. Различие подробно разобрано в области видимости.
Скобки у twoBoxes() пустые: новых аргументов нет. : int объявляет целочисленный результат. Ниже на складе берут две полные коробки по шесть предметов, резервируют пять и печатают остаток.
<?php
const ITEMS_PER_BOX = 6;
function twoBoxes(): int {
return ITEMS_PER_BOX * 2;
}
$available = twoBoxes();
$reserved = 5;
$remaining = $available - $reserved;
echo 'В двух коробках: ', $available, "\n";
echo 'Зарезервировано: ', $reserved, "\n";
echo 'Осталось: ', $remaining, "\n";
Ожидаемый результат
В двух коробках: 12
Зарезервировано: 5
Осталось: 7
Вызов справа от = входит в twoBoxes. Тело читает ITEMS_PER_BOX=6, умножает на 2 и возвращает 12 точно в выражение twoBoxes(). Присваивание сохраняет 12 в available; следующая арифметика использует его для 12−5=7. Return сам ничего не печатает. Global для чтения константы не нужен. Если на двух складах разная вместимость, передайте её параметром вместо одного общего имени.
<?php
function registerExportLimit(): void
{
define('FUNCTION_EXPORT_LIMIT', 25);
}
registerExportLimit();
echo FUNCTION_EXPORT_LIMIT;
Ожидаемый результат
25До вызова имени ещё нет. Повторный вызов попытался бы объявить его снова: предупреждение, старое значение останется. void означает отсутствие полезного возвращаемого значения. Такой шаблон не подходит для разных параметров каждого заказа.
Полное имя и namespace
Каталог и доставка могут иметь разные LIMIT благодаря пространствам имён. namespace задаёт префикс обычных объявлений файла. const получает его автоматически; define получает готовую строку. Текущий namespace и use-псевдонимы к этой строке сами не добавляются.
<?php
namespace Lesson\Catalog;
const PAGE_LIMIT = 12;
define('OUTSIDE_LIMIT', 4);
define(__NAMESPACE__ . '\\DYNAMIC_LIMIT', 8);
echo PAGE_LIMIT, "\n";
echo \OUTSIDE_LIMIT, "\n";
echo constant('Lesson\\Catalog\\DYNAMIC_LIMIT'), "\n";
Ожидаемый результат
12
4
8
__NAMESPACE__ даёт префикс, точка соединяет строки. OUTSIDE_LIMIT объявлен глобально. Для define передавайте полное имя без ведущего обратного слеша. constant читает значение по готовому строковому имени.
Обычное неполное имя константы внутри namespace сначала ищется в нём, затем может использовать глобальное имя. К классам это правило не относится. Для однозначности применяйте полный путь или use const.
<?php
require __DIR__ . '/rules.php';
echo \Lesson\Shipping\MAX_PARCELS;
Ожидаемый результат
3require выполняет приложенный rules.php, namespace только организует имена. Обычная автозагрузка классов сама не загружает свободные константы и функции. В Composer их файлы можно явно перечислить в autoload.files; классам подходит PSR-4.
Два модуля строят свои пути без конфликта имён
Реальная проблема из вопроса о define внутри namespace: два раздела хотят одинаковое короткое имя, но разные значения. Сначала ниже обычный const автоматически получает пространство. Во втором модуле define получает полное имя строкой. Это самостоятельный файл; фигурные скобки отделяют пространства, а завершающий namespace без имени — глобальный участок.
<?php
namespace Shop\Catalog {
const BASE_PATH = '/catalog/';
const OFFERS_PATH = BASE_PATH . 'offers/';
}
namespace Shop\Delivery {
define(__NAMESPACE__ . '\\BASE_PATH', '/delivery/');
define(__NAMESPACE__ . '\\OFFERS_PATH', BASE_PATH . 'offers/');
}
namespace {
echo 'Каталог: ', \Shop\Catalog\OFFERS_PATH, "\n";
echo 'Доставка: ', constant('Shop\\Delivery\\OFFERS_PATH'), "\n";
}
Ожидаемый результат
Каталог: /catalog/offers/
Доставка: /delivery/offers/
В Catalog константное выражение складывает две строки точкой; результат /catalog/offers/. В Delivery __NAMESPACE__ даёт Shop\Delivery, добавление \BASE_PATH формирует имя для define. Следующий вызов читает собственный BASE_PATH и строит /delivery/offers/. В глобальном коде прямое полное имя и constant по строке получают готовые значения. Эти пути ещё не создают страницы сайта. Пространство не добавляется к строкам define автоматически; без префикса возникли бы общие глобальные имена.
Сравнение const/define из отдельного обсуждения следует проверять по текущему Manual: старые ответы описывают ограничения версий PHP 5. Простые строковые и арифметические константные выражения не требуют замены const на define. Если значение получено из переменной после загрузки конфигурации, используйте define или передайте его обычным параметром.
Имена, уже определённые PHP
PHP_VERSION_ID описывает версию числом, PHP_OS_FAMILY — семейство ОС, PHP_INT_SIZE — размер целого в байтах. Другие константы предоставляют расширения. Не запоминайте случайное числовое значение флага: используйте его документированное имя.
Предопределённое имя полезно, когда от него зависит следующий шаг. Ниже проверяется допустимость прибавления к целому: вместо потенциально переполняющего сложения сначала сравниваем прибавляемое число с оставшимся запасом до PHP_INT_MAX. Оба входа — уже проверенные неотрицательные int.
<?php
$preparedBytes = 2000000000;
$nextBatchBytes = 100000000;
if ($nextBatchBytes > PHP_INT_MAX - $preparedBytes) {
echo "Размер не помещается в целое этой сборки PHP\n";
} else {
$totalBytes = $preparedBytes + $nextBatchBytes;
echo 'После партии: ', $totalBytes, ' байт', "\n";
}
if (PHP_VERSION_ID >= 80200) {
echo "Можно запустить утилиту для PHP 8.2+\n";
}
Ожидаемый результат
После партии: 2100000000 байт
Можно запустить утилиту для PHP 8.2+
PHP_INT_MAX даёт верхнюю границу int именно этой сборки. Ветвь else получает суммарные 2100000000 байт и печатает их; выбранное число помещается и в 32-, и в 64-битный int. Если прибавление не помещается, сложение не выполняется. 80200 обозначает 8.2.0: проверка версии разрешает сообщение о минимальном требовании, но не проверяет срок поддержки или расширения. Эти имена уже предоставляет PHP, объявлять их самостоятельно не нужно. Для отрицательных входов или уже полученного float эта проверка не является готовым универсальным алгоритмом.
Проверка версии внутри файла не спасает от неподдерживаемого синтаксиса в том же файле: сначала PHP должен его разобрать. Новый файл подключайте после проверки в совместимом загрузчике. Полный перечень специфических имён находится в соответствующих категориях расширений.
Специальные имена показывают место исходного кода
| Запись | Что обозначает |
|---|---|
| __LINE__ | Номер строки в месте записи. |
| __FILE__ | Полное имя текущего файла с разрешёнными символическими ссылками. |
| __DIR__ | Каталог этого файла. |
| __FUNCTION__ | Имя функции с namespace; в методе — имя метода. |
| __CLASS__ | Класс объявления; в трейте — использующий его класс. |
| __TRAIT__ | Имя трейта с namespace. |
| __METHOD__ | Имя метода с классом/трейтом. |
| __NAMESPACE__ | Текущее пространство имён, в глобальном — пустая строка. |
| __PROPERTY__ (8.4+) | Имя свойства в его hook. |
| ИмяКласса::class | Отдельная конструкция: разрешённое строковое имя класса. |
Магические имена нечувствительны к регистру. Это не записи обычной таблицы констант: их не читают через constant и не проверяют defined. Контекст зависит от места записи. Для анонимных функций с PHP 8.4 сгенерированное имя содержит привязку к файлу и строке: это не устойчивый идентификатор между правками программы. Для абсолютных путей заранее определите, кому доступна диагностика; посетителю сайта путь к исходнику обычно не нужен.
<?php
class BaseReport
{
public static function identify(): void
{
echo __CLASS__, "\n";
echo __METHOD__, "\n";
echo static::class, "\n";
}
}
class StockReport extends BaseReport {}
StockReport::identify();
Ожидаемый результат
BaseReport
BaseReport::identify
StockReport
Это пример после главы наследования: extends создаёт потомка, :: вызывает статический метод. __CLASS__/__METHOD__ описали исходное объявление, static::class — вызвавший класс. Так в журнале различают «где написан код» и «от чьего имени он работает».
<?php
namespace Lesson;
trait DescribeContext
{
public function describe(): void
{
echo __TRAIT__, "\n";
echo __CLASS__, "\n";
echo __METHOD__, "\n";
echo __FUNCTION__, "\n";
echo __NAMESPACE__, "\n";
}
}
class DeliveryClient { use DescribeContext; }
(new DeliveryClient())->describe();
Ожидаемый результат
Lesson\DescribeContext
Lesson\DeliveryClient
Lesson\DescribeContext::describe
describe
Lesson
use внутри класса подключает трейт, а не импортирует namespace. Подписи различают источник метода и получивший его класс. Они не доказывают, что доставка или запрос прошли успешно: для этого нужен результат операции.
<?php
class Parcel
{
public int $weight {
set {
echo __PROPERTY__, "\n";
$this->weight = $value;
}
}
}
$parcel = new Parcel();
$parcel->weight = 1200;
echo $parcel->weight;
Ожидаемый результат
weight
1200Нужна глава свойств и property hooks: set перехватывает запись, value содержит новое значение. __PROPERTY__ обозначает weight. Здесь демонстрируется контекст, а не законченная модель посылки: единицы и допустимые значения проверяются отдельно. Синтаксис требует PHP 8.4+.
Вне подходящего контекста __CLASS__, __TRAIT__, __FUNCTION__, __METHOD__, __NAMESPACE__ и __PROPERTY__ дают пустую строку. __DIR__ не имеет завершающего разделителя, кроме корня; добавляем / сами. Вне метода __METHOD__ совпадает с __FUNCTION__. Имена анонимных классов, как и замыканий, генерирует движок; не делайте их устойчивыми ключами хранилища.
Константа с объектом не даёт глубокой неизменяемости
С PHP 8.1 объект может быть значением глобальной константы; const с new допустим в соответствующем глобальном контексте. Это не разрешение new в любом значении свойства или константе класса. Сначала изучите объекты: new создаёт объект, стрелка обращается к свойству.
<?php
class DeliveryRule
{
public int $limit = 3;
}
const DELIVERY_RULE = new DeliveryRule();
$rule = DELIVERY_RULE;
$rule->limit = 4;
echo DELIVERY_RULE->limit;
Ожидаемый результат
4rule указывает на тот же объект. Константу не переназначали, но свойство изменили. Для фиксированного числа проще скаляр; для объекта нужны продуманные правила изменения и доступа. clone создаёт другой объект с отдельными ограничениями глубины копии.
Общий клиент с токеном в константе усложняет разные настройки двух интеграций и тесты. Явная передача настроенного объекта показывает зависимость — композиция и внедрение зависимостей.
PHP 8.5: приведения, Closure и first-class callable
Следующие файлы требуют PHP 8.5+. Приведения теперь допустимы в константных выражениях. Для Closure разрешена форма static function без захвата внешних переменных через use; fn здесь не заменяет её. Создание вызываемого значения не запускает тело функции.
<?php
const RETRY_STEPS = (int) 3.8;
echo RETRY_STEPS;
Ожидаемый результат
3Дробная часть отброшена. Обычно проще сразу записать целое 3; пример показывает допустимый синтаксис для чтения библиотек, а не проверку пользовательского ввода.
<?php
const LABEL_FORMATTER = static function (string $label): string {
return '[' . $label . ']';
};
$format = LABEL_FORMATTER;
echo $format('SKU-17');
Ожидаемый результат
[SKU-17]Константа хранит Closure. Присваивание даёт это значение format. Скобки после $format запускают функцию: аргумент становится label, return возвращает [SKU-17] в место вызова, echo выводит результат.
<?php
const LABEL_LENGTH = strlen(...);
$measure = LABEL_LENGTH;
echo $measure('SKU-17');
Ожидаемый результат
6Три точки создают first-class callable; strlen ещё не вызывается. Запуск происходит через $measure. strlen считает байты, поэтому для кириллицы метрику выбирают отдельно.
PHP 8.5 также разрешает атрибуты у глобальных const. Это метаданные объявления; define не становится объявлением с атрибутом. Применение и получение через Reflection разобраны в главе атрибутов.
Выбрать инструмент по задаче
| Задача | Переход |
|---|---|
| Объявить вычисленное правило | define |
| Проверить существование | defined |
| Прочитать значение по строке имени | constant |
| Исследовать таблицу для диагностики | get_defined_constants |
| Индивидуальные настройки двух клиентов | Передать два настроенных объекта |
| Имена разных библиотек конфликтуют | Пространства имён |
Попробуйте. У двух служб доставки лимиты 3 и 7 мест. Достаточно общей MAX_PARCELS?
Разбор
Нет: одно глобальное число не выражает два одновременно действующих ограничения. Передавайте лимит в функцию или храните в двух объектах настроек. Неизменность правила внутри расчёта не требует одной глобальной константы.
Для одного имени используйте defined: получение всей таблицы ради проверки создаёт лишний массив. Измеряйте время целой операции — обращение к API и обход большого набора обычно важнее микроразницы const/define.
Проверьте выбор: правило или изменяемые данные
- Не вызывайте define второй раз для изменения настройки; создайте отдельную переменную или объект настроек.
- Не записывайте секреты в публичный репозиторий только потому, что назвали их константами.
- Не прячьте неограниченное число настроек за defined: обязательную ошибку конфигурации лучше обнаружить явно.
Попробуйте сами. Показываем по 4 товара. Для 9 товаров ожидается 3 страницы, для пустого списка — 0. Что поменять в первом примере и где хранить текущий номер страницы?
Разбор и проверка
Замените значение PAGE_SIZE на 4, количество каталога — на 9. Текущая страница меняется от запроса к запросу, поэтому это проверенная переменная, а не ещё одна константа. Для нуля формула даёт 0; отрицательные значения отклоняет функция из второго примера.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
defineОбъявить константу во время выполнения по строковому имени и уже проверенному значению.
PHP 4+; object value — PHP 8.1+ · standard
define(string $constant_name, mixed $value, bool $case_insensitive = false): boolОбъявить константу во время выполнения по строковому имени и уже проверенному значению.
Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.
Что произойдёт при вызове
- Получить настройку
- Проверить тип и диапазон
- define регистрирует значение один раз
- Код читает константу по имени
Первый запуск и развитие задачи
Если значение меняется или два клиента одновременно имеют разные настройки, используйте переменные/объекты конфигурации. Для буквального значения в исходнике обычно яснее const.
Полный договор вызова
| Часть вызова | Полный договор |
|---|---|
| constant_name | Обычная строка. Для namespaced-константы передайте полное имя без начального обратного слеша. Зарезервированные/невалидные имена технически возможны, но читать их можно только через constant и создавать их не рекомендуется. |
| value | Значение; объект разрешён с PHP 8.1. Ресурс технически допустим, но Manual предупреждает о непредсказуемом поведении. |
| case_insensitive | Оставляйте false. true deprecated с 7.3 и с 8.0 даёт E_WARNING; регистронезависимые пользовательские константы больше не поддерживаются. |
| Возврат | true при объявлении, false при отказе. Это статус, а не объявленное значение. |
Ошибки и границы. Повторное имя вызывает диагностику и не заменяет прежнее значение. Внешний ввод сначала валидируется: define не знает предметных ограничений.
Версии и платформа. PHP 8 принимает только false для case_insensitive; ведущий обратный слеш в строковом имени не нормализуется.
Нужна, когда именованное правило вычисляется во время выполнения. Например, настройки прочитаны и проверены до регистрации общего размера пакета импорта. Если значение буквально записано в исходнике, const обычно проще.
| Параметр / результат | Смысл |
|---|---|
| constant_name: string | Имя константы; строка не получает текущий namespace или use-псевдонимы автоматически. |
| value: mixed | Объявляемое значение. Массивы поддерживаются с PHP 7, объекты — с 8.1. Ресурсы не используйте как постоянную конфигурацию. |
| case_insensitive: bool = false | Оставьте false. В PHP 8 регистронезависимые пользовательские константы не поддерживаются; true вызывает предупреждение. |
| Возврат: bool | Успех объявления, а не объявленное значение. При повторном имени — предупреждение и false; прежнее значение остаётся. |
Сначала отделим статус от значения. Define получает два аргумента: строку имени и число 10. Его bool-возврат попадёт в created и управляет сообщением; объявленное число читается по имени MANUAL_PAGE_SIZE и участвует в расчёте свободных мест.
<?php
$created = define('MANUAL_PAGE_SIZE', 10);
if ($created) { echo "Размер страницы установлен\n"; }
$shown = 7;
$free = MANUAL_PAGE_SIZE - $shown;
echo 'Показано: ', $shown, ' из ', MANUAL_PAGE_SIZE, "\n";
echo 'Свободных мест: ', $free, "\n";
Ожидаемый результат
Размер страницы установлен
Показано: 7 из 10
Свободных мест: 3
Define возвращает true, поэтому if печатает первую строку. MANUAL_PAGE_SIZE содержит 10, а не true. Вычитание 10−7 даёт 3 в free; оба числа используются в отчёте. Если написать $pageSize=define(...), в pageSize окажется bool: он не заменит числовое правило. Повторное объявление имени вызывает предупреждение и возвращает false; прежнее значение сохраняется.
Дальше используем массив настроек, проверку типа is_int и if. Знак || означает «или», ! — отрицание. throw прекращает неподходящую инициализацию через исключение: это уже стадия после глав условий и исключений.
<?php
$settings = ['batchSize' => 2];
$batchSize = $settings['batchSize'];
if (!is_int($batchSize) || $batchSize < 1 || $batchSize > 100) {
throw new InvalidArgumentException('Размер должен быть от 1 до 100');
}
define('MANUAL_BATCH_SIZE', $batchSize);
$jobs = ['SKU-10', 'SKU-20', 'SKU-30', 'SKU-40', 'SKU-50'];
$batches = array_chunk($jobs, MANUAL_BATCH_SIZE);
foreach ($batches as $index => $batch) {
echo 'Пакет ', $index + 1, ': ', implode(', ', $batch), "\n";
}
Ожидаемый результат
Пакет 1: SKU-10, SKU-20
Пакет 2: SKU-30, SKU-40
Пакет 3: SKU-50
Settings имитирует уже прочитанную конфигурацию. Is_int принимает целое 2, диапазон 1..100 допускает его. Define регистрирует 2; array_chunk возвращает три массива по два, два и одному артикулу. Implode получает разделитель и очередной массив, возвращает текст артикулов в echo. Это план пакетов, отправки во внешнюю систему нет. При batchSize=3 будут пакеты SKU-10/20/30 и SKU-40/50; при 0, 101 или строке "2" проверка прервёт инициализацию до define. Диапазон — правило этого импортёра, не ограничение define.
Не переопределяйте имя для каждого нового заказа. Различающиеся настройки храните в аргументах или объектах. Нельзя создать константу класса вызовом define. Для namespaced-константы задавайте полное строковое имя без начального обратного слеша. Объектное значение не становится глубоко неизменяемым. Встроенная функция не шифрует секрет, если передать токен как value.
Сначала: объявление и чтение константы. Рядом: defined, constant, get_defined_constants.
Полный контракт допускает необычные или зарезервированные строковые имена, которые можно читать только через constant; для нового кода выбирайте обычные идентификаторы. В отличие от constant/defined функция define не удаляет ведущий обратный слеш: имя вида \App\LIMIT может успешно зарегистрироваться, но обычное чтение его не найдёт. Передавайте App\LIMIT. Ресурс технически может быть значением, но официальный Manual предупреждает о непредсказуемых результатах; используйте явную переменную времени жизни ресурса.
definedПроверить, существует ли константа, не пытаясь читать отсутствующее имя.
PHP 4+ · standard
defined(string $constant_name): boolПроверить, существует ли константа, не пытаясь читать отсутствующее имя.
Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.
Что произойдёт при вызове
- Есть строка имени
- defined отвечает только о наличии
- При true — constant читает значение
- При false — явная запасная политика
Первый запуск и развитие задачи
Обязательную конфигурацию не стоит молча подменять запасным значением: сообщите об ошибке запуска. Для одной константы не выгружайте всю таблицу get_defined_constants.
Полный договор вызова
| Часть вызова | Полный договор |
|---|---|
| constant_name | Строковое полное имя глобальной/namespaced/class-константы или enum-case. Namespace и use к строке автоматически не добавляются. |
| Возврат | true, если доступное имя объявлено, иначе false. Значение false или null всё равно считается объявленным. |
| Не проверяет | Переменные проверяет isset/array_key_exists, функции — function_exists. |
Ошибки и границы. false сообщает отсутствие; это не исключение и не оценка истинности самого значения.
Версии и платформа. Работает с константами классов и enum-case при соблюдении загрузки и видимости.
Проверяет существование константы до чтения. Это удобно для необязательной настройки старого модуля. Наличие объявления и смысл значения — разные вопросы: false или null могут быть корректно объявленными значениями.
| Часть контракта | Что означает |
|---|---|
| constant_name: string | Строковое имя глобальной, namespaced или доступной константы класса; поддерживаются и имена enum-case. |
| bool | true — имя найдено, false — нет доступного объявления. Это не проверка переменной или функции. |
| Строковые имена | Не переписываются use-псевдонимами; используйте полное имя. Для динамического имени класса важны загрузка и правила доступа. |
<?php
const MANUAL_SIGNATURE = null;
if (defined('MANUAL_SIGNATURE')) {
$signature = MANUAL_SIGNATURE;
echo 'Настройка найдена: ', $signature ?? 'подпись отключена', "\n";
} else {
echo "Настройки нет: используется подпись магазина\n";
}
if (!defined('MANUAL_FOOTER')) {
echo "Нижний текст не настроен\n";
}
Ожидаемый результат
Настройка найдена: подпись отключена
Нижний текст не настроен
Defined возвращает true для существующего MANUAL_SIGNATURE даже при значении null. Поэтому читается настройка и ?? выбирает пояснение отключения. Для MANUAL_FOOTER объявления нет: defined возвращает false, ! разрешает второе сообщение. Здесь null — наше соглашение «подпись отключена». Если удалить первое объявление, выполнится другая ветка с подписью магазина. Это отличается от isset для переменных, где null даёт false.
В следующем примере оператор ? : выбирает один из двух результатов: после ? — при наличии имени, после : — при отсутствии. constant читает уже проверенное имя. В применении ниже str_pad возвращает строку заданной ширины; её параметры и байтовое ограничение объяснены после кода.
<?php
const MANUAL_LABEL_WIDTH = 12;
$width = defined('MANUAL_LABEL_WIDTH') ? constant('MANUAL_LABEL_WIDTH') : 8;
$sku = 'SKU-7';
$label = str_pad($sku, $width, '.', STR_PAD_RIGHT);
echo '|', $label, '|', "\n";
Ожидаемый результат
|SKU-7.......|
Defined находит имя: условие выбирает constant(...), который возвращает int 12 в width. Str_pad получает текст из пяти ASCII-байтов, ширину 12, заполнитель "." и направление справа; возвращает SKU-7 с семью точками в label. Echo ставит видимые границы. Без объявления width стал бы 8 и добавились бы три точки. Это ширина в байтах, не экранных колонках для произвольного Unicode. Обязательную настройку нельзя молча заменять этим запасным правилом.
Передавайте имя строкой: попытка сначала вычислить неизвестную константу вызовет Error до самой проверки. Наличие имени не означает доступность сервера, корректность токена или включённость функции приложения. Для одного имени defined проще и дешевле по объёму создаваемых данных, чем выгрузка всей таблицы констант.
Сначала: объявление и чтение константы. Рядом: define, constant, get_defined_constants.
constantПолучить значение уже объявленной константы, когда её имя хранится в строке.
PHP 4.0.4+; Error для отсутствующего имени — PHP 8.0+ · standard
constant(string $name): mixedПолучить значение уже объявленной константы, когда её имя хранится в строке.
Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.
Что произойдёт при вызове
- Получить или составить разрешённое имя
- Проверить optional-имя через defined
- constant находит объявление
- Использовать значение с его исходным типом
Первый запуск и развитие задачи
Прямое LIMIT проще, когда имя известно в исходнике. Динамическое имя полезно для совместимости с таблицей профилей; не позволяйте посетителю читать произвольные внутренние константы.
Полный договор вызова
| Часть вызова | Полный договор |
|---|---|
| name | Полное строковое имя. Текущий namespace, namespace\ и use-псевдонимы к строке не применяются. Namespace-часть регистронезависима, конечное имя константы — нет. |
| Возврат | Исходное значение любого допустимого типа; также работают доступные константы классов и enum-case. |
| Отсутствующее имя | С PHP 8 выбрасывается Error; до 8.0 было E_WARNING и null. Для необязательного имени сначала defined. |
Ошибки и границы. Неизвестное имя — Error. Наличие имени не подтверждает корректность или безопасность его значения.
Версии и платформа. Строковое имя не получает namespace автоматически; это существенная граница, а не только синтаксическая деталь.
Получает значение, когда имя известно только как текст. Например, старый модуль связывает выбранный профиль с названием одной из известных констант. Если имя буквально известно в коде, прямое обращение проще.
| Часть контракта | Что означает |
|---|---|
| name: string | Полное строковое имя. Конечное имя пользовательской константы чувствительно к регистру; часть namespace в таком строковом имени регистронезависима. Сохраняйте единое написание для читаемости. |
| mixed | Значение найденной константы с его исходным типом. Это не обязательно строка. |
| Неизвестное имя | В PHP 8 выбрасывается Error. Для необязательных имён сначала defined; старое поведение с предупреждением и null не является текущим контрактом. |
| ClassName::CONSTANT / EnumName::Case | Допустимые формы при соблюдении загрузки и доступа. use не меняет строку автоматически. |
<?php
const MANUAL_MAX_ROWS = 30;
$name = 'MANUAL_MAX_ROWS';
$limit = constant($name);
$prepared = 12;
echo 'Правило: ', $name, "\n";
echo 'Готово строк: ', $prepared, ' из ', $limit, "\n";
echo 'Можно добавить: ', $limit - $prepared, "\n";
Ожидаемый результат
Правило: MANUAL_MAX_ROWS
Готово строк: 12 из 30
Можно добавить: 18
Name хранит буквы MANUAL_MAX_ROWS. Constant получает эту строку, находит объявление и возвращает целое 30 в limit. Обычный echo name печатает название; вычитание использует возвращённое число 30−12=18. Это не вызов функции по имени и не чтение переменной со знаком $. Если название постоянно известно автору, присваивание limit = MANUAL_MAX_ROWS проще.
Для выбора из внешнего запроса создайте разрешённое отображение: ключ массива — короткое название профиля, значение — допустимое имя. isset проверяет, что такой элемент есть и не равен null; после этого разрешаем чтение.
<?php
const MANUAL_SMALL_BATCH = 2;
const MANUAL_LARGE_BATCH = 4;
$profiles = ['small' => 'MANUAL_SMALL_BATCH', 'large' => 'MANUAL_LARGE_BATCH'];
$requested = 'small';
if (!isset($profiles[$requested])) {
throw new InvalidArgumentException('Неизвестный профиль');
}
$constantName = $profiles[$requested];
$size = constant($constantName);
$parts = array_chunk(['TEA', 'COFFEE', 'CUP'], $size);
foreach ($parts as $index => $items) {
echo 'Группа ', $index + 1, ': ', implode(', ', $items), "\n";
}
Ожидаемый результат
Группа 1: TEA, COFFEE
Группа 2: CUP
Вход small выбирает строку MANUAL_SMALL_BATCH из разрешённого отображения. Constant возвращает её значение 2 в size. Array_chunk создаёт [TEA,COFFEE] и [CUP], foreach показывает обе группы. При large размер 4 поместит все три артикула в одну группу. Unknown будет отклонён до чтения константы. В новом модуле часто проще хранить сами числа в profiles; строковые имена полезны для совместимости с существующим договором конфигурации.
Магические имена __DIR__/__FILE__ так не читаются: пишите их непосредственно в месте кода. Не принимайте от посетителя произвольное имя без ограничения выбора — внутренние константы могут содержать конфиденциальные настройки.
Сначала: объявление и чтение константы. Рядом: define, defined, get_defined_constants.
get_defined_constantsПолучить константы текущего процесса одним списком или по группам расширений.
Есть в проверенном PHP 8.5.11 · Core
get_defined_constants(bool $categorize = false): arrayПолучить константы текущего процесса одним списком или по группам расширений.
Без аргумента результат — name=>value. categorize=true группирует системные константы по расширению, а объявленные приложением помещает в user. Magic constants вроде __FILE__ в список не входят: они разрешаются компилятором в зависимости от места кода. Это инструмент исследования и закрытой диагностики; постоянный код обычно обращается к известной константе через defined/constant.
Первый запуск и развитие задачи
<?php
declare(strict_types=1);
define('SHOP_DEFAULT_CURRENCY', 'RUB');
$groups = get_defined_constants(true);
echo $groups['user']['SHOP_DEFAULT_CURRENCY'], "\n";
echo isset($groups['Core']['PHP_VERSION']) ? "ядро отдельно\n" : "нет Core\n";
Ожидаемый результат
RUB
ядро отдельно
Аргумент true группирует значения по расширениям и выделяет user. Полный системный список велик; в обычной диагностике выводите только нужные имена.
<?php
declare(strict_types=1);
$coreReady = extension_loaded('Core');
$constants = get_defined_constants(false);
$ordinary = get_loaded_extensions(false);
$zend = get_loaded_extensions(true);
ob_start();
$creditsOk = phpcredits(CREDITS_QA);
ob_end_clean();
ob_start();
$infoOk = phpinfo(INFO_MODULES);
ob_end_clean();
$engine = zend_version();
$capabilitiesOk = $coreReady && isset($constants['PHP_VERSION'])
&& in_array('Core', $ordinary, true) && is_array($zend);
$reportsOk = $creditsOk === true && $infoOk === true && $engine !== '';
echo $capabilitiesOk ? "возможности подтверждены\n" : "неполная среда\n";
echo $reportsOk ? "локальные отчёты сформированы и отброшены\n" : "ошибка отчёта\n";
Ожидаемый результат
возможности подтверждены
локальные отчёты сформированы и отброшены
Пример отличается от полного inventory: код проверяет конкретные факты, phpcredits/phpinfo удерживает в локальном буфере и удаляет, а наружу отдаёт только две безопасные фразы.
Полный договор вызова
| Параметр | Что передаём и зачем |
|---|---|
| categorize | false — плоский массив; true — группы расширений и user. |
| Часть договора | Что получает программа |
|---|---|
| Сигнатура | get_defined_constants(bool $categorize = false): array |
| Результат | array. |
| Ошибки и особые значения | Массив велик и может меняться с составом расширений. Не сериализуйте его как стабильный внешний контракт и не печатайте целиком публично. |
| Версии | Есть в проверенном PHP 8.5.11 Официальный диапазон узла: (PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8). |
| Среда | Все SAPI, если ниже не указано иное. |
Более простой или безопасный выбор. Проверяйте одну возможность через defined("NAME") и объясняйте fallback.
Рядом: extension_loaded, get_loaded_extensions, phpinfo.
Вернуться к карте задач или полному дереву функций.
Сначала увидим форму плоского результата, затем готовый диагностический отчёт из двух выбранных имён. Возвращённая таблица — массив, а не текст для автоматической публикации. $constants['MANUAL_EXPORT_LIMIT'] читает значение по ключу; вариант true добавляет ещё один уровень группировки.
Полезна при создании локальной диагностической утилиты: показывает имена, объявленные в текущем процессе. Не является полным списком всего, что может существовать в другой сборке PHP.
| Параметр / результат | Смысл |
|---|---|
| categorize: bool = false | false — плоский массив имя → значение; true — группы по расширениям. Пользовательские объявления попадают в user. |
| array | Снимок текущей таблицы; состав зависит от версии, расширений и уже выполненных объявлений. |
| Что не входит | Магические константы и константы классов. Для класса применяют ReflectionClass. |
<?php
const MANUAL_EXPORT_LIMIT = 40;
$constants = get_defined_constants();
echo $constants['MANUAL_EXPORT_LIMIT'];
Ожидаемый результат
40Ключ массива — строка имени. Это знакомство с формой результата; получать всю таблицу ради единственного известного числа в обычной программе не требуется.
В сгруппированном варианте сначала берём user. Оператор ?? [] даёт пустой массив, если группа отсутствует. foreach далее проходит только явно разрешённый список имён, а не все внутренние настройки.
<?php
const MANUAL_PUBLIC_PAGE_SIZE = 20;
const MANUAL_PUBLIC_FORMAT = 'csv';
$groups = get_defined_constants(true);
$userConstants = $groups['user'] ?? [];
foreach (['MANUAL_PUBLIC_PAGE_SIZE', 'MANUAL_PUBLIC_FORMAT'] as $name) {
echo $name, '=', $userConstants[$name], "\n";
}
Ожидаемый результат
MANUAL_PUBLIC_PAGE_SIZE=20
MANUAL_PUBLIC_FORMAT=csv
Обе константы объявлены в этом самостоятельном примере. В реальной диагностике учитывайте отсутствие ожидаемого имени и не выводите всю группу публично: в ней могут находиться ключи интеграций.
Функция строит массив; не вызывайте её заново для каждой строки большого импорта. Для наличия одного имени подходит defined. Не делайте вывод о работоспособности сервиса по наличию его константы. Количество записей не фиксировано и не подходит для переносимого теста.
Сначала: объявление и чтение константы. Рядом: define, defined, constant.
Источники и обсуждения
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


