Формирование request_uri

rotoZOOM

ACM maniac
Получилась у меня такая вот функция, для замены/добавления GET параметра, вне зависимости от того используется ЧПУ или нет. Функция не самая быстрая, но я думаю замена параметров не будет происходить 1000 раз в одном скрипте.
*****, я понимаю, что ты не используешь конкретно в своей работе ЧПУ, но так как такая тема поднялась, чтобы не плодить топики решил выложить функцию тут.
Массив $rep - массив замен спец. символов для регулярки.
(скорее это уже для экзотики).
PHP:
    function urlEditParam ($par)
    {
    	$s=$_SERVER['REQUEST_URI'];
    	$rep=array ("\\" => "\\\\",
			    	"." => "\\.",
			    	"*" => "\\*",
			    	"+" => "\\+");

    	$b = strpos($s,"?")!==FALSE;
    	foreach ($par as $p => $v){
        	$zam=strtr ($p,$rep);
    		if (strpos($s,"?$p=")){
    			$s=preg_replace ("/\?$zam=([^&]+)/i","?$p=$v",$s);
    		}elseif (strpos($s,"&$p=")){
    			$s=preg_replace ("/\&$zam=([^&]+)/i","&$p=$v",$s);
    		}else{
    			if ($b)$s.="&";
    			else $s.="?";
    			$s.="$p=$v";
    			$b=TRUE;
    		}
    	}
    	return $s;
    }
 

Фанат

oncle terrible
Команда форума
rotoZOOM
повторяю второй раз
у меня в QUERY_STRING попадает то, что было в запросе.
я так понимаю, что это из-за QSA

-~{}~ 01.02.08 13:32:

как минимум, ты не урленкодишь получаемую строку.
и зачем твой реп, когда есть preg_quote?
 

Kill_Santa

Новичок
Re: Формирование request_uri

Автор оригинала: *****
Че-та я и сам идиотским вопросом озаботился.
Задача классическая - формирование реквест ури из существующего, с заменой переменных.
То есть, если у нас запрос /script.php?a=b&c=d и надо в него вписать c=z

Подхода я вижу два
1.Отрезать от реквест ури путь, сформировать квери стринг вручную перебором $_GET и потом соединить их
2. Заменять прямо в реквест ури.
Раньше я увлекался первым, но сейчас что-то показалось - второй попроще будет. Но при попытке сделать реализацию получается кода не меньше, чем в первом. В силу того, что запрос, разумеется, может быть и /script.php, и /script.php? и /script.php?a=b

А кто как делает?
Первый способ красивее и академичнее.
 

rotoZOOM

ACM maniac
Фaнат Я понимаю, что это так. Вопрос в том, какая ссылка будет формироваться в строке браузера, после перехода по преобразованной ссылке.
Как пример, пользователь переходит на страницу:
http://www.bestsite.ru/users/123/private?a=b
там после преобразования mod_rewrite и добавления/редактирования параметра 'page=2' появляется ссылка:
http://www.bestsite.ru/index.php?mod=users&p0=123&p1=private&a=b&page=2
вместо:
http://www.bestsite.ru/users/123/private?a=b&page=2
Или я что-то непонимаю ?

Насчет урленкода и preg_quote спасибо, учту обязательно.
 

Фанат

oncle terrible
Команда форума
блин.
покажи хоть строчку в любом из имеющихся здесь кодов, которая из http://www.bestsite.ru/users/123/private сделает http://www.bestsite.ru/index.php

-~{}~ 01.02.08 17:13:

короче, с формированием более-менее решили, а теперь объявляется конкурс на оптимальное решение с заменой.

А дальше будем их сравнивать
 

rotoZOOM

ACM maniac
В этой ветке нет таких строчек. Я говорю о преобразовании mod_rewrite, например такое:
Код:
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
После преобразования URL из браузера, например:
/a/b/c/d?h=1
в скрипт (QUERY_STRING)попадает уже не чпу'шная строка
index.php?q=/a/b/c/d&h=1
после того, как ты ее обработаешь своей функцией, на
выходе у тебя получится уже такая ссылка, которая будет показана пользователю и пойдет в строку браузера (если не будет обратного преобразования):
index.php?q=/a/b/c/d&h=1&page=2
А не логично ли было бы формировать URL'строку в том же виде, в котором юзер видит ее изначально:
/a/b/c/d?h=1&page=2
?

Я недавно начал юзать модреврайт, может я туплю или плохо объясняю, или в данной ветке сохранение стиля URL'а автора не волнует ?

-~{}~ 01.02.08 19:39:

Раз пошла такая пьянка, с замечаниями Фaната:
PHP:
function urlEditParam ($par)
    {
    	$s=$_SERVER['REQUEST_URI'];
        $b = strpos($s,"?")!==FALSE;
        foreach ($par as $p => $v){
            $zam=preg_quote ($p);
            $pu=urlencode($p);
            $vu=urlencode($v);
            if (strpos($s,"?$p=")){
                $s=preg_replace ("/\?$zam=([^&]+)/i","?$pu=$vu",$s);
            }elseif (strpos($s,"&$p=")){
                $s=preg_replace ("/\&$zam=([^&]+)/i","&$pu=$vu",$s);
            }else{
                if ($b)$s.="&";
                else $s.="?";
                $s.="$pu=$vu";
                $b=TRUE;
            }
        }
        return $s;
    }
 

Фанат

oncle terrible
Команда форума
В этой ветке нет таких строчек.
после того, как ты ее обработаешь своей функцией, на
выходе у тебя получится index.php?q=/a/b/c/d&h=1&page=2
Да ё-моё!
Так есть или нету?!
Если функция испортит урл - значит в ней должен быть код, который это сделает! Ты можешь его показать?
Ты можешь показать место в моей функции, которое выдаст на выходе index.php?q=/a/b/c/d&h=1&page=2 ??????
или в данной ветке сохранение стиля URL'а автора не волнует ?
твоюмать.
ты можешь объяснить, с чего ты решил, что стиль не сохраняется-то? Пальцем покажи! Ссылку на работающий пример моей функции, который портит урл чпу!
 

StUV

Rotaredom
Че-та я и сам идиотским вопросом озаботился.
Задача классическая - формирование реквест ури из существующего, с заменой переменных.
То есть, если у нас запрос /script.php?a=b&c=d и надо в него вписать c=z
странно, но проблемы такой никогда не было
А кто как делает?
код, формирующий страницу "логическим образом" знает, по какому урлу была запрошена эта страница - т.е. собственно выполнение кода, ее формирующего + вид урлов, по которым с этой страницы можно куда-либо перейти
соответственно, любой урл не дополняется, а генерится "с нуля" на основе входных параметров и, при необходимости, расширяющей бизнес-логики

зы:
ессно были случаи, в которых приходилось генерить урл на основе исходного, но до сих пор стыдно смотреть на это дело - как на явный пример быстрой заплатки

*****
к чему это все... - можешь привести пример, в котором без этого не обойтись?..
 

rotoZOOM

ACM maniac
Нивапрос.

часть .htaccess
Код:
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
index.php
PHP:
// почти последняя твоя функция в этой ветке
function modURIparam($name,$value) {
  $uri = strtok($_SERVER['REQUEST_URI'],"?")."?";
  foreach ($_GET as $k => $v) if ($k != $name) $uri.=urlencode($k)."=".urlencode($v)."&";
  if ($value !==FALSE) $uri.=urlencode($name)."=".urlencode($value);
  return $uri;
}

echo $uri=modURIparam("page",FALSE);
строка на входе браузера:
http://localhost/game/a/b/c?h=1

После твоей функции:
/game/a/b/c?q=a%2Fb%2Fc&h=1&

Повторяю. Это справедливо только для ЧПУ преобразований.
 

Фанат

oncle terrible
Команда форума
ну и где здесь index.php?

-~{}~ 01.02.08 17:59:

StUV
так написано же вроде в начале?
таблица с результатами поиска и возможностью сортировки и постраничного вывода
 

rotoZOOM

ACM maniac
StUV Может и не корректный пример, но в страницу GET'ом передается модуль, id какие-то и т.д., а так же заодно параметры для постраничного вывода page, numberperpage, и т.д. При смене страницы модуль и еже с ним не должны изменяться, но при нажатии на следующую страницу функция должна сгенерировать корректный URL и не потерять аргументы, а зачем этой функции значть что-то еще, кроме как ее page, numberperpage, и т.д ?

-~{}~ 01.02.08 20:06:

***** так как есть такое правило:
Код:
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
то после преобразования такой URL
http://localhost/game/a/b/c?h=1
становится таким:
http://localhost/game/index.php?q=a/b/c&h=1
(.htaccess лежит в localhost/game)
Соответственно, phpinfo выдает на это следующую инфу:
Код:
QUERY_STRING 	q=a/b/c&h=1
REQUEST_URI 	/game/a/b/c?h=1
SCRIPT_NAME 	/game/index.php
Если пользоваться $_GET[], то в нем будут параметры именно:
['q']='a/b/c';
['h']='1';
и после вызова твоей функции
урл становится таким, какой я уже писАл.
 

StUV

Rotaredom
все-равно не понятно =)

у меня код, отдающий страницу знает о всех гет-параметрах, допустимом диапазоне их значений, их назначении и т.п...

вид урла страницы или запроса на сортировку известен представлению

данные тупо отдаются в шаблон, который собирает из них урл в необходимом порядке, "зная", что все необходимые значения пришли (включая дефолты) - иначе мы бы просто не дошли до парсинга шаблона (на этапе валидации параметров слетели бы на error_page)
 

Фанат

oncle terrible
Команда форума
Ну слава богу. бред про index.php в урле ты больше не повторяешь. уже хорошо.

по поводу квери стринг - да, я ошибся. у меня тоже в неё попадает параметр из реврайта. Соответственно, если формировать строку, то его надо убирать руками.

-~{}~ 01.02.08 18:21:

StUV
во-первых, так и надо было писать. не "покажите, когда это нужно", а "я такой умный, у меня урл контролируется скриптом". Раз так - хорошо. Тебе такой функционал не нужен.
А я не люблю перегружать скрипты бессмысленным функционалом.

Во-вторых, вообще-то, урл - это совсем не дело шаблона.
 

StUV

Rotaredom
во первых, я в первом же посте и написал про
урл контролируется скриптом
---
перегружать скрипты бессмысленным функционалом
в чем смысл таскать за собой левые переменные, которые потенциально могут использовать при формировании страницы левый функционал?

урл - это совсем не дело шаблона
постраничка по диапазону как "довесок" к фиксированному базоввому урлу?..
 

Фанат

oncle terrible
Команда форума
rotoZOOM
Или отрезать квери стринг из реквест-ури...

Просто надо конструктивно подходить к вопросу. Не "здесь никого оне волнует реврайт", а "при таком подходе будет такая ошибка".
За неё - спасибо.

-~{}~ 01.02.08 18:36:

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

StUV

Rotaredom
*****
т.е. логичнее сгенерить массив из 10 ссылок и передать в шаблон, который так же в цикле их все будет выводить?

имхо, здесь как раз тратится лишние память/время
 

Фанат

oncle terrible
Команда форума
Да, я считаю, что правильнее будет именно так - сгенерить массив и передать в шаблон.
Из 10 для постранички и ещё кучку ссылок - для сортировки.

-~{}~ 01.02.08 18:58:

rotoZOOM
Извини, пожалуйста. Я неадекватно среагировал

-~{}~ 01.02.08 19:23:

В результате, получается примерно так:
PHP:
function mod_qstr($params) {
  $parts=parse_url($_SERVER['REQUEST_URI']);
  $qs = array();
  if ($parts['query']) parse_str($parts['query'], $qs);
  $qs = $params + $qs;
  $qs = empty($qs) ? '' : '?'.http_build_query($qs);
  return $parts['path'] . $qs; 
}
немного тяжеловесно, но зато работает.

-~{}~ 01.02.08 19:25:

StUV
А можешь рассказать в общих чертах, каким образом у тебя скрипт знает обо всех параметрах?

Я могу добавить в скрипт массив разрешенных параметров.
Но вот так, чтобы скрипт сам знал - это мне сложно представить
 

rotoZOOM

ACM maniac
Фaнат все ок.

-~{}~ 01.02.08 21:35:

Твоя функция мне нравится больше, она использует специальные URL'ные функции, и не надо заморачиваться с регулярками.
 

Фанат

oncle terrible
Команда форума
Мне она именно этим не нравится =)
Черт его знает, что у них там внутри.

К тому же, в ней я пошел на поводу у fixxxer-а, который поступает классически - в параметрах функции указывает массив.
А мне бы хотелось от функции скорее удаление параметра.
чтобы можно было получить строку-заготовку, а потом в цикле цеплять к ней ту же page=$1
а не проворачивать всю операцию в цикле

может, как-то со static извратиться...
 

Kill_Santa

Новичок
Автор оригинала: *****
блин.
покажи хоть строчку в любом из имеющихся здесь кодов, которая из http://www.bestsite.ru/users/123/private сделает http://www.bestsite.ru/index.php

-~{}~ 01.02.08 17:13:

короче, с формированием более-менее решили, а теперь объявляется конкурс на оптимальное решение с заменой.

А дальше будем их сравнивать
В данном случае причиной непоняток является явное путание понятий URI и URL

/users/123/private - URL
?type=fucker&resource=mother - URI

Если я не прав, переформулируй изначальную тему!
 
Сверху