Vladchucha
Добрый день,
решил переделать сайт на ЧПУ и пришел тупик,
возможно не понимаю что-то фундаментальное.
Стал пробовать, по простому сначала.
Супер — работает. Но когда стал делать вызов с GET
параметрами, то ….ничего не понимай.
Далее текстКод (Text):
ini_set(‘display_errors’, 1); ini_set(‘display_startup_errors’, 1); error_reporting(E_ALL); $router=»»; if (isset($_GET[‘router’])) { $router = trim($_GET[‘router’]); $url= explode(«https://php.ru/», $router); } else $url=»»; echo_r($url); if ($url==») { include ‘../app/main.php’; } else { $myfile=»../app/».$url[0].’.php’; if (file_exists($myfile)) { include ‘../app/’.$url[0].’.php’; echo ‘../app/old-world.php’; } else { include ‘404.html’; header(«HTTP/1.0 404 Not Found » ); } }Это работает, скрипт с формой корректно передает по POST данные.
Теперь хочу обработать с параметрами для поиска в БД.
/app/main.php/id/5/category/44.
И вот здесь ступор.
В лоб не получается, то есть если я это преобразую (неважно как)
в /app/main.php?id=5&category=44,
то не могу include сделать, система не найдет такого файла.
КАК вызывыется в этом случае скрипт не понимаю.
Допустим есть движок с контроллерами, машрутизаторами….
все равно в конечном итоге надо, чтобы скрипт начал выполняться с полученными параметрами.
Тупо проинклудить не получается.
Как это сделать, ну для начала максимально по-простому?
Файл .htaccsess.Код (CSS):
AddDefaultCharset utf8 RewriteEngine On DirectoryIndex index.php #RewriteCond %{REQUEST_FILENAME} !-f #RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?router=$1 [L,QSA]Спасибо.
don.bidon
ничего непонятно, но очень интересно
ADSoft
подход в принципе верный.. реализация не очень )))
1. Единая точка входа — index.php?router=$1 у вас есть
2. в ней нужно разбирать урл, всегда, любой
3. после вашего кодаКод (Text):
if (isset($_GET[‘router’])) { $router = trim($_GET[‘router’]); $url= explode(«https://php.ru/», $router); }в $url — путь разбитый по / … то есть если вы передаете как /news/5/24 у вас будет массив [‘news’,5,24]
а уж сам роутер пусть решает чего там как инклудить, как и куда параметры эти передавать
miketomlin
Лучше бы и не начинали. Перенос пути в GET-параметр, в PATH_INFO – это прошлый век. Разбирайте прямо $_SERVER[‘REQUEST_URI’]: Как сделать единую точку входа с ЧПУ?
— Добавлено —Нафига для главной пускать отдельную ветку? Ну, пусть будет файл называться .php – просто и элегантно.
Дыра. В GET-параметре вам легко могут подсунуть ../ и вывести из каталога app
— Добавлено —Это WP-шная хрень. В норм. движках правило перенаправления во фронт работает в том числе и для главной.
— Добавлено —
Пустая строка в .htaccess явно не на том месте. Условия относятся к тому правилу, которое ниже, а не выше
— Добавлено —Естественно. Из фронта/роутера параметры передаются обычным для пыха путем: в переменных, в параметрах ф-ции/метода и т.п. Не надо при инклуде пытаться юзать GET-параметры, PATH_INFO
— Добавлено —
У тебя в $url[N] будут параметры (необработанные). В последний и не только может затесаться строка параметров, т.к. ты ее не отделил перед разделением пути на компоненты.
— Добавлено —
См. вторую демку в моей статье
miketomlin
Тут попутал, сорри. Это нужно будет учитывать, если будешь использовать $_SERVER[‘REQUEST_URI’].
Vladchucha
THANKS very much,
1. С безопасностю, да, надо ряд дырок закрывать.
2. Вроде ступор (частично) прошел, вечером виски, может совсем уйдет.
3. Посмотрел пару видео умных людей.
Один говорит —
www.site.com/ и www.site.com
мы так обработаем, что в обоих случаях корректно
на главную страницу попадем и все доворльны.
Другой говорит— так очень плохо, так как
роботы воспримут это как полное дублирование страниц и вызовут полицию
Что верно/не верно?
miketomlin
Это один и тот же адрес, а вот глубже, да, будут дубли. Если смотрели мои демки, там множественные и трэйлинг слеши автоматом корректируются, многое во фронте (этот фильтр есть в статье, ссылку на которую я давал).
— Добавлено —
Корректировка трэйлинг слешей отдана на откуп серверу (.htaccess и т.п.), во фронте они просто обрезаются (см. преобразование в «нормализованный» путь, который в $px сохраняется).
MouseZver
@Vladchucha, привет.
Начнем с первого байта строки.PHP:
Второй аргумент принимает только строковое значение, а ты присваиваешь значение с типом int.
В результате, правильно делается так:PHP:
$ini_set = [ ‘error_reporting’ => E_ALL, // ругаться на всё интерпретатору php ‘html_errors’ => 1, // хрень, которая в браузере выделяет жирным текстом основу ошибки ‘log_errors’ => 1, // 0 — использ. system журнал | 1 — использ. пользов. журнал для сохранения ошибок ‘log_errors_max_len’ => 0, // 0 — безлимит | 1024 — байт, максимальный размер содержимого об ошибки ‘ignore_repeated_errors’ => 0, // загуглить, долго объяснять ‘ignore_repeated_source’ => 0, // загуглить, долго объяснять ‘error_log’ => $_SERVER[‘DOCUMENT_ROOT’] . ‘/logs/Debug.log’, // лог файл (пользовательский журнал), куда так же летят все ошибки ‘display_errors’ => ‘on’, // on — включить | off — выкл. Не вывод, а ПОКАЗАТЬ ошибки юзеру ‘display_startup_errors’ => 1, // Презерватив для display_errors. Именно эта опция должна быть отключена на боевом сайте, чтоб ошибки юзеры не видели. ‘date.timezone’ => ‘Europe/Moscow’, // Временная зона для всего, кроме БД — загуглить ‘default_charset’ => ‘UTF-8’, // мы должны любить UTF-8 везде ]; foreach ( $ini_set AS $option => $value ) { }Cовет — перед началом любого твоего скрипта, начинай со строки:
PHP:
<?php declare ( strict_types = 1 ); /* …code… */и ты автоматически отсеиваешься от всего сброда говнокодеров.
https://www.php.net/manual/ru/language.types.declarations.php#language.types.declarations.strict
Строгая типизация и повышение токсичности интерпретатору (ошибки) для, например — как было с твоим ini_set во втором аргументе.
——Это чейт за функция в php ? print_r ? или пользовательская…
——
Роутер… больная тема как с Авторизацией/Идентификацией пользователя.
Начнем с файла .htaccsessАбсолютно верно и добавлю +15копеек:
Такой метод единой точки не просто прошлый век, он тупо убивает принцип $_GET параметров и у нас остается лишь одинокий router, вместо положенных атрибутов, который пользователь к нам прислал.Поэтому, идем к Ларавельке и просто тырим у нее htaccess
——
Оформление кода роутера.
Хм..
Да как хочешь вот реально — как хотелка пожелает.
Хочешь максимально по простому — пили проверки как ты и делал.
Хочешь организованно со всякими плюшками — используй composer + куча всяких фаст роутеров в github.
Но… имей ввиду, что $_SERVER[‘REQUEST_URI’] сырой и нуждается в тотальной мясорубке.PHP:
$uri = $_SERVER[‘REQUEST_URI’]; $routing = [ «https://php.ru/» => ‘index’, ‘/test’ => ‘test’, ‘/test/(d+)’ => ‘test’, // /test/54 ]; $action = ‘404’; foreach ( $routing AS $route => $name ) { { $action = $name; break; } } require __DIR__ . «/resource/{$action}.php»;Помню давным-давно @igordata постил свою пипетку, там было наглядно и максимально упрощен роутер.
https://github.com/igordata/PinPIE/…ee634a12816140eee74/pinpie/classes/pinpie.php
Начиная с 36 по 113 строки. Довольно типичный и приближенный вариант для твоей ситуации.——
На данном этапе изучи composer php.
Единственное, ценное и нужное тебе сейчас знание, на которое грех не потратить свободное время. В итоге получаешь и единую точку автозагрузки требуемых классов, своих/чужих библиотек и не надо будет использовать по 100500 раз require к каждому файлу.
Зарегистрируйся на сайтах
https://github.com
https://packagist.org
Это все нужно будет для composer.
Скачай если нет, openserver. Через его консоль сможешь использовать его, подключать библиотеки различных разработчиков. Сможешь так же подключить FastRouter или подобные им. А в своем скрипте просто одной строкой:PHP:
<?php require ‘vendor/autoload.php’;——
После, через некоторое время захочется узнать, как устроен фреймворк, каков его скелет, что запускается, когда сессия стартует, идентификация пользователя, в каком ввиде контент отдавать юзеру / кому еще, какова логика последовательных действий в кратком понимании. Сам лично чуть ли не переписал процедуру обработки данных. И после сверки со Symfony, задался вопросом — а нахрена я буду тратить время, там логика идентична. Бери и пользуйся.
PHP:
require ‘vendor/autoload.php’; // загрузка конфига, подготовка апи (инструменты фрейма) к использованию // дебаг, прочее, ini_set // сессия // GET POST COOKIE SERVER в ооп стиль со всякими вкусняшками // SymfonyComponentHttpFoundationRequest :: createFromGlobals(); // Идентификация юзера // еще что-то кучу важных операций // роутер // логика кода — что надо юзеру // SymfonyComponentHttpFoundationResponse // конецhttps://symfony.com/doc/current/components/http_foundation.html
Но тебе эта ссылка сейчас ничего не скажет / покажет
miketomlin
Флаг QSA помогает. Там основная проблема – это мегадубль /path vs /[index.php]?router=path, с которым можно бороться до [сами придумайте слово]
Vladchucha
Спасибо за кучу информации.
Потихоньку (время свободного мало) буду делать/разбираться
1. echo_r($url); Это пользовательская, просто вывод с <pre>.
2. Несколько лет назад прочел книгу немецкого автора «PHP: quick & dirty».
Предназначена для полуновичков и если разработчик
а. один все делает
б. Время мало и/или заказчик с топором над душой стоит.
Сейчас понимаю, что многое там спорно, подход не совсем корректный.
В то же время для одиночки ( то есть я не в коллективе программистов)
и практически с нуля, единственный источник тогда нашел,
где описывается процесс создания сайта, начиная со структуры каталогов,
какие файлы вообще нужны, взаимосвязи и пр.
Мне кажется, что и сейчас такких книг(статей) практически нет.
Вот, с вашей помощью буду дальше разбираться,
на пенсии напишу правильную книжку.
Evgenii_web
книг много но в основном они поверхностные и когда получаешь проблему нет возможности решить ее, книги пишутся плохо. Русские книги можно не покупать, авторы в России отдалены от проблем создания сайтов их код php живет своей жизнью DDD. Иностранные толковые книги переводятся с опозданием лет так на 5 ито если переведут. Научная толковая литература разбирается моментально. Сегодня купил последнюю книку по созданию каталога от Ларри Ульман по всей рашке их не было в Таганроге последнюю урвал. Код прост, процедурный минимум функции и ооп. Буду писать каталог свой с осенью.