Как я могу согласовать требования к пространству имен SplClassLoader с моим собственным макетом каталога?
Я недавно начал писать пользовательский MVC-фреймворк на PHP. Это в основном учебное упражнение.
Мои классы расположены в следующих каталогах:
- Система / Библиотеки /
- система / Контроллеры /
- система / модели
- Приложение / библиотеки /
- приложение / контроллеры /
- применение / модели
Я не использую пространства имен, потому что не могу понять, как создавать экземпляры контроллеров, используя пространства имен и URL-адреса в стиле обработчика Apache 2 (controller/action/id). Я создал класс Bootstrap для автозагрузки других моих классов:
class Bootstrap
{
public function autoloadClasses($class)<br/>
{
$class .= '.php';
$classDirectories = array(
SYSTEM_LIBS_DIR,
SYSTEM_CONTROLLERS_DIR,
SYSTEM_MODELS_DIR,
APPLICATION_LIBS_DIR,
APPLICATION_CONTROLLERS_DIR,
APPLICATION_MODELS_DIR
);
foreach ($classDirectories as $classDirectory) {
$directoryIterator = new DirectoryIterator($classDirectory);
foreach($directoryIterator as $file) {
if ($file == $class) {
include $classDirectory . $class;
break 2;
}
}
}
}
public function register()
{
spl_autoload_register(array($this, 'autoloadClasses'), true);
}
public function init()
{
$this->register();
$loader = new Loader($_GET);
$controller = $loader->createController();
$controller->executeAction();
}
}
Работает нормально. Тем не менее, я знаю, что действительно должен использовать реализацию, рекомендованную PSR-0:
https://gist.github.com/221634
Однако я не могу понять, как заставить его работать без пространств имен. Похоже, что пространство имен является необязательным параметром. Однако, если я сделаю следующее, ничего не произойдет - даже ошибка в журналах Apache:
$libLoader = new SplClassLoader('', 'system/libraries');
2 ответа
Цель PSR-0 состояла в том, чтобы попытаться указать, как должны именоваться внешние классы сторонних библиотек и где файлы, содержащие эти классы, должны находиться на диске. Эта цель была достигнута, и на высоком уровне это не так уж плохо. Взаимозаменяемость и не переступать через другие библиотеки - это хорошо.
Ваша структура каталогов и схема именования классов не совпадают с PSR-0, что означает, что SplClassLoader будет практически бесполезен для вас.
У вас есть два варианта:
- Переименуйте все ваши классы, перетасуйте их в иерархию пространства имен и проведите рефакторинг остальной части кода, который должен беспокоиться об этом, или
- Не используйте SplClassLoader и не пишите свой собственный автозагрузчик.
Если вы создаете библиотеку, предназначенную для внешнего распространения, было бы неплохо сделать себя совместимым с PSR-0, поскольку это чертовски просто, логично и безболезненно.
Если вы создаете свое собственное приложение для собственного использования и не намерены использовать его в качестве библиотеки, тогда вам не нужно выполнять всю эту работу, и вы не должны этого делать, потому что это было бы глупо. Похоже, что так оно и есть, поэтому я могу закончить большой жир: не беспокойтесь.
Я получил это на работу. УРА!
Вот код из моего фронт-контроллера (index.php). Я собираюсь реорганизовать его, так как было бы проще сделать один вызов для некоторого типа класса начальной загрузки:
<?php
use NeilMVC\system\libraries\Loader;
require_once('conf/conf.php');
require_once('SplClassLoader.php');
$loadSystemLibraries = new SplClassLoader('NeilMVC\system\libraries');
$loadSystemControllers = new SplClassLoader('NeilMVC\system\controllers');
$loadSystemModels = new SplClassLoader('NeilMVC\system\models');
$loadApplicationLibraries = new SplClassLoader('NeilMVC\application\libraries');
$loadApplicationControllers = new SplClassLoader('NeilMVC\application\controllers');
$loadApplicationModels = new SplClassLoader('NeilMVC\application\models');
$loadSystemLibraries->register();
$loadSystemControllers->register();
$loadSystemModels->register();
$loadApplicationLibraries->register();
$loadApplicationControllers->register();
$loadApplicationModels->register();
$loader = new Loader($_GET);
$controller = $loader->createController();
$controller->executeAction();
Мне пришлось провести рефакторинг некоторых классов, чтобы преобразовать полностью определенные классы в неквалифицированные имена, используемые в URL-адресах в стиле MVC. Это было не так сложно сделать, мне просто пришлось повозиться с этим, чтобы понять это. Если кто-то хочет узнать больше, вы можете написать мне на мой сайт http://neilgirardi.com/
Ура и счастливых праздников!