Настраиваю ссылки хочу привести к такому виду site/язык/get/ сейчас прописано так Код (Text): RewriteRule ^rus/(.*)/$ /search.php?lang=rus&q=$1 Проблема в том что для каждого языка нужно создавать по две записи одна та что выше и вторая если get параметра нет Код (Text): RewriteRule ^rus/$ /search.php?lang=rus для 20 языков уже создаётся 40 записей а если добавить ещё один get то уже 60 Можно ли как то это упростить??? Второй вопрос На странице есть форма. При отправке данных с формы получаю ссылку вида /rus/?q=апапап а нужно /rus/апапапапа/
Зачем создавать две записи если можно в search.php проверять существование параметра и его значение. По второму вопросу: можно вообще поменять метод в форме и запрос не будет виден.
Ок начал разбираться PHP: $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); $segments = explode('/', trim($uri, '/')); //Получаем доступные языки из папки lang $get_lang_mas = scandir('lang/'); foreach ($get_lang_mas as $get_lang) { preg_match('/\w\w\w/', $get_lang, $leng); if (!empty($leng)) { $leng_mas[] = $leng; } } //сравниваем доступные языки с запрашиваемыми foreach ($leng_mas as $odin) { if($segments[0]==$odin[0]) echo 'язык определили'; } после чего у меня будет первая часть ссылки правильно думаю ? site/rus/ добавил вот так PHP: foreach ($leng_mas as $odin) { if($segments[0]==$odin[0]) $ssika[] = $segments[0]; } if (!empty($segments[1])){ $ssika[] = $segments[1]; } header("Location: https://dottorrent.ru/$ssika[0]/$ssika[1]/"); Всё заканчивается бесконечным редиректом
Какой ссылки? В смысле входящего адреса? Когда парсят путь из входящего адреса explode'ом, то первая часть – это, естественно, rus (если site – это имя хоста). У вашего парсинга есть огрехи. Непробиваемый вариант показан в этой статье: Как сделать единую точку входа с ЧПУ? И нафига цикл для проверки попадания в созданный белый список? Здесь даже ф-ция поиска в массиве – это логическая ошибка. Сделайте rus и т.п. ключами массива – можно будет использовать бинарный поиск, т.е. просто проверять наличие этого ключа. --- Добавлено --- Нафига Location? Вы про это вообще ничего не писали. Или думаете, что Location нужен для реализации роутинга? --- Добавлено --- Фишку из кода моей статьи с добавлением пустого второго компонента пути можно использовать и вам. Ее смысл в том, что потом не нужно проверять наличие этого параметра, как имени переменной. После этого можно искать просто по значению. Т.е. «тупо» искать и не найти пустой ключ. Или искать и найти
Если q – это типа параметр из формы, то меняем метод на POST и в POST-обработчике делаем редирект методом GET (можно и Get-Redirect-Get, но это реально тупо). Иначе просто action="/rus/апапапапа/" Хотя все равно должен быть Post-Redirect-Get.
Я чёт понять не могу.........Получил я два нужных мне параметра /язык/запрос/ что мне с ними дальше делать? Как отдать браузеру ? Например был некорректный запрос site.ru/язык/запрос/fgfdgdg/gdfgdfgdg/ я хочу взять нужные 2 параметра и обработать затем сказать браузеру что site.ru/язык/запрос/fgfdgdg/gdfgdfgdg/ не существует и отдать браузеру site.ru/язык/запрос/ Вот сейчас у меня идёт бесконечный редирект
Вы пытаетесь создать то, что сами не знаете как должно работать. Возьмите любую CMS и вникайте как она устроена. В результате вы должны понимать буквально весь путь от htaccess и index.php до вызовов методов контроллера. Разобрались? Время разочарований: берите другую CMS и снова разбираете, сравнивая с предыдущей. Вот тогда у вас сложится картинка и советы коллег станут приобретать смысл.
дак я и пытаюсь разобраться. Вот так придумал PHP: $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); $segments = explode('/', trim($uri, '/')); //Если пришло больше параметров чем нужно значит ошибка перенаправим на адекватную страницу if(!empty($segments[2])){ header("Location: localhost/$segments[0]/$segments[1]/", true, 301); exit(); } //Получаем доступные языки из папки lang $get_lang_mas = scandir('lang/'); foreach ($get_lang_mas as $get_lang) { preg_match('/\w\w\w/', $get_lang, $leng); //Сравниваем доступные языки с запрашиваемым если совпадает выходим из перебора if ($segments[0]==$leng[0]) { break; } else { //Запрашиваемый язык не нашли возвращаем русский по умолчанию $leng[0] = 'rus'; } } echo $leng[0];
Вот так ещё дописал PHP: $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); $segments = explode('/', trim($uri, '/.')); //Если пришло больше параметров чем нужно значит ошибка if(!empty($segments[2])){ header("Location: localhost/$segments[0]/$segments[1]/", true, 301); exit(); } //Нет запроса по этому придумаем его if(empty($segments[1])){ $input = array("Человек", "Марс", "Батистута", "Барабан", "Tank", "Баргузин", "Матрица", "Павел Мурашко"); $rand_keys = array_rand($input, 2); header('Location: localhost/'.$segments[0].'/'.$input[$rand_keys[0]].'/', true, 301); exit(); } //Нет языка редиректим на русский по умолчанию if(empty($segments[0])){ header('Location: localhost/rus/', true, 301); exit(); } //Получаем доступные языки из папки lang $get_lang_mas = scandir('lang/'); foreach ($get_lang_mas as $get_lang) { preg_match('/\w\w\w/', $get_lang, $leng); //Сравниваем доступные языки с запрашиваемым если совпадает выходим из перебора if ($segments[0]==$leng[0]) { break; } else { //Запрашиваемый язык не нашли верём русский по умолчанию $leng[0] = 'rus'; } } echo $leng[0];
ещё немного переделал PHP: //Если нет запроса то придумывать его не будем а просто покажем стартовую страницу if(empty($segments[1])){ include('main.php'); exit(); } таким образом получается структура сайта site.ru/rus/ site.ru/rus/проверка/
Ещё раз переписал ))) PHP: session_start(); $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); $segments = explode('/', trim($uri, '/.')); //Если пришло больше параметров чем нужно значит ошибка if(!empty($segments[2])){ header("Location: localhost/$segments[0]/$segments[1]/", true, 301); exit(); } //Нет запроса грузим main.php if(empty($segments[1])){ include('main.php'); exit(); } //Нет языка редиректим на русский по умолчанию if(empty($segments[0])){ header('Location: localhost/rus/', true, 301); exit(); } //если мы дошли сюда то значит всё в порядке и загрузим страницу search $_SESSION['lang'] = $segments[0]; $_SESSION['get'] = $segments[1]; include('search.php');
Вы это у нас спрашиваете? Попробуйте echo Можно и дальше пойти, т.к. сами параметры из адреса обычно не нужно выводить (по ним др. данные выбирают): PHP: <h1><?= $page['name'] ?></h1> <?= $page['content'] ?> Код (Text): INSERT INTO `site_categories` (`id`, `name`, `bits`, `module`) VALUES ('rus', 'Язык: русский', 19, 'page'); CREATE TABLE `site_rus` ( `id` varchar(26) NOT NULL, `name` tinytext NOT NULL, `content` text NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `site_rus` (`id`, `name`, `content`) VALUES ('', 'Главная', '<p>Главная</p>'), ('get', 'Внутряк', '<p>Внутряк</p>'); В итоге: g09.ru/rus g09.ru/rus/get --- Добавлено --- Лучше отдать 404-ую без редиректа. Корректировку редиректом обычно делают для опечаток в адресе или для ранее существовавших страниц, траф на которые уместно направить на что-то другое. --- Добавлено --- Но если сильно хоЦА, пишите соотв. логику.
Например, я могу перевести используемый фронт-контроллер в режим «ручного анализа второго параметра» и добавить такой контроллер: PHP: if (count($pa = explode('/', $p1, 2)) < 2) { $page = findOrFail(table($p0), $pa[0]); } else { redirect('/'.$p0.'/'.$pa[0]); } У меня $p0 == 'rus' && $p1 == 'запрос' (или 'запрос/fgfdgdg/gdfgdfgdg'). В реале вместо $p0 лучше использовать спец. переменную, значение которой выбрано из БД, а не получено из адреса.
Я вот про это..... Это похоже на единую точку входа или я всё же что ещё не совсем понимаю Понятно что с переменными можно дальше уже работать запросы в базу или ещё чего
Помогите распознать слеш PHP: $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); $segments = explode('/', trim($uri, '/.')); //Если пришло больше параметров чем нужно значит ошибка if(!empty($segments[0])){ header("Location: /rus/", true, 301); } else { include('main.php'); } При таком подходе я не могу проверить есть ли слеш на конце так как создавая массив слешы удаляются и сайт доступен как по site/rus так и site/rus/
Парни, парни, парни ещё раз переписал у кого будут замечания напишите пожалуйста PHP: ob_start(); // Проверка полного УРЛ $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); // Удаляем всё ненужное из УРЛ $clean_uri = str_replace(array('//', '\\', '\'', '"', ' '), '', $uri); // Проверим чем заканчивается УРЛ слеш там или нет $slesh = substr($clean_uri, -1); if($slesh!=='/'){ header('Location: '.$_SERVER['REQUEST_URI'].'/');// На конце не слеш редиректим со слешем } //Переходим к обработке принимаемых данных создадим массив // Обрежем километровые запросы они нам не к чему $short_url = substr($clean_uri, 0, 200); $segments = explode('/', trim($short_url, '/'));// создаём массив из УРЛ строки //Проверяем на наличие языка если его нет редиректим на язык по умолчанию if(empty($segments[0])){ header('Location: '.$_SERVER['REQUEST_URI'].'/rus/'); } else { //Язык есть и УРЛ меня устраивает поэтому с ним больше делать нечего и покажем то за чем пришли страницу include('main.php'); } ob_clean(); ob_end_flush();
Все плохо Начиная с первой строчки. Расписывать уже в лом, т.к. обратной реакции ноль. --- Добавлено --- Вместо того чтобы думать об «Обрежем километровые запросы они нам не к чему», лучше бы вспомнили, что в REQUEST_URI может быть не только путь, поэтому лепить к этому трэйлинг слеш – затея так себе Про доп. логику, не относящуюся к делу, когда уже намечен редирект, промолчу --- Добавлено --- P.S. Фронт может обрабатывать запросы как бы к файлам, поэтому бездумно лепить трэйлинг слеш – не самое удачное решение. Значительно лучше наоборот убирать. Но потребность в нем все же может быть, поэтому этот фильтр нужно или вообще выносить из фронта на уровень конфига сервера, или наоборот глубоко закапывать.
Ещё раз переписал код уже раз пятый наверно, но уже с незначительными измененями PHP: <?php session_start(); ob_start(); // Начинаем проверку полного УРЛ $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); // Удаляем всё ненужное из УРЛ приводим к некому стандарту $clean_uri = str_replace(array('//', '\\', '\'', '"', ' ', '..', ',', '~', '<', '>', '%'), '', $uri, $count_error); // Берём последний символ УРЛ строки что бы проверить чем УРЛ заканчивается $slesh = substr($clean_uri, -1); //Проверяем УРЛ на соответствие нашим высоким требованиям //Во первых проверяем есть ли слеш на конце УРЛ, а во-вторых есть ли некрасивые символы и повторы в УРЛ //Если нашли что то не устраивающее редиректим на эталонный УРЛ if($slesh!=='/' or $count_error > 0){ header('Location: /'.$clean_uri.'/');// Редиректим на адекватный УРЛ exit; } //Если дошли до сюда значит УРЛ нам в целом нравится //Переходим к обработке принимаемых данных //Обрежем километровые запросы мне на сайте они не нужны $short_url = substr($clean_uri, 0, 200); //Создаём массив из УРЛ строки $segments = explode('/', trim($short_url, '/')); //Проверяем пришёл ли нам параметр для установки языка. //Это первый параметр который нужен //Если параметра нет здесь будет написана функция которая так или иначе добудет яыка и поставит его на место if(empty($segments[0])){ header('Location: '.$_SERVER['REQUEST_URI'].'/rus/'); } else { //Язык есть и УРЛ меня полностью устраивает поэтому покажем то за чем пользователь сюда пришёл include('main.php'); } //Проверяем пришли ли к нам какие то параметры (запросы) //Их ожидаем вторым эшелоном //Если они есть запихнём всё в сессию для дальнейшей работы if(!empty($segments[1])){ $_SESSION['lang'] = $segments[0]; $_SESSION['get'] = $segments[1]; //Запускаем в работу полученные даныне include('search.php'); } //Если каким то чудом пришло больше даных типа //site.ru/rus/а-я/всё/летала/но/я/так/и/знала/что/мечты/лишь/для/любви/лалала //По количеству символово это ешё укладывается в лимит 200 знаков //игнорировать не получится надо что то с этим делать забьём на них следующим образом if(!empty($segments[2])){ header('Location: /'.$segments[0].'/'.$segments[1].'/'); } ob_clean(); ob_end_flush(); ?> Кто разбирается ответьте это всё похоже на единую точку входа и роутинг или я всё же не понял. По поводу слешей мне там больше не надо так самый норм. Файл будут маленько по другому обрабатываться ещё не дошёл до этого.
У меня нет таких прав это походу форум из бекапа восстанавливали --- Добавлено --- В общем я обдумал сказанное тобой и пересмотрел подход страницы действительно могут быть и должны быть по этому ещё раз чуть-чуть переписал PHP: <?php session_start(); ob_start(); // Начинаем проверку полного УРЛ $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); // Удаляем всё ненужное из УРЛ приводим к некому стандарту $clean_uri = str_replace(array('//', '\\', '\'', '"', ' ', '..', ',', '~', '<', '>', '%'), '', $uri, $count_error); // Берём последний символ УРЛ строки что бы проверить чем УРЛ заканчивается $slesh = substr($clean_uri, -1); //Проверяем УРЛ на соответствие нашим высоким требованиям //Во первых проверяем есть ли слеш на конце УРЛ, а во-вторых есть ли некрасивые символы и повторы в УРЛ //Если нашли что то не устраивающее редиректим на эталонный УРЛ if($slesh!=='/' or $count_error > 0){ preg_match_all("|(.*).html|", $clean_uri, $out, PREG_PATTERN_ORDER); if(!empty($out[0][0])){ header('Location: /'.$out[0][0]); exit; } else { header('Location: /'.$clean_uri.'/');// Редиректим на адекватный УРЛ exit; } } //Если дошли до сюда значит УРЛ нам в целом нравится //Переходим к обработке принимаемых данных //Обрежем километровые запросы мне на сайте они не нужны $short_url = substr($clean_uri, 0, 200); //Создаём массив из УРЛ строки $segments = explode('/', trim($short_url, '/')); //Проверяем пришёл ли нам параметр для установки языка. //Это первый параметр который нужен //Если параметра нет здесь будет написана функция которая так или иначе добудет яыка и поставит его на место if(empty($segments[0])){ header('Location: /'.$_SERVER['REQUEST_URI'].'/rus/'); } else { //Язык есть и УРЛ меня полностью устраивает поэтому покажем то за чем пользователь сюда пришёл include('main.php'); } //Проверяем пришли ли к нам какие то параметры (запросы) //Их ожидаем вторым эшелоном //Разделим запросы и страницы //Это запрос if(!empty($segments[1]) and empty($out[0][0])){ $_SESSION['lang'] = $segments[0]; $_SESSION['get'] = $segments[1]; //Запускаем в работу полученные даныне include('search.php'); } //Здесь страница if(!empty($segments[1]) and !empty($out[0][0])){ switch($out[0][0]) { case 'contact.html': include('contact.html'); case 'about.html': include('about.html'); default: case '404.html': include('404.html'); } } //Если каким то чудом пришло больше даных типа //site.ru/rus/а-я/всё/летала/но/я/так/и/знала/что/мечты/лишь/для/любви/лалала //По количеству символово это ешё укладывается в лимит 200 знаков //игнорировать не получится надо что то с этим делать забьём на них следующим образом if(!empty($segments[2])){ header('Location: /'.$segments[0].'/'.$segments[1].'/'); } ob_clean(); ob_end_flush(); ?>
@AnteFil Скачай то, что прикрепил к посту. Залей поверх папки OpenServer содержимое в архиве. Убедись что у тебя PHP 8.1 и перезапусти Локалку. Врубай у себя: http://Site Все что в публичном доступе, должен находится единственный php файл, все остальное - стили и картинки. В Nouvu тебя должно будет только интересовать папка userdata_phpdotru Маршрутизации роутера: userdata_phpdotru\Resources\System\RecreateRouting.php Контроллер твоих страничек: userdata_phpdotru\Resources\Controllers\MainController.php Это в целях ознакомления на моем фрейме. Изучай Composer для подключения готовых решений, без него никуда. --- Добавлено --- Ммм... ну ок https://disk.yandex.ru/d/nzeGEsvtAjy8Ig
Спасибо за информацию но не подходит Несколько дней гугления и разбирательств нашёл видосы на ютубе и в итоге имею вот такой класс. Прошу помочь дальше разобраться прошу прочитать больше мои комментарии нежели сам код. В общем нужны разьяснения, замечания, коментарии. PHP: <?php // создаём пространиство имён namespace core; // создаём класс Router class Router {//Обьявляем две переменные со статусом private что бы работали только в этом классе private $routes = []; private $params = []; //function __construct автоматически выполниться при подключении класса потомучто __construct function __construct(){ //Создадим масси с будущими страницами controller и action //Другими словами некий блок и отдельные элементы по аналогии с новостями например категория новсти и новость $arr = [ "" => ['controller' => 'main', 'action' => 'index'], "account/login" => ['controller' => 'account', 'action' => 'login']]; //Здесь я понимаю что перебираем массив для чего так и не понял foreach ($arr as $key => $val) { $this->add($key, $val); } } //Создаём функцию в которую передаём 2 значения public function add($route, $params){ //Создаем из $route регулярное выражение $route = '#^'.$route.'$#'; //Эта строчка не понятна //И тут же вопрос почему мы пишем функцию add если как то её уже выполнили ранее в __construct $this->routes[$route] = $params; } //Создаём функцию match public function match(){ //Смотрим в REQUEST_URI какой запрос пришёл к нам $url = trim($_SERVER['REQUEST_URI'], '/'); //Здесь перебираем опять непонтно что и зачем foreach ($this->routes as $route => $params) { //Ищем по решулярке совпадения if(preg_match($route, $url, $matches)){ //Здесь не понятно что происходит $this->params = $params; //В случае успеха если нашли возвращаем из функции true return true; } } //если не нашли запрашиваему страницу возвращаем false return false; } //Создаём фукцию run() public function run(){ //если функция match нашла запрашиваему страницу идум дальше если её нет то пишем ошибку if($this->match()){ //Запишем в переменную $path предпологаемый контроллер для страницы $path = 'controller\\'.ucfirst($this->params['controller']).'Controller'; //Страница есть проверим есть контроллер( другими словами категория,группа) для работы с этой страницей if(class_exists($path)){ //Запишем в $action запрашиваемый элемент или обьект или новость $action = $this->params['action'].'Action'; //Контроллер есть проверим есть ли action ( другими словами конкретная страница, новость) в этом контроллере (группе) if(method_exists($path, $action)){ //Контроллер есть и экшен есть поэтому мы передаём запрашиваемыые параметры в них $controller = new $path($this->params); $controller->$action(); } else { echo 'Не найден экшен '.$action; } } else { echo 'Не найден: '.$path; } } else { echo 'Нет маршрута'; } } } ?> Сам контроллер PHP: <?php namespace controller; use core\Controller; class AccountController extends Controller{ public function loginAction(){ echo 'Есть'; } public function registerAction(){ echo 'Есть'; } } ?> И страничка index.php PHP: <?php //Старт сессии session_start(); //подключаем правила require 'core/Router.php'; //подключаем пространство имён use core\Router; //автозагрузка класса spl_autoload_register(function ($class) { $path = str_replace('\\','/', $class.'.php'); if(file_exists($path)){ require $path; } }); ///запуск правил роутинга $router = new Router; $router->run(); ?>