alestro
@alestro

Php маршрутизация. Чем плох такой вариант?

Есть небольшой класс реализующий маршрутизацию в приложении.
namespace http;
class Router{
	private $routes=[];
	private $args=[];
	private $wildcards=['/{id}/'=>'([0-9]+)','/{name}/'=>'(.+)'];
	private $requestedUri;
	public function get($route, callable $callback){
		$this->routes['GET'][$route]=$callback;
	}
	public function post($route, callable $callback){
		$this->routes['POST'][$route]=$callback;
	}
	private function dispatch(){
		$uri = reset(explode('?', $_SERVER["REQUEST_URI"]));
      	$this->requestedUri = empty(urldecode(rtrim($uri, '/')))? '/':urldecode(rtrim($uri, '/'));
		$callback=$this->routes[$_SERVER['REQUEST_METHOD']][$this->requestedUri];
		if(is_callable($callback)){
			return $this->execute($callback);
		}
		foreach($this->routes[$_SERVER['REQUEST_METHOD']] as $route=>$callback){
			if($route==='/'){continue;}
			$pattern=preg_replace(array_keys($this->wildcards), $this->wildcards, $route);
			if(preg_match('~'.$pattern.'~',$this->requestedUri)===1){
				$this->args=array_diff(explode('/',$this->requestedUri),explode('/',$pattern));
				return $this->execute($callback);
			}
		}
	
	
	}
	
	private function execute(callable $callback){
			return call_user_func_array($callback,$this->args);
	}
	
	public function run(){
		return $this->dispatch();
	}
}

$router=new \http\Router();
$router->get('/path/{id}/self/{name}', function($id, $name){echo 'id : '.$id.'
name : '.$name;}); Пример использования роутера с функцией-замыканием.
Хотелось бы услышать мнение общественности. Что следует изменить, что добавить. Или может быть вовсе не делать так.
  • Вопрос задан
  • 466 просмотров
Пригласить эксперта
Ответы на вопрос 1
index0h
@index0h
PHP, Golang. https://github.com/index0h
Вы не проверяете вставляемый роут, а что если я туда объект вместо строки влеплю? Если что-то влетело не так - бросайте исключение.

Не используйте супер глобальные переменные. В начале создайте объект Request и уже с ним работайте.

Не ясно, зачем нужны trim-ы, urldecode и т.д. Если что-то пришло не так как надо - роут не найден, и ничего более. Это не проблема роутера, что ему могут каку вбросить.

callable - это довольно специфическая хрень. Это может быть массив из двух строк, функция, объект со строкой, просто строка. Нахрен это дерьмо. Используйте тогда уже \Closure.

Если у вас все равно регулярки всюду - имеет смысл использовать именованные последовательности:
|(?P<id>\d+)|
|(?P<name>[a-Z]+)|


Замены паттернов имеет смысл делать при вставке роута, а не на момент диспатча.

Форматирование...gqBbWeuzy9E.jpg
Почитайте про PSR-2

З.Ы. Когда наиграетесь - возьмите готовое и качественное в Symfony/Silex))
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы