привет, друзья. пишу CMS с нуля, назвал её hacked)))
делаю роутинг. оцените пожалуйста.
API для работы выглядит следующим образом:
Route::register(
[
'/' => 'Home',
'/user/$id/profile' => function ($id) {echo "Вы указали " . (int) $id . " в адресной строке";},
'/blog/' => 'Blog::Index',
'catch_all' => function () {die('404 - Not found.');}
]
);
Route::run('/');
Метод Route::register принимает массив с данными в формате «путь» => «класс», «метод», «функция» или «омнонимная функция».
Если указать просто класс, то будет вызван метод $_SERVER['REQUEST_METHOD']. Например, если мы выполняем GET-запрос странички /home/, которая ссылается на класс Home, то будет выполнен new Home()->get(); соответственно для post будет вызван метод new Home()->post(); и так далее. Поэтому самому указывать GET, POST и т.д. нигде не нужно.
Так же, в URL можно передавать параметры функциям, например URL вида «/user/$id/profile» запишет в переменную $id реальное значение параметра из URL
В случае, если запрошенный адрес не соответствует ни одному из указанных шаблонов в массиве Route::register([]);, то будет предложено вызвать содержимое 'catch_all' из массива. Например, туда можно записать 404 ошибку.
Ну и в довершении всего, метод Route::run(); запускает на выполнение заданный REQUEST_URI.
Route::run('/');
Route::run('/blog/something-else-string/');
Route::run(strtok($_SERVER['REQUEST_URI'], '?'));
Вы можете сами указать там любой URI, таким образом из любого места в любом скрипте вызвать любую страничку. А можете оставить стандартный $_SERVER['REQUEST_URI'].
<?php
class Route {
static protected $instance = null;
static private $routes = [];
public function __construct() {}
public function __destruct() {}
public function __clone() {}
static public function register($routes) {
if (self::$instance == null) {
self::$instance = new self;
}
if (is_array($routes)) {
self::$routes = $routes;
}
}
static public function run($route) {
if (self::$instance == null) {
self::$instance = new self;
}
$request_method = strtolower($_SERVER['REQUEST_METHOD']);
$discovered_handler = null;
$handler_instance = null;
$catch_all = true;
$path_args = [];
$path_parts = explode('/', $route);
foreach (self::$routes as $pattern => $handler_name) {
$uri_parts = explode('/', $pattern);
$uri_args = [];
$uri_rebuild = [];
for ($i = 0; $i < sizeof($uri_parts); $i++) {
if (isset($path_parts[$i])) {
if (substr($uri_parts[$i], 0, 1) == '$') {
$name = substr($uri_parts[$i], 1);
$uri_args[$name] = $path_parts[$i];
$uri_rebuild[] = $uri_parts[$i];
}
elseif ($path_parts[$i] == $uri_parts[$i]) {
$uri_rebuild[] = $uri_parts[$i];
}
}
}
$uri_rebuild = implode('/', $uri_rebuild);
if (isset(self::$routes[$uri_rebuild])) {
$discovered_handler = $handler_name;
$path_args = $uri_args;
}
}
if ($discovered_handler) {
if (is_string($discovered_handler)) {
if (class_exists($discovered_handler)) {
$handler_instance = new $discovered_handler();
}
}
elseif (is_callable($discovered_handler)) {
$handler_instance = $discovered_handler();
}
}
if ($handler_instance) {
if (method_exists($handler_instance, $request_method)) {
$catch_all = false;
call_user_func_array([$handler_instance, $request_method], $path_args);
}
}
if ($catch_all) {
if (isset(self::$routes['catch_all'])) {
self::run('catch_all');
}
}
}
}