Автозагрузка классов php из подпапок с использованием нотации подчеркивания (стиль PEAR)
Я немного новичок в объектно-ориентированном PHP и MVC, поэтому мне действительно нужна помощь, пожалуйста.
У меня есть структура папок в стиле MVC с подпапками в файловой системе
- например view/classes/subfolder/classname.php
Я использую mod_rewrite для удобных для пользователя URL, так как /classname
или же /foldername/calssname
, которые затем передаются загрузчику страниц в виде значений, разделенных подчеркиванием.
- например foldername_classname
// Файл загрузчика страницы require_once($_SERVER['DOCUMENT_ROOT'] '/ местные /classLoader.php.); session_start(); $page = new $_REQUEST['page'];
Ранее я использовал блок [if / else if / else] для тестирования в каждой возможной папке, но это кажется неэффективным, поэтому я ищу лучший способ, чтобы автозагрузчик выглядел во многих разных местах.
Вот моя последняя ошибка, когда не удается найти ни один из запрошенных классов, а просто выводится исключение для каждого, заканчивающегося фатальной ошибкой!:
function classToPath ($ class) { $ path = str_replace ('_', '/', $ class). '.Php'; вернуть $ path; } function autoloadController ($ class) { echo 'LoadController'. '
"; $ root = '/ controller / classes /'; $ pathtoclass = $ root.classToPath ($ class); пытаться { if( file_exists($pathtoclass)) require_once($pathtoclass); иначе сгенерировать новое исключение ('Cannot load controller'.$class); } catch(исключение $e) { echo 'Исключение контроллера:'. $ e-> getMessage (). "
"; } } function autoloadModel ($ class) { echo 'LoadModel'. '
"; $root = '/model/classes/'; $pathtoclass = $root.classToPath($class); пытаться { if( file_exists($pathtoclass)) require_once($pathtoclass); еще бросить новое исключение ("Не удается загрузить модель".$class); } catch(исключение $e) { echo 'Исключение модели:'. $ e-> getMessage (). "
"; } } function autoloadView ($ class) { echo 'LoadView'. '
"; $root = '/view/classes/'; $pathtoclass = $root.classToPath($class); пытаться { if( file_exists($pathtoclass)) require_once($pathtoclass); еще бросить новое исключение ("Не удается загрузить представление".$class); } catch(исключение $e) { echo 'Просмотр исключения:'. $ e-> getMessage (). "
"; } } spl_autoload_register ('autoloadController'); spl_autoload_register ('autoloadModel'); spl_autoload_register ('autoloadView');
Мне также было интересно, как именно должен работать URL для сопоставления папок / классов:
- т.е. URL:
/foldername/classname
mod_rewritten to foldername_classname
; с именем файла класса
classname.php
под foldername
папки; и определение класса php
class foldername_classname extends another_class { etc.
Это правильный метод?
1 ответ
Скорее случайно, касаясь другого вопроса, я нашел решение своей проблемы!
Поэтому, чтобы ответить на мои собственные вопросы (и, надеюсь, помочь другим):
- имя файла должно быть только последней частью URL
т.е..../not-this-part/but-this
- структура папок должна быть картой структуры URL
например.../folder/subfolder/class
- и класс должен быть определен как полный путь, но с подчеркиванием вместо прямой косой черты
напримерclass folder_subfolder_class {
Затем я написал функцию для каждой системы классов (модель, представление и контроллер) и использовал spl_autoload_register()
зарегистрировать каждую функцию как __autoload
функция. Таким образом,...
function loadController ($ class) { $ path = $ _SERVER ['DOCUMENT_ROOT']. '/ application / controller /'; $ filename = str_replace ('_', DIRECTORY_SEPARATOR, strtolower ($ class)). '. php'; if (file_exists ($ path. $ filename)) { require_once ($ путь $ имя_файла.); } } etc..etc.. spl_autoload_register('loadController'); ...
Для тех, кто интересуется mod_rewrite
часть...
IfModule mod_rewrite.c RewriteEngine On RewriteBase / RewriteCond %{SCRIPT_FILENAME}!-F RewriteCond %{SCRIPT_FILENAME}!-D RewriteRule ^([az]+)/([az]+)/? [$ /? Page=$1_$2 [QSA,NC,L] RewriteRule ^([az]+)/?$ /? Page=$1 [QSA,NC,L] /IfModule