Форум программистов, компьютерный форум, киберфорум
PHP для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/18: Рейтинг темы: голосов - 18, средняя оценка - 4.56
2 / 2 / 0
Регистрация: 19.08.2017
Сообщений: 50

Как сделать 404 ошибку в Роутере

05.05.2018, 01:19. Показов 3571. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Коллеги! Как сделать проверку в файле Router.php - чтобы когда при заходе на любую неправильную ссылку вместо белого экрана была 404 ошибка. На данный момент из-за роута типа 'category/([-a-z]+)' => 'catalog/category/$1', при вводе любой неправильной ссылки типа site/category/errorlinkkk - выводит категорию без нужных значений. Нужно чтобы срабатывала 404 ошибка. Код учебный, реализую для своего проекта и тренируюсь. С уважением, Александр!

Файл Router.php

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class Router {
    
    private $routes; //массив, в котором будут храниться роуты
    
    public function __construct() {
        
        $routesPath = ROOT.'/config/routes.php'; //путь к роутам
        $this->routes = include($routesPath);
        
    }
    
    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);
                //Определить какой контроллер и метод обрабатывает запрос
                $segments = explode('/', $internalRoute);
                //Получить имя контроллера
                $controllerName = ucfirst(array_shift($segments)).'Controller';
                //Получить имя метода
                $actionName = 'action'.ucfirst(array_shift($segments));
                //Подключить файл класса контроллера
                $controllerFile = ROOT . '/controllers/' . $controllerName . '.php';
                if (file_exists($controllerFile)) {
                    include_once($controllerFile);
                }
                //Создать объект, вызвать метод
                $parameters = $segments;
                $controllerObject = new $controllerName;
                $result = call_user_func_array(array($controllerObject, $actionName), $parameters);
                if($result != null) {
                    break;
                }
            }
        }
    }
}
Часть кода из routes.php

PHP
1
2
3
4
5
6
7
8
9
return array(
    // Товар:
    'product/([-a-z]+)' => 'product/view/$1', // actionView в ProductController
    // Каталог:
    'catalog' => 'catalog/index', // actionIndex в CatalogController
    // Категория товаров:
    '([0-9]+)/page-([0-9]+)' => 'catalog/category/$1/$2', // actionCategory в CatalogController   
    'category/([-a-z]+)' => 'catalog/category/$1', // actionCategory в CatalogController
);
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
05.05.2018, 01:19
Ответы с готовыми решениями:

Как сделать ошибку 404 в .htaccess при mod_rewrite
Всем доброго времени суток. Есть следующий код RewriteRule ^administrator$ /admin.php Он преобразовывает admin.php administrator....

Не получается сделать ошибку 404
В общем, есть сайт. php структура у него на картинке ps.jpg. Но не знаю, как сделать страницу 404, у которой будет такая же структура, но...

Как вызвать ошибку 404?
почитал в интернете все говорят так: include ($_SERVER."/404.php"); die; а в документе: <?php header ("HTTP/1.0 404...

14
14 / 13 / 10
Регистрация: 01.04.2018
Сообщений: 106
05.05.2018, 04:11
Попробуйте в начале файла "Router.php", после строчки <?php, добавить такой код:
PHP
1
2
3
4
if (basename($_SERVER['SCRIPT_FILENAME']) == basename(__FILE__)) {
    header('Location: error404.php');
    exit;
}
Вместо basename(__FILE__) можно использовать 'Router.php'.
error404.php - файл, который выводит ошибку 404.

Можно даже так (первая строка условия):
PHP
1
if ($_SERVER['SCRIPT_FILENAME'] == __FILE__) {
Это на случай, если названия файлов в разных папках могут повторяться.
0
377 / 319 / 73
Регистрация: 15.09.2017
Сообщений: 1,436
05.05.2018, 13:05
cahe4a, чтобы ответить на ваш вопрос, нужно знать как в принципе у вас работает обработка ошибок. Например, в маршрутизаторе при неудачном обходе всех маршрутов тоже должна выводиться страница ошибки 404, но в представленном коде я этого не вижу. Вместо того чтобы воспроизводить посредственный код из сети, лучше бы сели и хорошо продумали логику каркаса вашего приложения.
0
2 / 2 / 0
Регистрация: 19.08.2017
Сообщений: 50
05.05.2018, 14:19  [ТС]
Не могу догнать, что именно мне нужно сравнить в этом коде, чтобы вывести файл ошибки?

PHP
1
2
3
4
if (basename($_SERVER['SCRIPT_FILENAME']) == basename(__FILE__)) {
    header('Location: error404.php');
    exit;
}
0
377 / 319 / 73
Регистрация: 15.09.2017
Сообщений: 1,436
05.05.2018, 14:27
cahe4a, и не "догоните". Slash Mix что-то не то написал.
0
05.05.2018, 14:56

Не по теме:

Извиняюсь. Я действительно "что то не то" написал... Я неправильно понял вашу задачу... Понял, только что, когда перечитал первый пост еще раз.
Торопился ответить и...

0
Особый статус
 Аватар для FloppyDisc
623 / 221 / 164
Регистрация: 18.11.2015
Сообщений: 1,086
05.05.2018, 15:02
как вариант в массив роутов добавить последним элементом
PHP
1
'/([-a-z]+)' => 'error/notFound'
но это доставит много хлопот, а так наверное после условия
PHP
1
2
3
4
5
if (preg_match("~^$uriPattern$~", $uri)) {
 
} else {
 
...not found
если совпадения не найдены, вызвать контроллер ErrorController с действием actionNotFound().

Но перед этим возможно было бы полезно сделать еще один поиск без роутов - чисто по названию контроллера и действия и проверять существует ли такой контроллер, если нет то уже 404
0
377 / 319 / 73
Регистрация: 15.09.2017
Сообщений: 1,436
05.05.2018, 15:13
FloppyDisc, он хочет генерировать ошибку при неверном параметре.
0
Особый статус
 Аватар для FloppyDisc
623 / 221 / 164
Регистрация: 18.11.2015
Сообщений: 1,086
05.05.2018, 15:25
Phantom-84, упс, да и точно, ИМХО, но ошибки в неверных параметрах при таком роутинге лучше отслеживать на уровне самого действия, вручную, так сказать.

Если говорить о категориях простым языком, то сделать запрос к БД и в зависимости от результата уже генерировать ответ, скажем:
PHP
1
2
3
4
5
6
7
8
9
10
public function actionCategory($categoryName)
{
   $category = Category::find()->where(['name' => $categoryName])->one();
   if(!$category){
      throw new NotFoundHttpException('Данная категория не найдена или ее не существует!');
   }
 
   ... other logic
   ... rendering view page with result 
}
опять же, если я правильно понял вопрос
0
2 / 2 / 0
Регистрация: 19.08.2017
Сообщений: 50
05.05.2018, 18:03  [ТС]
В общем нужно прописать action в контроллере для вывода ошибки, а в routes.php прописать чтобы любая ссылка, которая отличается от нужных, вела в этот action, верно?

А как можно прописывать в routes.php регулярки, чтобы любые значения кроме указанных ниже выводило на ошибку? Не могу сообразить. И например если ссылка будет site/product/errorlinkk то она все равно пройдет через роутер и выведет раздел продукт - только с пустыми значениями.
PHP
1
2
3
4
        // Товар:
    'product/([-a-z]+)' => 'product/view/$1', // actionView в ProductController
    // Категория товаров:
    'category/([-a-z]+)' => 'catalog/category/$1', // actionCategory в CatalogController
0
Особый статус
 Аватар для FloppyDisc
623 / 221 / 164
Регистрация: 18.11.2015
Сообщений: 1,086
05.05.2018, 19:36
Цитата Сообщение от cahe4a Посмотреть сообщение
которая отличается от нужных, вела в этот action, верно?
Это конечно не есть хорошо, но если не критично

Цитата Сообщение от cahe4a Посмотреть сообщение
А как можно прописывать в routes.php регулярки, чтобы любые значения кроме указанных ниже выводило на ошибку?
Наверное как-то так (.+)

Цитата Сообщение от cahe4a Посмотреть сообщение
И например если ссылка будет site/product/errorlinkk то она все равно пройдет через роутер и выведет раздел продукт - только с пустыми значениями.
Вот этого я не понимаю, у вас очень странные роуты, вот куда должна обращаться такая ссылка: site/product/errorlinkk
site - это контроллер, product - действие, errorlinkk - параметр? Или product - контроллер, а вместо errorlinkk - любое действие? Не ясно совсем.

Цитата Сообщение от cahe4a Посмотреть сообщение
то она все равно пройдет через роутер и выведет раздел продукт
Выведет, ведь регулярки соответствуют шаблону, вам нужно поменять на типа такое: product/view/([-a-z]+), либо оставить как есть и вводить ошибку в actionView(), что нет параметров и т.д
0
2 / 2 / 0
Регистрация: 19.08.2017
Сообщений: 50
08.05.2018, 01:23  [ТС]
Не могу догнать к сожалению. Не хватает источников информации и примеров кода. Спасибо за ответы!

Добавлено через 23 часа 57 минут
Вот этот контроллер только работает, ответ сервера 404. Однако когда пытаюсь подключить файл header('Location:test4/views/error/404.php'); вместо die - код ответа сервера 302


PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
class ErrorController
{
    
    public function actionMistake()
    {
 
        header('HTTP/1.1 404 Not Found');
        die ('404 Not Found');
        
 
    }
 
}
0
 Аватар для Lazy_Den
3325 / 2845 / 1423
Регистрация: 15.01.2014
Сообщений: 6,170
08.05.2018, 01:28
cahe4a, может http_response_code поможет?
0
2 / 2 / 0
Регистрация: 19.08.2017
Сообщений: 50
08.05.2018, 01:38  [ТС]
Все равно HTTP/1.1 302 Found - ответ


PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class ErrorController
{
 
    public function actionMistake()
    {
        // Получает текущий код ответа по умолчанию
        var_dump(http_response_code()); // int(200)
 
// Устанавливает заданный код ответа
        http_response_code(404);
 
// Получает новый код ответа
        var_dump(http_response_code()); // int(404)
        
        header('HTTP/1.1 404 Not Found');
        header('Location:http://accounts-market.ru/views/error/404.php');
 
 
    }
 
}
0
377 / 319 / 73
Регистрация: 15.09.2017
Сообщений: 1,436
08.05.2018, 12:46
Location плохо сочетается со статусом 404.

И вы действительно хотите принудить клиент напрямую обращаться к представлению (шаблону представления)?

Добавлено через 4 минуты
И header не вместо die обычно вставляется, а перед die.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.05.2018, 12:46
Помогаю со студенческими работами здесь

Как правильно обрабатывать 404-ю ошибку?
Подскажите, как правильно обрабатывать 404-ю ошибку. Сейчас сделано следующее: &lt;customErrors mode=&quot;RemoteOnly&quot;...

Как правильно настроить 404 ошибку?
Здравствуйте уважаемые форумчане. Не могу правильно настроить 404 ошибку Урлы строятся следующим образом: ...

Как устранить т.н. ложную ошибку 404?
Google https://support.google.com/webmasters/answer/2409443?ctx=MCE&amp;ctx=S4 теперь сообщает о &quot;ложной ошибке&quot;. В файле .htaccess у меня...

Как убрать ошибку 404 при переходе на существующую страницу?
Добрый день! Сегодня с утра обнаружила, что во вкладку &quot;новости&quot; (на навигационном меню) не переходит. За место нее выскакивает ошибка...

Как сделать 404
Здравствуйте, как сделать страницу 404 ошибки? Дело в том, что я переехал на новый хост, и там есть эта функция(старый был бесплатным,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru