#php #cms #роутер #ядро
Через запросы GET или POST из ядра движка идут запросы на те или иные модули, например,
модуль просмотра новости на сайте.
Если URL http://site.ru/?module=readnews&id=3, я делаю это так:
if ($module=="readnews") {
$news = new ReadNews();
$news->Display($id);
}
И т.д. через if-ы перебираю все модули. Или switch.
Но я где-то читал, что от такой конструкции можно избавиться, написав класс подключения
модулей, но этот класс надо написать так, чтобы внутри такая конструкция не встречалась.
Как можно такое организовать.
Ответы
Ответ 1
Расскажу как сделал свою CMS, которая используется на многих моих сайтах. Запросы идут через роутер (не знаю, но может быть, это не правильное название данного метода). Сразу скажу что моя система не идеальна и не каждому она подойдет, но мои сайты на ней прекрасно работают. Структура движка: / - корень — classes - классы — — engine.php - основной класс — — route.php - роутер (обработчик запросов) — controllers - контроллеры Элемент списка — — controller_index.php - главный модуль, будет запущен при вот таком вызове - site.ru/ — — controller_messages.php - тестовый модуль — index.php - главный файл, он принимает все запросы — .htaccess - ну это понятно Начну по порядку пожалуй. htaccess RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-l RewriteRule ^(.*)$ index.php?route=$1 [L,QSA] index.php /* разные настройки (вкл. ошибок и т.п.) */ function __autoload($class_name) { // авто подключение классов и модулей $file = $_SERVER['DOCUMENT_ROOT'] . '/' . (substr_count($filename, 'controller') ? 'controllers' : 'classes') . '/' . strtolower($class_name) . '.php'; if ( file_exists($file) ) include_once($file); } /* безопасное соединение с базой данных, файл лежит перед корнем сайта если вдруг упадет php, логин и пароль к базе данных никто не сможешь увидеть */ include_once('../db-site.php'); route::delegate(); // обрабатываем запросы, подключаем и запускаем необходимый модуль engine::run(); // стартуем движок engine.php - /classes/ class engine { /** * переменные движка * */ public static $alias, $content ; /** * Вывод 404 ошибки * */ public static function away() { header('HTTP/1.0 404 Not Found'); exit('404 Not Found'); } /** * Обработка запроса * * @param array $alias массив с параметрами */ public static function alias($alias) { foreach($alias as $k => $v) if ( !empty($v) ) $alias[$k] = $v; else unset($alias[$k]); self::$alias = $alias; } /** * Стартер движка * */ public static function run($alias) { echo self::$content; } } route.php - /classes/ class route { public static function delegate() { $route = empty($_GET['route']) ? '' : $_GET['route']; // проверка запроса if ( empty($route) ) $route = 'index'; // если запрос пуст, то есть - http://site.ru/ engine::alias(explode('/', $route)); // разбираем запрос на массив, site.ru/one/two -> array('one', 'two') $route = engine::$alias[0]; // достаем первый, он будет модулем - one $file = '/controllers/controller_' . $route . '.php'; if ( !is_file($file) ) engine::away(); // если модуль не найден - 404 Not Found $route = 'controller_' . $route; if ( !class_exists($route) ) engine::away(); // если модуль найден, а класс не найден - 404 Not Found $controller = new $route(); // создаем экземпляр класса $controller->delegate(engine::$alias); // запускаем модуль и передаем параметры запроса } } controller_messages.php - /controllers/ class controller_messages { function delegate($alias) { return self::$alias[0](); // [0] - это первый параметр. Например, site.ru/messages } function messages() { switch(engine::$alias[1]) { case 'add' : $ex = 'add message'; break; case 'edit' : $ex = 'edit message'; break; default : $ex = 'all messages'; break; } core::$content = $ex; } } controller_index.php - /controllers/ class controller_index { function delegate($alias) { core::$content = 'index page.. engine ok!'; } } Всё, система готова! Теперь при открытии главной страницы будет запускаться модуль controller_index.php и выводится текст index page.. engine ok!. На данной системе у меня стоит обработка AJAX и обычных POST запросов, мобильная версия, а также крутой парсер с условиями который упрощает работу в разы. Вопросы в комменты.Ответ 2
Ну вы же можете сделать вот так. Пользователь вводит URL: http://site.ru/?module=readnews&id=3. Мы видим, что он хочет загрузить какой-то модуль (какой - мы не знаем). Значит, берем значение из переменной module и проверяем есть ли такой модуль на сайте. Если модуль найден, загружаем его. Код при этом будет выглядеть примерно следующим образом: $modules = array('readnews', 'readarticles', 'watchphotos','404module'); $module = $_GET['module']; if(in_array($module, $modules){ $Module = new $module($_GET); $Module->Display(); }else{ $module = '404module'; $Module = new $module($_GET); $Module->Display(); } Пусть сам модуль думает над параметрами, которые ему передали в $_GET и что ему надо отобразить исходя из этих параметров. Код очень грубый. Но оформить его в виде удобных классов - это уже согласитесь... дело техники... Рекомендую также к прочтению: Model-View-Controller. Там описывается очень удобная структурная модель любого программного обеспечения. В том числе и для сайтов написанных на PHP. Называется MVC. Вообем здесь только дело за вами. Как сделаете - так и будете развивать в дальнейшем то, что сделали раньше. Другое дело, чтобы потом самому приятно было кодить...
Комментариев нет:
Отправить комментарий