Всем привет! Разрабатываю некоторый проект на 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?