@Artur937
junior

Почему не возникает ошибка 404?

Настраиваю выдачу ошибок 404 на сайте. На страницах происходит следующее явление:
адрес - site.ru/job/3232412 (генерирует ошибку 404)
НО страницы site.ru/job и site.ru/job/(любой текст) ошибку 404 не генерируют
Помогите разобраться в чем дело и как это исправить.

На странице генерируется ошибка
Warning: call_user_func_array() expects parameter 1 to be a valid callback, class 'JobController' does not have a method 'actionSadasads' in C:\OS\OSPanel\domains\mysite.ru\components\Router.php on line 63

Проверку "есть ли такой контроллер" я настроил, а как сделать проверку "есть ли в контроллере нужный метод". Или что-то неправильно понимаю? Проясните.

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


Модель Job
class Job{

    public static function getTest($id){
        $id = intval($id);

        if ($id) {
            $db = Db::getConnection();
            header("Content-Type: text/html; charset=UTF-8");
            $db->query( "SET CHARSET utf8" );
            $result = $db->query ("SELECT * FROM tests WHERE id = " . $id);
            return $result->fetch();

        }
    }

    public static function getQuestion($id){
        $id = intval($id);

        if ($id) {
            $db = Db::getConnection();
            header("Content-Type: text/html; charset=UTF-8");
            $db->query( "SET CHARSET utf8" );
            $result = $db->query ("SELECT * FROM tests_new WHERE var_id = " . $id);                
            return $result->fetch();


        }
    }

}


Файл JobController
include_once ROOT.'/models/Job.php';

class JobController{
    public static function actionGetTest($id){
        $test = Job::getTest($id);
        if(!($test)) {
                header('HTTP/1.0 404 Not Found');
                readfile('err404.html');
                exit();
            }
        $question = Job::getQuestion($id);
        if(!($question)) {
            header('HTTP/1.0 404 Not Found');
            readfile('err404.html');
            exit();
         }
        require_once (ROOT. '/views/job/job.php');
        return true;
    }
}


Сам Router
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;
                $result = call_user_func_array(array($controllerObject, $actionName), $parameters);
                
                if($result != null){
                    break;
                } 
            }
        }
    }
}
  • Вопрос задан
  • 98 просмотров
Решения вопроса 1
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
TL;DR
Есть простой выход: Во первых контроллеры должны расширяться от базового контроллера, во вторых в базовом контроллере напишите __call() метод с выбросом ошибки и выводом 404 вьюшки.

PS: что в модели делают заголовки и прочий хтмл мусор, включая подгрузку из вью?
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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