Я знаю, что на этот вопрос уже есть ответ, но я хотел предоставить более реалистичное решение того, что я считаю вашей проблемой.Если бы у меня было больше времени вчера, когда я сделал свой комментарий, я бы опубликовал это.Извините, что я этого не сделал.
Похоже, у OP есть модульная система, которую он должен знать, загружен ли конкретный модуль, прежде чем разрешить ему вызов.
Во-первых, я хотел бы сказать, что использование пространств имен просто для объявления активных модулей - это, IMO, злоупотребление тем, для чего они предназначены.Если вы следуете цели пространства имен для буквы, ваша структура может выглядеть примерно так:
Вся ваша система должна находиться в собственном пространстве имен.Давайте назовем это пространство имен System
.Тогда модули, вероятно, будут находиться в пространстве имен System\Module
.Тогда, в зависимости от сложности, возможно, что каждый модуль может иметь пространство имен в System\Module
.Взяв ваши примеры, System\Module\FOO
и System\Module\BAR
.
Теперь давайте приступим к созданию модульной системы, которая регистрирует себя при нагрузке.
Сначала нам нужно место для регистрации.Давайте назовем это System\Module\Registry
и, поскольку существует много разных реестров, он будет реализовывать System\iRegistry
.Для краткости я выкладываю только System\Module\Registry
.По всей вероятности, он также будет реализовывать какую-то глобальную модель согласованности, например, синглтон, но я тоже этого не показываю.Вот оно:
<?php
namespace System\Module
{
class Registry extends System\Registry
{
protected $registered = array();
public function register( $name=null )
{
$this->registered[] = $name;
}
public function isRegistered( $module )
{
// Code to find module
}
public function getModule( $module )
{
// Code to find module
// OR, if you can't find it...
throw new ModuleNotRegisteredException("Module named \"{$module}\" could not be found in the registry.");
}
}
}
?>
Теперь в каждом модуле вам нужно вызывать эту функцию регистра при загрузке файла.Есть несколько способов сделать это.Во-первых, иметь некоторый код в пространстве имен вашего модуля, который работает под нагрузкой, аналогично типичному процессуальному коду:
namespace System\Module\FOO
{
// Load this module
$system->module->register("FOO");
}
Выше было бы означать дублирование кода.Вместо этого вы также можете использовать автозагрузку, чтобы «регистрирующий» код находился в одном месте.Вот очень простая концепция для этого:
spl_autoload_register(
function ($className)
{
// Code to load files.
// Once loaded register our modules.
if( $namespace = "System\\Module" )
{
$system->module->register( $classname );
}
}
);
Другой возможный способ сделать это - определить интерфейс для модулей с определенной функцией регистрации при инициализации модуля.Это, однако, означает, что модуль должен быть загружен первым и может вызвать его собственные проблемы в зависимости от ваших потребностей.
После этого:
- у вас есть согласованное пространство имен для модулей дляживя в
- у вас есть согласованный интерфейс, который позволяет любому модулю знать, как зарегистрироваться
- вы можете легко расширять интерфейсы модуля или реестра в будущем для новых вещей, сохраняя при этом ваш код чистыми легко понять.
- и, самое главное , вы будете знать, что ваши модули фактически объявят, что они загружены и / или готовы вместо того, чтобы полагаться на чёрную магию, чтобы сделать это для вас.