@lemonlimelike

Как сделать правильный роутинг?

Всем привет! Разрабатываю некоторый проект на php. Делаю свою MVC. Есть файл routes, в котором я прописываю маршруты. Сейчас там вот что:
<?php

return [
	[
		'url' => '', 
		'method' => 'GET', 
		'controller' => 'IndexController.php', 
		'action' => 'index'
	],
	[
		'url' => 'page/([0-9]+|[a-z]+)/',
		'method' => 'GET', 
		'controller' => 'PageController.php', 
		'action' => 'index'
	],
	[
		'url' => 'page/([0-9]+|[a-z]+)/([0-9]+|[a-z]+)',
		'method' => 'GET', 
		'controller' => 'PageController.php', 
		'action' => 'index'
	],
	[
		'url' => 'test/{name}/{id}',
		'method' => 'GET',
		'controller' => 'TestController.php',
		'action' => 'index'
	]
];


Первые три рута работаю по такой реализации:
<?php

namespace Core;

define("BASE_DIR", $_SERVER['DOCUMENT_ROOT']);
use Core\Request;

class Route
{
	const FILE_ROUTES = BASE_DIR . "/config/routes.php";
	const DIR_SRC = BASE_DIR . "/src";

	private $routes;
	private $url;
	private $method;
	private $params;

	public function __construct(string $url, string $method)
	{
		$this->url = $url;
		$this->method = $method;
	}

	private function load()
	{
		if ( file_exists(self::FILE_ROUTES) ){
			$this->routes = require self::FILE_ROUTES;
		}else{
			throw new \Exception('Routes not found');
		}
		
	}

	private function existUrl(): ?array
	{
		$url = trim($this->url, '/');

		foreach($this->routes as $route){
			$route['url'] = rtrim($route['url'], "/");
			$regExp = "#^{$route['url']}$#";

			if ( preg_match($regExp, $url, $matches) and $route['method'] === $this->method ){
				$this->params = array_slice($matches,1);
				return $route;
			}
		}

		return Null;
	}

	public function run()
	{
		$this->load();
		
		$route = $this->existUrl();
		
                // Всякие проверки

		$method = strtolower($route['method']);
		$this->$method($path, $route, $action);
		
	}

	public function get(string $path, array $route, string $action)
	{
		$request = new Request();

		$args = [$request, ...$this->params];

		$controller = new $path($route);
		call_user_func_array([$controller, $action], $args);
	}
}


Проблема такой реализации: я хочу в класс Request добавлять всякие GET параметры, POST параметры, хедеры и всякое такое; И передавать этот класс и еще какие-то параметры в контролер; Но я хочу чтоб эти параметры были именованы, чтоб в контролере с легкостью с ними работать.
Поэтому я решил сделать роутинг на подобие как в laravel. В файле routes.php есть пример такого рута, последний.
То есть на месте тех псевдо параметрах должны быть нормальные параметры.
Как такое реализовать?

Я думаю что стоит переписать метод existUrl, чтоб в нем по регулярном выражению находить в рутах совпадение и возвращать этот рут. Но как блин это сделать?

Я попытался написать такую регулярку, но она выводит лишь параметр {name}, а {id} почему-то нету
preg_match("#\w+/(\{[\w]*\})#", $route['url'], $matches);


Заранее извиняюсь за такой велосипед, просто задание писать на чистом php

Вот почему тут https://regex101.com/r/VJiGhL/1 регулярка показывает и name и id, а preg_match не показывает id?
  • Вопрос задан
  • 263 просмотра
Пригласить эксперта
Ответы на вопрос 1
nokimaro
@nokimaro
Меня невозможно остановить, если я смогу начать.
preg_match замените на preg_match_all
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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