Помогите настроить .htaccess

Настраиваю ссылки хочу привести к такому виду
site/язык/get/
сейчас прописано так

Код (Text):
  1. RewriteRule ^rus/(.*)/$ /search.php?lang=rus&q=$1

Проблема в том что для каждого языка нужно создавать по две записи одна та что выше и вторая если get параметра нет

Код (Text):
  1. RewriteRule ^rus/$ /search.php?lang=rus

для 20 языков уже создаётся 40 записей а если добавить ещё один get то уже 60
Можно ли как то это упростить???

Второй вопрос
На странице есть форма. При отправке данных с формы получаю ссылку вида
/rus/?q=апапап
а нужно
/rus/апапапапа/

 

изучи единую точку, роутинг. Станет легче и понятнее. Сейчас кашу мутишь в каше — велосипед WTF

 

Зачем создавать две записи если можно в search.php проверять существование параметра и его значение. По второму вопросу: можно вообще поменять метод в форме и запрос не будет виден.

 

Ок начал разбираться

PHP:
  1. $uri = parse_url($_SERVER[‘REQUEST_URI’], PHP_URL_PATH);
  2. $segments = explode(«https://php.ru/», trim($uri, «https://php.ru/»));
  3. //Получаем доступные языки из папки lang
  4. $get_lang_mas = scandir(‘lang/’);
  5. foreach ($get_lang_mas as $get_lang) {
  6.     preg_match(‘/\w\w\w/’, $get_lang, $leng);
  7.     if (!empty($leng)) {
  8.         $leng_mas[] = $leng;
  9.     }
  10. }
  11. //сравниваем доступные языки с запрашиваемыми
  12. foreach ($leng_mas as $odin) {
  13. if($segments[0]==$odin[0])
  14. echo ‘язык определили’;
  15. }

после чего у меня будет первая часть ссылки правильно думаю ?
site/rus/
добавил вот так

PHP:
  1. foreach ($leng_mas as $odin) {
  2. if($segments[0]==$odin[0])
  3. $ssika[] = $segments[0];
  4. }
  5. if (!empty($segments[1])){
  6. $ssika[] = $segments[1];  
  7. }
  8. header(«Location: https://dottorrent.ru/$ssika[0]/$ssika[1]);

Всё заканчивается бесконечным редиректом

 

Какой ссылки? В смысле входящего адреса? Когда парсят путь из входящего адреса explode’ом, то первая часть – это, естественно, rus (если site – это имя хоста). У вашего парсинга есть огрехи. Непробиваемый вариант показан в этой статье: Как сделать единую точку входа с ЧПУ?

И нафига цикл для проверки попадания в созданный белый список? Здесь даже ф-ция поиска в массиве – это логическая ошибка. Сделайте rus и т.п. ключами массива – можно будет использовать бинарный поиск, т.е. просто проверять наличие этого ключа.
— Добавлено —

Нафига Location? Вы про это вообще ничего не писали. Или думаете, что Location нужен для реализации роутинга? :D
— Добавлено —
Фишку из кода моей статьи с добавлением пустого второго компонента пути можно использовать и вам. Ее смысл в том, что потом не нужно проверять наличие этого параметра, как имени переменной. После этого можно искать просто по значению. Т.е. «тупо» искать и не найти пустой ключ. Или искать и найти :)

 

Если 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:
  1. $uri = parse_url($_SERVER[‘REQUEST_URI’], PHP_URL_PATH);
  2. $segments = explode(«https://php.ru/», trim($uri, «https://php.ru/»));
  3. //Если пришло больше параметров чем нужно значит ошибка перенаправим на адекватную страницу
  4. if(!empty($segments[2])){
  5.     header(«Location: localhost/$segments[0]/$segments[1], true, 301);
  6.     exit();
  7. }
  8. //Получаем доступные языки из папки lang
  9. $get_lang_mas = scandir(‘lang/’);
  10. foreach ($get_lang_mas as $get_lang) {
  11.     preg_match(‘/\w\w\w/’, $get_lang, $leng);
  12. //Сравниваем доступные языки с запрашиваемым если совпадает выходим из перебора
  13.     if ($segments[0]==$leng[0]) {
  14.         break;
  15.     } else {
  16. //Запрашиваемый язык не нашли возвращаем русский по умолчанию
  17.         $leng[0] = ‘rus’;
  18.     }
  19. }
  20. echo $leng[0];
 

Вот так ещё дописал

PHP:
  1. $uri = parse_url($_SERVER[‘REQUEST_URI’], PHP_URL_PATH);
  2. $segments = explode(«https://php.ru/», trim($uri, ‘/.’));
  3. //Если пришло больше параметров чем нужно значит ошибка
  4. if(!empty($segments[2])){  
  5. header(«Location: localhost/$segments[0]/$segments[1], true, 301);
  6. exit();
  7. }
  8. //Нет запроса по этому придумаем его
  9. if(empty($segments[1])){  
  10. $input = array(«Человек», «Марс», «Батистута», «Барабан», «Tank», «Баргузин», «Матрица», «Павел Мурашко»);
  11. $rand_keys = array_rand($input, 2);
  12. header(‘Location: localhost/’.$segments[0].«https://php.ru/».$input[$rand_keys[0]].«https://php.ru/», true, 301);
  13. exit();
  14. }
  15. //Нет языка редиректим на русский по умолчанию
  16. if(empty($segments[0])){  
  17. header(‘Location: localhost/rus/’, true, 301);
  18. exit();
  19. }
  20. //Получаем доступные языки из папки lang
  21. $get_lang_mas = scandir(‘lang/’);
  22. foreach ($get_lang_mas as $get_lang) {
  23.     preg_match(‘/\w\w\w/’, $get_lang, $leng);
  24. //Сравниваем доступные языки с запрашиваемым если совпадает выходим из перебора
  25.     if ($segments[0]==$leng[0]) {
  26.         break;
  27.     } else {
  28. //Запрашиваемый язык не нашли верём русский по умолчанию
  29.         $leng[0] = ‘rus’;
  30.     }
  31. }
  32. echo $leng[0];
 

ещё немного переделал

PHP:
  1. //Если нет запроса то придумывать его не будем а просто покажем стартовую страницу
  2. if(empty($segments[1])){
  3. include(‘main.php’);
  4. exit();
  5. }

таким образом получается структура сайта
site.ru/rus/
site.ru/rus/проверка/

 

Ещё раз переписал )))

PHP:
  1. $uri = parse_url($_SERVER[‘REQUEST_URI’], PHP_URL_PATH);
  2. $segments = explode(«https://php.ru/», trim($uri, ‘/.’));
  3. //Если пришло больше параметров чем нужно значит ошибка
  4. if(!empty($segments[2])){  
  5. header(«Location: localhost/$segments[0]/$segments[1], true, 301);
  6. exit();
  7. }
  8. //Нет запроса грузим main.php
  9. if(empty($segments[1])){  
  10. include(‘main.php’);
  11. exit();
  12. }
  13. //Нет языка редиректим на русский по умолчанию
  14. if(empty($segments[0])){  
  15. header(‘Location: localhost/rus/’, true, 301);
  16. exit();
  17. }
  18. //если мы дошли сюда то значит всё в порядке и загрузим страницу search
  19. $_SESSION[‘lang’] = $segments[0];
  20. $_SESSION[‘get’] = $segments[1];
  21. include(‘search.php’);
 

Вы это у нас спрашиваете? :)

Попробуйте echo :) Можно и дальше пойти, т.к. сами параметры из адреса обычно не нужно выводить (по ним др. данные выбирают):

PHP:
  1. <h1><?= $page[‘name’] ?></h1>
  2. <?= $page[‘content’] ?>
Код (Text):
  1. INSERT INTO `site_categories` (`id`, `name`, `bits`, `module`) VALUES
  2. (‘rus’, ‘Язык: русский’, 19, ‘page’);
  3.  
  4. CREATE TABLE `site_rus` (
  5.   `id` varchar(26) NOT NULL,
  6.   `name` tinytext NOT NULL,
  7.   `content` text NOT NULL,
  8.   PRIMARY KEY (`id`)
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  10.  
  11. INSERT INTO `site_rus` (`id`, `name`, `content`) VALUES
  12. (», ‘Главная’, ‘<p>Главная</p>’),
  13. (‘get’, ‘Внутряк’, ‘<p>Внутряк</p>’);

В итоге:
g09.ru/rus
g09.ru/rus/get
— Добавлено —

Лучше отдать 404-ую без редиректа. Корректировку редиректом обычно делают для опечаток в адресе или для ранее существовавших страниц, траф на которые уместно направить на что-то другое.
— Добавлено —
Но если сильно хоЦА, пишите соотв. логику.

 

Например, я могу перевести используемый фронт-контроллер в режим «ручного анализа второго параметра» и добавить такой контроллер:

PHP:
  1. if (count($pa = explode(«https://php.ru/», $p1, 2)) < 2)
  2. {
  3.   $page = findOrFail(table($p0), $pa[0]);
  4. }
  5. else
  6. {
  7.   redirect(«https://php.ru/».$p0.«https://php.ru/».$pa[0]);
  8. }

У меня $p0 == ‘rus’ && $p1 == ‘запрос‘ (или ‘запрос/fgfdgdg/gdfgdfgdg‘). В реале вместо $p0 лучше использовать спец. переменную, значение которой выбрано из БД, а не получено из адреса.

 

Я вот про это…..
Это похоже на единую точку входа или я всё же что ещё не совсем понимаю
Понятно что с переменными можно дальше уже работать запросы в базу или ещё чего

 

@AnteFil, Ты OpenServer используешь ?

 

Помогите распознать слеш

PHP:
  1. $uri = parse_url($_SERVER[‘REQUEST_URI’], PHP_URL_PATH);
  2. $segments = explode(«https://php.ru/», trim($uri, ‘/.’));
  3. //Если пришло больше параметров чем нужно значит ошибка
  4. if(!empty($segments[0])){
  5. header(«Location: /rus/», true, 301);
  6. } else {
  7. include(‘main.php’);
  8. }

При таком подходе я не могу проверить есть ли слеш на конце так как создавая массив слешы удаляются и сайт доступен как по site/rus так и site/rus/

 

Парни, парни, парни ещё раз переписал у кого будут замечания напишите пожалуйста

PHP:
  1. // Проверка полного УРЛ
  2. $uri = parse_url($_SERVER[‘REQUEST_URI’], PHP_URL_PATH);
  3. // Удаляем всё ненужное из УРЛ
  4. $clean_uri = str_replace(array(‘//’, ‘\\’, ‘\», ‘»‘, ‘ ‘), », $uri);
  5. // Проверим чем заканчивается УРЛ слеш там или нет
  6. $slesh = substr($clean_uri, 1);
  7. if($slesh!==«https://php.ru/»){
  8.     header(‘Location: ‘.$_SERVER[‘REQUEST_URI’].«https://php.ru/»);// На конце не слеш редиректим со слешем
  9. }
  10. //Переходим к обработке принимаемых данных создадим массив
  11. // Обрежем километровые запросы они нам не к чему
  12. $short_url = substr($clean_uri, 0, 200);
  13. $segments = explode(«https://php.ru/», trim($short_url, «https://php.ru/»));// создаём массив из УРЛ строки
  14. //Проверяем на наличие языка если его нет редиректим на язык по умолчанию
  15. if(empty($segments[0])){
  16. header(‘Location: ‘.$_SERVER[‘REQUEST_URI’].‘/rus/’);
  17. } else {
  18. //Язык есть и УРЛ меня устраивает поэтому с ним больше делать нечего и покажем то за чем пришли страницу
  19. include(‘main.php’);    
  20. }
  21.  
  22.  
 

Все плохо :) Начиная с первой строчки. Расписывать уже в лом, т.к. обратной реакции ноль.
— Добавлено —
Вместо того чтобы думать об «Обрежем километровые запросы они нам не к чему», лучше бы вспомнили, что в REQUEST_URI может быть не только путь, поэтому лепить к этому трэйлинг слеш – затея так себе ;) Про доп. логику, не относящуюся к делу, когда уже намечен редирект, промолчу :)
— Добавлено —
P.S. Фронт может обрабатывать запросы как бы к файлам, поэтому бездумно лепить трэйлинг слеш – не самое удачное решение. Значительно лучше наоборот убирать. Но потребность в нем все же может быть, поэтому этот фильтр нужно или вообще выносить из фронта на уровень конфига сервера, или наоборот глубоко закапывать.

 

+1

 

Добавить комментарий

Ваш адрес email не будет опубликован.