Сегодня поисследуем использование пространств имен (они же неймспейсы) для объявления констант и обращения к ним.
Как сказано в мануале:
классы (включая абстрактные и трейты), интерфейсы, функции и константы зависят от пространства имен.
То есть, если зарегистрировать константы с одинаковыми именами в нескольких неймспейсах, в том числе и глобальном, то за это ничего не будет, и обращение к каждой из констант будет работать без ошибок.
Проверим:
namespace FirstNs {
const SUPER_VALUE = 'NS-1';
}
namespace SecondNs {
const SUPER_VALUE = 'NS-2';
}
namespace {
const SUPER_VALUE = 'NS-GLOBAL';
var_dump(
SUPER_VALUE,
FirstNs\SUPER_VALUE,
SecondNs\SUPER_VALUE,
);
}
// Вывод:
// string(9) "NS-GLOBAL"
// string(4) "NS-1"
// string(4) "NS-2"
Ровно то, что нужно.
Но что если мы хотим определить константы методом define
.
Не проблема, пробуем написать так:
namespace FirstNs {
define('SUPER_VALUE', 'NS-1');
}
namespace SecondNs {
define('SUPER_VALUE', 'NS-2');
}
namespace {
define('SUPER_VALUE', 'NS-GLOBAL');
var_dump(
SUPER_VALUE,
FirstNs\SUPER_VALUE,
SecondNs\SUPER_VALUE,
);
}
Запускаем и видим:
Warning: Constant SUPER_VALUE already defined in ...
Warning: Constant SUPER_VALUE already defined in ...
Fatal error: Uncaught Error: Undefined constant "FirstNs\SUPER_VALUE" in ...
Судя по всему, мы пытаемся три раза определить одну и ту же константу в глобальном неймспейсе. Что же делать?
А просто указать нужный неймспейс при определении константы, благо php это позволяет:
namespace FirstNs {
define('FirstNs\\SUPER_VALUE', 'NS-1');
// или
define(__NAMESPACE__ . '\\SUPER_VALUE', 'NS-1');
}
namespace SecondNs {
define('SecondNs\\SUPER_VALUE', 'NS-2');
}
namespace {
define('SUPER_VALUE', 'NS-GLOBAL');
var_dump(
SUPER_VALUE,
FirstNs\SUPER_VALUE,
SecondNs\SUPER_VALUE,
);
}
// Вывод:
// string(9) "NS-GLOBAL"
// string(4) "NS-1"
// string(4) "NS-2"
Можно даже пойти дальше и в одном неймспейсе определить константу другого неймспейса:
namespace FirstNs {
define('SecondNs\\SUPER_VALUE', 'NS-2-1');
}
namespace SecondNs {
define('FirstNs\\SUPER_VALUE', 'NS-1-2');
}
Делать так в продакшене категорически не рекомендуется.
Итак, сегодня мы разобрались с тем, как определять константы с учетом неймспейсов, используя как ключевое слово const
, так и функцию define
.