@Artur937
junior

Почему Router странно обрабатывает запрос типа 'article/$1/$2', при этом 'article/$1' верно обрабатывается?

Router работал без нареканий, до того момента как потребовалось формировать на сайте запросы типа 'article/$1/$2' и 'woking/$1/$2'.

В процессе генерирования страницы верно находится нужный метод, при этом возникает следующая ошибка: при попытке захода на страницу 'working/1/2' ищет несуществующий action1 в контроллере, при попытке захода на страницу 'working/3/2' ищет несуществующий action3.

Warning: call_user_func_array() expects parameter 1 to be a valid callback, class 'WorkingController' does not have a method 'action3' in C:\OS\OSPanel\domains\mysite.ru\components\Router.php on line 65


Помогите разобраться в чем дело.

Файл routes
return array(
    'work' => 'work/view',
    'working/([0-9]+)/([0-9]+)' => 'working/getTestByNumq/$1/$2',
    'job/([0-9]+)' => 'job/getTest/$1',
    'article/([0-9]+)' => 'article/view/$1',
    'kurs' => 'kurs/index',
    '' => 'main/index',
);


Сам Router
<?php 

class Router
{
    private $routes;

    public function __construct()
    {
        $routesPath = ROOT.'/config/routes.php';
        $this->routes = include($routesPath);
    }

    // return request string

    private function getURI()
    {
        if (!empty($_SERVER['REQUEST_URI'])) {
            return trim($_SERVER['REQUEST_URI'], '/');
        }
    }

    public function run()
    {
        //Получить строку запросы
        $uri = $this->getURI();

        //Проверить наличие такого запроса в routes.php
        foreach ($this->routes as $uriPattern => $path) {
        
           // Сравниваем $uriPattern и $uri
            if (preg_match("~$uriPattern~", $uri)) {

                //Получаем внутренний путь из внешнего согласно правилу
                $internalRoute = preg_replace("~^$uriPattern$~", $path, $uri);


                //Определить какой контроллер и action обрабатывает запрос и параметры
                
                $segments = explode('/', $internalRoute);

                $controllerName = array_shift($segments) . 'Controller';
                $controllerName = ucfirst($controllerName);

                $actionName = 'action'.ucfirst(array_shift($segments));

                $parameters = $segments;

                //Подключить файл класса контроллера
                $controllerFile = ROOT . '/controllers/' . 
                $controllerName . '.php';

                if (file_exists($controllerFile)) {
                    include_once($controllerFile);
                } 
                // else {
                //     header('HTTP/1.0 404 Not Found');
                //     readfile('err404.html');
                //     exit();
                // }


                //Создать объект, взывать метод (т.е. action)
                $controllerObject = new $controllerName;                
                try { 
                    $result = call_user_func_array(array($controllerObject, $actionName), $parameters); 
                } catch (Exception $e) {
                    header('HTTP/1.0 404 Not Found');
                    readfile('err404.html');
                    exit();
                } 
                
                if($result != null){
                    break;
                } 
            }
        }
    }
}


Файл WorkingController
include_once ROOT.'/models/Working.php';

class WorkingController{  

    public static function actionGetTestByNumq($sub, $numq){

        require_once (ROOT. '/views/job/job.php');

        return true;
    }
}
  • Вопрос задан
  • 76 просмотров
Пригласить эксперта
Ответы на вопрос 2
Randel
@Randel
Developer
Знакомый код :)

$segments = explode('/', $internalRoute);

Вот тут ставьте бряку и смотрите на дальнейшие действия шаг за шагом.

Прочёл комментарии и вспомнил свой камент массиве маршрутов - регулярки писать от сложных к простым!!!
Ответ написан
Комментировать
VladimirAndreev
@VladimirAndreev
php web dev
preg_match("~^$uriPattern\$~", $uri)
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы