Q:

Как прописать маршрут с помощью регулярок PHP

routes.php:
<?php
return [
  'jobs' => [
    'controller' => 'main',
    'action' => 'jobsList',
    'path' => 'main/jobs/jobs'
  ],
  'jobs/{page:\d+}' => [
    'controller' => 'main',
    'action' => 'jobsList',
    'path' => 'main/jobs/jobs'
  ],
  'jobs/{url:\D+}' => [
    'controller' => 'main',
    'action' => 'job',
    'path' => 'main/jobs/job'
  ],
];

Есть массив который содержит маршруты. Первый элемент это просто страница со списком вакансий (www.site.com/jobs). Второй элемент это страницы, через неё я сделал пагинацию(www.site.com/jobs/3). Третий элемент это ссылка на конкретную страницу с конкретными данными о вакансии (www.site.com/jobs/url_url).
Router.php:
<?php

namespace app\core;

use app\core\View;

class Router {

  protected $routes = [];
  protected $params = [];

  public function __construct() {
    $arr = require 'app/config/routes.php';
    foreach ($arr as $key => $val) {
      $this->add($key, $val);
    }
  }

  public function add($route, $params) {
    $route = preg_replace('/{([a-z]+):([^\}]+)}/', '(?P<\1>\2)', $route);
    $route = '#^'.$route.'$#';
    $this->routes[$route] = $params;
  }

  public function match() {
    // debug($this->routes);
    $url = trim($_SERVER['REQUEST_URI'], '/');
    foreach ($this->routes as $route => $params) {
      if (preg_match($route, $url, $matches)) {
        foreach ($matches as $key => $match) {
          if (is_string($key)) $params[$key] = $match;
        }
        $this->params = $params;
        return true;
      }
    }
    return false;
  }

  public function run(){
    if ($this->match()) {
      $path = 'app\controllers\\'.ucfirst($this->params['controller']).'Controller';
      if (class_exists($path)) {
        $action = $this->params['action'].'Action';
        if (method_exists($path, $action)) {
          $controller = new $path($this->params);
          $controller->$action();
        } else {
          View::errorCode(404);
        }
      } else {
        View::errorCode(404);
      }
    } else {
      View::errorCode(404);
    }
  }
}

Вот роутер. Я не сам его писал, взял с видео урока и не до конца понимаю как он обрабатывает маршрут. Но всё вроде как работает и отлично. Но сейчас столкнулся с проблемой. Я хочу сделать фильтр, и разумеется делать это лучше всего через отправку формы методом GET, но когда добавляются переменные к адресу, www.site.com/jobs?param1=val1&param2=val2. Уже выдаёт ошибку View::errorCode(404) потому что в маршрутах такого нет. Так вот, может кто то помочь прописать маршрут с помощью регулярок, чтобы работала ссылка при отправке формы с помощью GET, и чтобы она работала на разных страницах, тобиш www.site.com/jobs/1?param1=val1, www.site.com/jobs/2?param2=val2

A:

Все что нужно сделать это изменить эту строчку:
$url = trim($_SERVER['REQUEST_URI'], '/');
Дело в том, что REQUEST_URI возвращает часть с _GET и поэтому роуты ломаются (ваш кеп).
Решение тут может быть такое:
$url = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/');

