Я работаю над разработкой пользовательской структуры. И я столкнулся с проблемой, когда попытался динамизировать вызов моих классов.
Это изображение моих файлов:
Поэтому я решил создать другую функцию для каждой папки (libs, controllers et modelses):
function autoloadLibs($class) { //require the general classes require 'libs/' . $class . '.php'; } function autoloadModels($class) { //require the models classes require 'models/' . $class . '.php'; } function autoloadControllers($class) { //require the controllers classes require 'controllers/' . $class . '.php'; } spl_autoload_register ('autoloadLibs'); spl_autoload_register ('autoloadControllers'); spl_autoload_register ('autoloadModels');
Тем не менее у меня есть это сообщение: Warning: require (libs / admin.php): не удалось открыть поток , и это не хорошая папка. Но я не знаю, как это исправить. Есть ли хороший способ оптимизировать мои вызовы классов?
После нескольких тестов я нашел это решение для своего случая:
set_include_path(implode(PATH_SEPARATOR, array(get_include_path(), './libs', './controllers', './models'))); spl_autoload_register();
Прежде чем пытаться require
его, вам необходимо проверить, существует ли файл с is_file()
.
При использовании spl_autoload_register()
я обнаружил, что лучше всего зарегистрировать один метод для включения файлов. Тот факт, что вы можете использовать несколько функций, я считаю, что облегчить взаимодействие с различными библиотеками (так что они не clobber __autoload()
). Это также поможет вам записать код несколько раз, чтобы проверить наличие существующего файла, _
в разделителе каталогов (если вы это сделаете) и т. Д.
Итак, если вы измените свои имена файлов в соответствии с соглашением Underscore_Separated_Name
, например Controller_Admin_Dashboard
, вы можете использовать …
function autoload($className) { $path = SYSPATH . str_replace("_", DIRECTORY_SEPARATOR, strtolower($className)) . ".php"; if (is_file($path)) { require $path; } }
При первом запуске Controller_Admin_Dashboard
PHP может включать файл, например /app/controller/admin/dashboard.php
.
Если у вас есть несколько вызовов spl_autoload_register
вам нужно убедиться, что вы не используете ключевое слово require
для включения файлов, потому что это означает «включить файл или умереть, если он не может» .
Лично я не согласен с другими в том, что у меня есть только одна функция автозагрузки, особенно если вы включаете классы из разных мест, например, контроллеры или некоторые библиотеки. Я также проверяю, существует ли файл первым, а затем включите его.
Версия tl; dr: не разрешать вызовы spl_autoload_register
блокировать друг друга.
ваш ответ здесь. когда вы регистрируете несколько автозагрузчиков, php пытается загрузить класс любым из этих автозагрузчиков. Затем php вызывает эти автозагрузчики с первого зарегистрированного до последнего. Затем в любом из этих автозагрузчиков вы должны проверить, что file_exists или нет, иначе php попытается включить его и выдает ошибку, если этот файл не существует. Затем , перед включением, проверьте наличие файла. Измените автозагрузчики на:
function autoloadLibs($class) { #require the general classes $file = 'libs/' . $class . '.php'; if(file_exists($file)) require $file; } function autoloadModels($class) { #require the models classes $file = 'models/' . $class . '.php'; if(file_exists($file)) require $file; } function autoloadControllers($class) { #require the controllers classes $file = 'controllers/' . $class . '.php'; if(file_exists($file)) require $file; }
Вы должны проверить имена классов перед тем, как потребовать файл, например:
function autoloadControllers($class) { //require the controllers classes if( substr( $class, -10) == 'Controller')){ require 'controllers/' . $class . '.php'; } }
Я считаю правильным вызвать ошибку, если класс не может быть загружен, но вы должны убедиться, что require
вызывается только по правильному пути.
Обратите внимание, что spl_autoload_register
предоставляет третий параметр ( prepend
). Вы можете установить это значение true
если хотите разместить определенную функцию автозагрузки поверх стека автозагрузки. Это означает, что эта конкретная функция затем будет вызвана первой.
Пример:
spl_autoload_register (массив ('My_Class', 'My_Method'), true, true);
http://www.php.net/manual/en/function.spl-autoload-register.php