Форум программистов, компьютерный форум, киберфорум
PHP для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.64/28: Рейтинг темы: голосов - 28, средняя оценка - 4.64
32 / 29 / 12
Регистрация: 04.03.2013
Сообщений: 897

Роуминг PHP: Как сделать редиректы и отдавать код ответа сервера?

16.11.2022, 17:32. Показов 7581. Ответов 90

Студворк — интернет-сервис помощи студентам
Здравствуйте!
Простите, если не сюда пишу.

Не силен в PHP.
Пишу роутинг.
Работаю на OpenServer.
index.php:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
 
// FRONT COTROLLER
 
// 1. Общие настройки
 
ini_set('display_errors', 1);
error_reporting(E_ALL);
 
// 2. Подключение файлов системы
 
define('ROOT', dirname(__FILE__));
require_once(ROOT.'/components/Router.php');
require_once(ROOT.'/components/Db.php');
 
// 3. Установка соединения с БД
 
 
// 4. Вызов Router
 
$router = new Router();
$router->run();
htaccess:
PHP
1
2
3
4
5
6
7
8
AddDefaultCharset utf-8
 
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?route=$1 [L]
routes.php:
PHP
1
2
3
4
5
<?php
return array(
'news/([0-9]+)' => 'news/view/$1',
'news' => 'news/index', // actionIndex in NewsController
);
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
<?php
 
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 = array_shift($segments).'Controller';
                $controllerName = ucfirst($controllerName);//первая буква строки заглавная
                $actionName = 'action'.ucfirst((array_shift($segments)));
 
                    $parameters = $segments;
 
                //подключить файл класса-контроллера
                $controllerFile = ROOT . '/controles/' .
                    $controllerName . '.php';
                    
                if (file_exists ($controllerFile)) {
                    include_once ($controllerFile);
                }
                
                $controllerObject = new $controllerName;
                
                $result = call_user_func_array (array($controllerObject, $actionName), $parameters);
                
                if ($result != null) {
                    break;
                }
                }
            }
        }
        }
NewsController.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
<?php
 
include_once ROOT. '/models/News.php';
 
class NewsController {
    public function actionIndex()
        {
            $newsList = array();
            $newsList = News::getNewsList();
            
            require_once(ROOT. '/views/news/index.php');
            
            return true;
        }
    public function actionView($id)
    {
        if ($id) {
            $newsItem = News::getNewsItembyId($id);
            
            echo '<pre>';
            print_r($newsItem);
            echo '</pre>';
            
            echo 'actionView';
        }
        return true;
    }
        
}
News.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
<?php
 
class News
{
        public static function getNewsItemById ($id)
        {
            $id = intval($id);
            
            if ($id) {
            $db = Db::getConnection();
 
            $result = $db->query('SELECT * FROM news WHERE id=' . $id);
            
            $result ->setFetchMode(PDO::FETCH_ASSOC);
            
            $newsItem = $result->fetch();
            
            return $newsItem;
            }
        }
        
        public static function getNewsList ()
        {
            $db = Db::getConnection();
            
            $newsList = array();
            
            $result = $db->query('SELECT id, title, date, short_content '
                . 'FROM news '
                . 'ORDER BY date DESC '
                . 'LIMIT 10 '); //количество выводимых превью новостей
            $i = 0;
            while($row = $result->fetch()) {
                $newsList [$i]['id'] = $row ['id'];
                $newsList [$i]['title'] = $row ['title'];
                $newsList [$i]['date'] = $row ['date'];
                $newsList [$i]['short_content'] = $row ['short_content'];
                $i++;
            }
            return $newsList;
        }
}
У меня несколько вопросов.
Сейчас открывается:
  • domain.ru/news
  • domain.ru/news/
  1. Как сделать, чтобы открывался ТОЛЬКО без слэша в конце?
Нужен вид domain.ru/news
Просто domain.ru открывается без слэша. Если слэш поставить, то перекидывает на domain.ru (т.е. без слэша).
  1. Как сделать адрес полного текста статьи не domain.ru/news/123, а domain.ru/news/horoshie-novosti?
Расширение .php в конце не должно быть.
  1. Как передавать код ответа сервера (404, 301 и т.д.)?

Буду благодарен советам и помощи.
Прошу сильно не пинать
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.11.2022, 17:32
Ответы с готовыми решениями:

Как получить код ответа сервера?
Есть какая нибудь функция, чтобы узнать код ответа? Типа даёшь урл, а он тебе возвращает 200, 404 и т.п.?

Как получить код ответа сервера?
Нужно получить заголовок страницы. Что-то вроде: -задаем url страницы - получаем &quot;200&quot; или &quot;301&quot; или...

Как с NodeJs или JavaScript получить код ответа сервера?
Есть какая нибудь функция, чтобы узнать код ответа? Типа даёшь урл, а он тебе возвращает 200, 404 и т.п.?

90
1460 / 1013 / 232
Регистрация: 01.10.2018
Сообщений: 3,938
22.12.2022, 18:47
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от iiwanc Посмотреть сообщение
Получается, необходимо описать класс NotFoundException?
Да. И перехват исключения тоже нужно прописать. Лучше вне контроллера. Можно перехватывать все исключения, используя базовый тип Exception:
PHP
1
2
3
4
5
try
{
    // ...
}
catch (Exception $e) { error($e->getCode()); }
Добавлено через 3 минуты
Для генерации тоже можно использовать базовый тип, тогда другие классы описывать не нужно:
PHP
1
throw new Exception('Not Found', 404);
Добавлено через 2 минуты
Теории DDD пока можно не касаться Тем более что есть и другие.

Добавлено через 6 минут
Цитата Сообщение от estic Посмотреть сообщение
error($e->getCode());
"Расшифровку" ошибки (текстовое сообщение) тоже можно получать от источника исключения (из $e->getMessage()).
0
 Аватар для sad67man
2605 / 1509 / 689
Регистрация: 23.08.2015
Сообщений: 3,841
22.12.2022, 19:00
Цитата Сообщение от estic Посмотреть сообщение
Теории DDD пока можно не касаться Тем более что есть и другие.
Просто мне не нравятся флаги). И я попытался это хоть как-то обосновать)

В моей голове слои существуют всегда, их может быть больше или меньше, просто они могут быть не выражены явно в коде)
И если мы берем какую-нибудь класс-службу, то необязательно использовать интерфейс, но мы должны проектировать таким образом, что он как-будто реализует некий интерфейс. Т. е. для меня важно, чтоб внутренняя логика не вытекала наружу.

Поэтому я бы не советовал использовать флаги в принципе. Либо с осторожностью и в очень редких случаях.
0
1460 / 1013 / 232
Регистрация: 01.10.2018
Сообщений: 3,938
22.12.2022, 19:54
sad67man, насчет "хоть как-то" я понял. Как будто в интерфейсе нельзя использовать флаги или не может быть "двойственной" функции (метода)...

Добавлено через 6 минут
Я даже в прикладные API люблю добавлять "двойственные" функции. Чтобы пользователь прошел небольшой квест, прежде чем понять всю их мощь
0
 Аватар для sad67man
2605 / 1509 / 689
Регистрация: 23.08.2015
Сообщений: 3,841
22.12.2022, 20:47
Цитата Сообщение от estic Посмотреть сообщение
Как будто в интерфейсе нельзя использовать флаги или не может быть "двойственной" функции (метода)...
Получается, что метод делает одно, но если вы передали флаг = true, то нечто другое. По мне так двойственности быть не должно. Лучше разделить на 2 метода либо использовать другие способы.

Для интерфейса проблема не в самом флаге, а как я писал ранее в сигнатуре. Получается что метод всегда может вернуть null, а это значит что мы не можем полагаться на передаваемый флаг и обязаны делать проверку....

Интерфейс служит для инверсии зависимости, и как правило он принадлежит тому классу, который его использует, а не тот который его реализует. И тот кто его использует по сути и диктует правила, какие параметры будут передаваться и что должно вернуться. С этой точки зрения для него нет смысла добавлять некие бессмысленные параметры.
0
1460 / 1013 / 232
Регистрация: 01.10.2018
Сообщений: 3,938
22.12.2022, 23:36
Цитата Сообщение от sad67man Посмотреть сообщение
Получается, что метод делает одно, но если вы передали флаг = true, то нечто другое.
В том примере я предлагал неявно передавать true (в значении "генерировать ошибку"), но не суть.

Цитата Сообщение от sad67man Посмотреть сообщение
Получается что метод всегда может вернуть null, а это значит что мы не можем полагаться на передаваемый флаг и обязаны делать проверку...
Если метод возвращает null вопреки интерфейсу, то это ошибочная реализация (интерфейс в этом не виноват). Если флаг приходит "сверху", то и результат обычно передается "наверх" без проверки.
0
32 / 29 / 12
Регистрация: 04.03.2013
Сообщений: 897
28.12.2022, 15:29  [ТС]
estic, решил здесь написать, т.к. я все еще допиливаю роутинг
В файле Router.php прописал:
PHP
1
2
3
4
5
6
if (preg_match("#\b$uriPattern\b#i", $uri)){
   echo 'test';
}else {
   http_response_code(404);
   echo 'NEtest';
}
В файле контроллера:
PHP
1
2
3
4
5
6
7
8
9
10
public function actionView($ssylka)
{
   if ($ssylka) {
      $newsItem = News::getNewsItembyId($ssylka);
      if(! $newsItem = News::getNewsItembyId($ssylka)) {
         http_response_code(404);
         echo 'Новость не найдена';
}
}
}
В ссылках такого вида хорошо отрабатывает: domain.ru/news/horoshie-novosti
Если "пользователь" допишет адресную строк (пример: domain.ru/news/horoshie-novosti/user), то откроется белая страница и нет кода 404.

Как в таком случае вывести 404?
0
1460 / 1013 / 232
Регистрация: 01.10.2018
Сообщений: 3,938
28.12.2022, 16:19
Цитата Сообщение от iiwanc Посмотреть сообщение
В ссылках такого вида хорошо отрабатывает: domain.ru/news/horoshie-novosti
Я вам в другой теме написал, что \b не заменяет в полной мере ^ и $ (и даже один контрпример привел: /bad/news/1).

Добавлено через 2 минуты
Цитата Сообщение от iiwanc Посмотреть сообщение
if ($ssylka) {


Цитата Сообщение от iiwanc Посмотреть сообщение
$newsItem = News::getNewsItembyId($ssylka);
if(! $newsItem = News::getNewsItembyId($ssylka))


Добавлено через 6 минут
По первому "почесыванию": если вы хотите проверить поступающий идентификатор на пустоту строки, делайте это явно, т.к. в PHP много чего приводится к bool false. И реакцию на некорректное значение нужно должным образом оформить.
PHP
1
if (strlen($id) == 0) fail(); // или strlen($id) > 0 or fail(); или strlen($id) == 0 and fail();
null, кстати, тоже приводится к пустой строке. Если для вас важно это различать, можно использовать $id === '' ($id !== '').
1
32 / 29 / 12
Регистрация: 04.03.2013
Сообщений: 897
28.12.2022, 16:24  [ТС]
Большое спасибо за разъяснения и терпение.
Многое стало понятно
0
1460 / 1013 / 232
Регистрация: 01.10.2018
Сообщений: 3,938
28.12.2022, 16:44
Цитата Сообщение от iiwanc Посмотреть сообщение
Большое спасибо за разъяснения и терпение.
Не за что. Хотя "спасибки" получать всегда приятно

Процитированное мной первое условие не понятно еще и в том смысле, что вы же вроде бы разделяли на уровне маршрутов (маршрутизатора) обработку /news и /news/1 (вместо 1 может быть и символьный идентификатор, просто я смотрю на начало темы). "+" в регулярном выражении означает, что должен быть хотя бы один символ (в идентификаторе).

Добавлено через 4 минуты
Кстати, у числовых идентификаторов, состоящих только из цифр, еще могут быть подобные дубли: 01 Нужно использовать или более строгий шаблон (чтобы в начале числа не мог появиться ноль), или какие-то специальные техники.

Добавлено через 1 минуту
В моих сайтах с этим все в порядке: hyde.pageshop.ru/news/01
1
32 / 29 / 12
Регистрация: 04.03.2013
Сообщений: 897
29.12.2022, 13:18  [ТС]
estic, наконец-то я столкнулся с подключением стилей
Ранее в своих HTML файлах делал так:
HTML5
1
<link rel="stylesheet" type="text/css" href="style/style.css">
А теперь как нужно делать?
В интернете не смог найти понятную для себя информацию
0
1460 / 1013 / 232
Регистрация: 01.10.2018
Сообщений: 3,938
29.12.2022, 15:56
Цитата Сообщение от iiwanc Посмотреть сообщение
А теперь как нужно делать?
Это к маршрутизации не относится

Я вам давал ссылку на шаблон. Или baseurl используете (конфигурационный параметр приложения или обычную константу), или просто на ветвь текущего хоста со статическими файлами ссылаетесь: /assets/... - обратите внимание на первый слэш, это важно.

Добавлено через 3 минуты
Проблема с расположением файлов относительно index.php

Добавлено через 5 минут
Если боитесь случайно повторно задействовать эту ветвь для динамического содержимого, можно сразу создать какой-нибудь блокирующий маршрут для /assets/...

Добавлено через 4 минуты
Лишних каталогов в корне лучше не создавать, чтобы меньше "блокировать" и провоцировать подобные потенциальные конфликты. В моих CMS, если статические файлы размещаются на том же хосте, обычно используются assets (или аналог), images для графических файлов, относящихся к основному содержимому, и files для всех прочих типов файлов, относящихся к основному содержимому. По аналогии с images в общем-то можно создавать videos и т.п. Если используется файловый кэш, в корне может быть и cache, но не обязательно (если кэш читает непосредственно код приложения, он вполне может это сделать из каталога вне корня).

На блокирующие маршруты при необходимости можно "навесить" и полезную функциональность, например генерацию статических файлов "по первому запросу", вывод "несуществующих" файлов и т.п. Примером вывода "несуществующего" файла может быть вывод atom.xml на демонстрационном сайте, который я показывал: hyde.pageshop.ru/atom.xml (код вывода содержимого этого файла есть в упомянутом шаблоне). Кстати, для файлов, расположенных непосредственно в корневом каталоге, тоже могут понадобиться блокирующие маршруты, если вы боитесь потери вывода одноименных динамических страниц из-за приоритета статических файлов.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
29.12.2022, 15:56

Как узнать статус код ответа сервера WebRequest и WebResponse?
Здрасте! Такой вопросец нагрянул, надо написать функцию обращения к серверу и получения ответа, но если статус код не 200, а например 404...

Как получить и вывести код ответа сервера при запросах по протоколу HTTP?
Всем привет! Cкажите, плиз, как получить и вывести код ответа сервера при запросах по протоколу HTTP на языке программирования HTML,...

Как отдавать файлы с сервера по запросу?
Здравствуйте! Непосредственно к вопросу: я научился загружать файлы на сервер через POST запрос достаю через request.FILES и...

Парсинг ответа от php сервера
как привести строку вида object(stdClass)#2 (1) { =&gt; object(stdClass)#3 (1) { =&gt; array(42) { =&gt; object(stdClass)#4 (2) { =&gt; string(0)...

Код ответа от сервера
В двух словах нужно на C# сделалать прогу для анализа битых ссылок. Для уточнения битые ссылки будут проверяться только для скачивания...


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

Или воспользуйтесь поиском по форуму:
91
Ответ Создать тему
Новые блоги и статьи
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru