+ (+/-)
<?php
/**
* паттерн Front Controller
* @link http://phpmaster.com/front-con ... rn-1/
*/
class Route {
protected $controller = 'Controller_Index';
protected $action = 'action_index';
protected $params = array();
protected $basePath = 'index/';
public function __construct(array $options = array())
{
if (empty($options))
{
$this->parse_Uri();
}
else
{
if (isset($options["controller"]))
{
$this->setController($options["controller"]);
}
if (isset($options["action"]))
{
$this->setAction($options["action"]);
}
if (isset($options["params"]))
{
$this->setParams($options["params"]);
}
}
}
protected function parse_Uri()
{
$path = trim(parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH), "/");
$path = preg_replace('/[^a-zA-Z0-9]\//', "", $path);
list($controller, $action, $params) = explode("/", $path, 3);
if (!empty($controller))
{
$this->setController($controller);
}
if (!empty($action))
{
$this->setAction($action);
}
if (!empty($params))
{
$this->setParams(explode("/", $params));
}
}
public function setController($controller)
{
$controller = 'Controller_'.ucfirst(strtolower($controller));
if (!class_exists($controller))
{
throw new \InvalidArgumentException(
'The action controller '.$controller.' has not been defined.');
}
$this->controller = $controller;
return $this;
}
public function setAction($action)
{
$action = 'action_'.$action;
if (!method_exists($this->controller, $action))
{
throw new \InvalidArgumentException(
'The controller action '.$action.' has been not defined.');
}
$this->action = $action;
return $this;
}
public function setParams(array $params)
{
$this->params = $params;
return $this;
}
public function run()
{
call_user_func_array(array(new $this->controller, $this->action), $this->params);
}
}
# Saniok (05.08.2013 / 21:23)++ Именно так по коду гг
Если я правильно понял это загрузка библиотек и классов из папки,...
// Подключаем и проверяем конфиг.
$config = require 'assets/conf/router.php';
$required = array('default' => 'string', 'error' => 'string');
$error = array();
foreach ($config as $key => $value) {
if (!array_key_exists($key, $required)) {
$error[] = '"' . $key . '"" element should be defined in the basic configuration.';
} else {
$type = 'is_' . $required[$key];
if (!$type($value)) {
$error[] = 'Invald type of "' . $key . '". Element should be a ' . $required[$key] . '.';
} else {
unset($required[$key]);
}
}
}
if (!empty($required)) {
$error[] = 'Missing: ' . implode(', ', array_keys($required));
}
if (!empty($error)) {
throw new Exception('The following errors occured:' . "\r\n" . implode("\r\n", $error) . "\r\n" . 'Check your router configuration file.');
}
// Рзбираем URI
// Parse URI
$uri = isset($_SERVER['REQUEST_URI']) && is_string($_SERVER['REQUEST_URI'])
? explode('/', trim($_SERVER['REQUEST_URI'], '\/ '))
: array();
$module = isset($uri[0]) && trim($uri[0]) != '' ? trim($uri[0]) : $config['default'];
$controller = isset($uri[1]) && trim($uri[1]) != '' ? trim($uri[1]) : 'index';
$action = isset($uri[2]) && trim($uri[2]) != '' ? trim($uri[2]) : 'view';
$args = sizeof($uri) > 3 ? array_slice($uri, 3) : array();
// Пробуем создать объект контроллера.
// Здесь подразумевапеся, что файл будет подключён автоматически с помощью функции заданной через spl_autoload_register
// Класс контроллера должен находиться в пространстве имён \modules\имя_модуля\controller
// Путь к файлу контроллёра должен быть следующим: ~/modules/имя_модуля/controller/имя_класса_контроллера.расширение_заданное_в_автозагрузчике
$class = '\modules\\' . $module . '\controller\\' . ucwords($controller);
try {
$object = new $class(/* TODO: pass args */); // Сюда нужно передать аргументы, которые требует родительский контроллёр
} catch (\Exception $e) {
// Проверяем, не является ли запрашиваемый контроллёр страницей ошибки, воизбежание зацикливания редиректа.
if ($module == $config['error'] && $controller == 'index') {
throw new Exception('Error page is not exists.');
} else {
redirect($config['error']); // Перенаправляем на страницу ошибки.
}
}
// Проверяем, наследуется ли контроллёр от нужного нам класса.
if (!$object instanceof \Controller) {
throw new Exception('Object of controller should be instance of \Controller');
}
// Проверка метода на существование.
// Здесь тоже следовало бы проверять, не отвечает ли контроллёр за страницу ошибки.
// Но так как родительский контроллер имеет абстрактный метод, который отвечает за страницу по умолчанию, в этом нужды нет.
// PHP предупредит нас об этом заранее.
$action = 'action_' . $action;
if (!method_exists($controller, $action)) {
redirect($config['error']);
}
// Вызываем метод контроллёра попутно передав ему аргументы, которые были получены из URI
$result = strval(call_user_func_array(array($controller, $action), $args));
if (headers_sent()) {
// Если заголовки были отправлены, то обрабатываем их. Например можно записать выведенные данные в лог. Вероятно где-то произошла ошибка.
// ...
} else {
// Если метод возвратил не пустую строку, то загружаем шаблонизатор и выводим полученные данные.
if (!empty($result) && is_string($result)) {
$tpl = new \Template();
header('Content-type: application/xhtml+xml; charset=utf-8');
echo $tpl->load('index', 'contents' => $result);
} else {
// Если метод вернул другой тип данных, то обрабатываем его так, как нам нужно.
// Например метод вернул массив, значит его можно отобразить в виде json строки, что мы и сделаем.
if (is_array($result)) {
echo json_encode($result);
}
}
}
function get_route()
{
$url = parse_url($_SERVER['REQUEST_URI']);
$url_arr = explode('/', $url['path']);
return array_slice($url_arr, 1);
}
$route = get_route();
echo $route[0]; // Вернёт path
echo $route[1]; // Вернёт action
echo $route[2]; // Вернёт id
чтобы act'ы по файлам раскиданы