Всем привет! Я значит пишу роутер:
<?PHP
class router {
public function Redirect($url, $permanent = false) {
header('Location: ' . $url, true, $permanent ? 301 : 302);
exit();
}
public function getRequestPath() {
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
return '/' . ltrim(str_replace('index.php', '', $path), '/');
}
public function getMethod(array $routes, $path) {
foreach ($routes as $route => $method) {
if ($path === $route) {
return $this->routing($method);
}
}
return $this->errorpage();
}
public function routing($method) {
if ($method == 'main') {
// Some code
echo 'Main Page!!!';
}
}
public function errorpage($error_page) {
$smarty = new Smarty();
$smarty->setTemplateDir('templates/');
$smarty->setCompileDir('templates_c/');
$smarty->setConfigDir('configs/');
$smarty->setCacheDir('cache/');
$smarty->assign('VERGEN',rand(20, 150000));
$HttpStatus = $_SERVER["REDIRECT_STATUS"];
$httpc = array(400,401,403,404,500,503);
if ($error_page == null) {
if (in_array($HttpStatus, $httpc)) {
$error_page = $HttpStatus;
} else {
$error_page = 404;
}
}
if ($error_page == 400) {
header('HTTP/1.0 400 Bad Request');
header("HTTP/1.1 400 Bad Request");
header("Status: 400 Bad Request");
$title = "400 - Плохой запрос!";
$title1 = "400";
$reason = "Плохой запрос!<br>Через 15 секунд вы будете автоматически перенаправлены на главную страницу.";
} else if ($error_page == 401) {
header('HTTP/1.0 401 Unauthorized');
header("HTTP/1.1 401 Unauthorized");
header("Status: 401 Unauthorized");
$title = "401 - Ошибка авторизации!";
$title1 = "401";
$reason = "Ошибка авторизации!<br>Через 15 секунд вы будете автоматически перенаправлены на главную страницу.";
} else if ($error_page == 403) {
header('HTTP/1.0 403 Forbidden');
header("HTTP/1.1 403 Forbidden");
header("Status: 403 Forbidden");
$title = "403 - Запрещено!";
$title1 = "403";
$reason = "Вы попали на запрещённую страницу сайта!<br>Через 15 секунд вы будете автоматически перенаправлены на главную страницу.";
} else if ($error_page == 404) {
header('HTTP/1.0 404 Not Found');
header("HTTP/1.1 404 Not Found");
header("Status: 404 Not Found");
$title = "404 - Нет такой страницы!";
$title1 = "404";
$reason = "Такой страницы не существует!<br>Через 15 секунд вы будете автоматически перенаправлены на главную страницу.";
} else if ($error_page == 500) {
header('HTTP/1.0 500 Internal Server Error');
header("HTTP/1.1 500 Internal Server Error");
header("Status: 500 Internal Server Error");
$title = "500 - Внутренняя ошибка сервера!";
$title1 = "500";
$reason = "Внутренняя ошибка сервера!<br>Через 15 секунд вы будете автоматически перенаправлены на главную страницу.";
} else if ($error_page == 503) {
header('HTTP/1.0 503 Service Temporarily Unavailable');
header('HTTP/1.1 503 Service Temporarily Unavailable');
header('Status: 503 Service Temporarily Unavailable');
$title = "503 - Ведутся технические работы";
$title1 = "503";
$reason = "Ведутся технические работы!<br>По окончанию всех работ сайт снова заработает.<br>Приносим свои извинения за доставленные неудобства.";
} else {
$this->Redirect('/', false);
}
$smarty->assign('TITLE',$title);
$smarty->assign('TITLE1',$title1);
$smarty->assign('REASON',$reason);
$smarty->display('global/error.tpl');
}
public function display($routes) {
$path = $this->getRequestPath();
$method = $this->getMethod($routes, $path);
return $method;
}
}
?>
Запускаю так:
$rout = new router();
$routes = [
'/' => 'main'
];
$rout->display($routes);
Всё замечательно работает и удовлетворяет мои потребности, но! Мне постоянно приходится править класс роутера, это неудобно! Хочу от этого уйти но не придумал как. Допустим, я хочу реализовать страницы в бд, и чтобы мне их отобразить, мне нужно снова править роутер (функцию routing).
Как, допустим, сделать привязку к каждому значению массива функцию? Допустим, есть массив и к каждой строке уже из базы задавать что откуда вызвать? Сделать другой многомерный массив? А там уже экшенами дёргать? Вот я курил это но не сообразил как сделать... Как организовать Router php
Если для чисто изучения - ReflectionClass Если хотите выучить и понять, как лучше - смотрите уже давно реализованные роутеры
Если в Вашем случае, попробуем такой небольшой велосипед.
Нам потребуются конкретно методы hasMethod => getMethod => invoke
Общий принцип такой:
А вот так будет выглядеть пример ( все методы парсинга я убрал из класса Router и добавил класс Controller )
class Router {
public function routing ( $method ) {
$reflectClass = new \ReflectionClass( "Controller" );
if ( $reflectClass->hasMethod( $method ) ) {
$reflectMethod = $reflectClass->getMethod( $method );
$className = $reflectClass->getName();
echo $reflectMethod->invoke( new $className );
}
}
}
class Controller {
public function main () {
return "main";
}
public function test () {
return "test";
}
}
$get = ["main", "test"];
$router = new Router();
foreach ( $get as $route ) {
$router->routing( $route );
echo " ";
}
// выведет: main test
Проверить можно тут
Это лишь самый простой, вялый и не проработанный пример, который просто показывает принцип. Нормальные конструкции уже будут включать в себя и автозагрузчики, и передачу аргументов, и более серьезные проверки и т.д.
ПыСы, необязательно использовать для этого ReflectionClass, однако он предоставляет удобный и более чем полный функционал для таких целей
Подошёл с другой стороны. Использовал call_user_func. Удалил routing из-за ненадобности.
<?PHP
class router {
public function Redirect($url, $permanent = false) {
header('Location: ' . $url, true, $permanent ? 301 : 302);
exit();
}
public function getRequestPath() {
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
return '/' . ltrim(str_replace('index.php', '', $path), '/');
}
public function getfuncuser(array $routes, $path) {
foreach ($routes as $route => $funcuser) {
if ($path === $route) {
return call_user_func($funcuser);
}
}
return $this->errorpage();
}
public function errorpage($error_page) {
$smarty = new Smarty();
$smarty->setTemplateDir('templates/');
$smarty->setCompileDir('templates_c/');
$smarty->setConfigDir('configs/');
$smarty->setCacheDir('cache/');
$smarty->assign('VERGEN',rand(20, 150000));
$HttpStatus = $_SERVER["REDIRECT_STATUS"];
$httpc = array(400,401,403,404,500,503);
if ($error_page == null) {
if (in_array($HttpStatus, $httpc)) {
$error_page = $HttpStatus;
} else {
$error_page = 404;
}
}
if ($error_page == 400) {
header('HTTP/1.0 400 Bad Request');
header("HTTP/1.1 400 Bad Request");
header("Status: 400 Bad Request");
$title = "400 - Плохой запрос!";
$title1 = "400";
$reason = "Плохой запрос!<br>Через 15 секунд вы будете автоматически перенаправлены на главную страницу.";
} else if ($error_page == 401) {
header('HTTP/1.0 401 Unauthorized');
header("HTTP/1.1 401 Unauthorized");
header("Status: 401 Unauthorized");
$title = "401 - Ошибка авторизации!";
$title1 = "401";
$reason = "Ошибка авторизации!<br>Через 15 секунд вы будете автоматически перенаправлены на главную страницу.";
} else if ($error_page == 403) {
header('HTTP/1.0 403 Forbidden');
header("HTTP/1.1 403 Forbidden");
header("Status: 403 Forbidden");
$title = "403 - Запрещено!";
$title1 = "403";
$reason = "Вы попали на запрещённую страницу сайта!<br>Через 15 секунд вы будете автоматически перенаправлены на главную страницу.";
} else if ($error_page == 404) {
header('HTTP/1.0 404 Not Found');
header("HTTP/1.1 404 Not Found");
header("Status: 404 Not Found");
$title = "404 - Нет такой страницы!";
$title1 = "404";
$reason = "Такой страницы не существует!<br>Через 15 секунд вы будете автоматически перенаправлены на главную страницу.";
} else if ($error_page == 500) {
header('HTTP/1.0 500 Internal Server Error');
header("HTTP/1.1 500 Internal Server Error");
header("Status: 500 Internal Server Error");
$title = "500 - Внутренняя ошибка сервера!";
$title1 = "500";
$reason = "Внутренняя ошибка сервера!<br>Через 15 секунд вы будете автоматически перенаправлены на главную страницу.";
} else if ($error_page == 503) {
header('HTTP/1.0 503 Service Temporarily Unavailable');
header('HTTP/1.1 503 Service Temporarily Unavailable');
header('Status: 503 Service Temporarily Unavailable');
$title = "503 - Ведутся технические работы";
$title1 = "503";
$reason = "Ведутся технические работы!<br>По окончанию всех работ сайт снова заработает.<br>Приносим свои извинения за доставленные неудобства.";
} else {
$this->Redirect('https://allsvr.ru/', false);
}
$smarty->assign('TITLE',$title);
$smarty->assign('TITLE1',$title1);
$smarty->assign('REASON',$reason);
$smarty->display('global/error.tpl');
exit;
}
public function display($routes) {
$path = $this->getRequestPath();
$funcuser = $this->getfuncuser($routes, $path);
return $funcuser;
}
}
?>
Теперь всё работает как надо.
То есть мой роутер запускает нужную мне функцию.
function main() {
echo "Hello World!";
}
$rout = new router();
$routes = [
'/' => 'main'
];
$rout->display($routes);
При заходе на главную запустится main и выведет Hello World!.
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости