Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737 Форумы портала PHP.SU :: Обработка строки URL запроса
, объясните пожалуйста принцип работы таких конструкций, просто хочется научиться делать "как надо".
Как я понимаю, url записывается в переменную $str = $_SERVER['QUERY_STRING'];, затем разбивается функцией parse_str(); для получения масива. А что дальше, как по полученному массиву строить страницу, выводить контент?
Надеюсь я понятно объяснил, если возможно, ответьте как можно подробнее, буду признателен за помощь!
-SCHATTEN-
Отправлено: 28 Февраля, 2007 - 08:40:06
Пользователь
Покинул форум
Сообщений всего: 615
Дата рег-ции: Июль 2006 Откуда: Оттуда !
Помог: 0 раз(а)
QUERY_STRING
Параметры, которые в URL указаны после вопросительного знака. Напомню, что они
доступны как при методе GET, так и при методе POST (если в последнем случае они
были определены в атрибуте action тэга <form>).
Передача параметров методом GET
Тут все просто. Все параметры передаются единой строкой (а именно, точно такой
же, какая была задана в URL после ?) в переменной QUERY_STRING. Единственная
проблема — то, что все данные поступят URL-кодированными. Так что нам понадо-
бится функция декодирования. Но это отдельная тема, пока мы не будем ее касаться.
Для того чтобы узнать значения полученных переменных в Си, нужно воспользовать-
ся функцией getenv(). Вот пример сценария на Си, который это обеспечивает.
Листинг 3.2. Работа с переменными окружения
Передача параметров методом POST
В отличие от метода GET, здесь параметры передаются сценарию не через перемен-
ные окружения, а через стандартный поток ввода (в Си он называется stdin). То
есть программа должна работать так, будто никакого сервера не существует, а она
читает данные, которые вводит пользователь с клавиатуры. (Конечно, на самом деле
никакой клавиатуры нет и быть не может, а заправляет всем сервер, который "изо-
бражает из себя" клавиатуру.)
Следует заметить очень важную деталь: то, что был использован метод POST,
вовсе не означает, что не был применен также и метод GET. Иными словами,
метод POST подразумевает также возможность передачи данных через URL-
строку. Эти данные будут, как обычно, помещены в переменную окружения
QUERY_STRING.
Но как же узнать, сколько именно данных переслал пользователь методом POST? До
каких пор нам читать входной поток? Для этого служит переменная окружения
CONTENT_LENGTH, в которой хранится строка с десятичным представлением числа
переданных байтов данных (разумеется, перед использованием ее надо перевести в
обычное число).
Модифицируем предыдущий пример так, чтобы он принимал POST-данные, а также
выводил и GET-информацию, если она задана:
Листинг 3.3. Получение данных POST
Странслируем этот сценарий и запишем то, что получилось, под именем script.cgi
в каталог, видимый извне как /cgi-bin/. Откроем в браузере следующий HTML-
файл с формой:
Листинг 3.4. POST-форма
Теперь, если набрать в полях ввода какой-нибудь текст и нажать кнопку, получим
HTML-страницу, сгенерированную сценарием, например, следующего содержания:
Здравствуйте. Мы знаем о вас все!
Ваш IP-адрес: 136.234.54.2
Количество байтов данных: 23
Вот параметры, которые Вы указали: name1=Vasya&name2=Petya
А вот то, что мы получили через URL: param=value
Как можно заметить, обработка метода POST устроена сложнее, чем GET. Тем не ме-
нее, метод POST используется чаще, особенно если нужно передавать большие объе-
мы данных или "закачивать" файл на сервер (эта возможность также поддерживается
протоколом HTTP и HTML).
Расшифровка URL-кодированных данных
Если бы в предыдущем примере мы ввели параметры, содержащие, например, буквы
кириллицы, то сценарию они бы поступили не в "нормальном" виде, а в URL-
закодированном. Пожалуй, ни один сценарий не обходится без функции расшифровки
URL-кодированных данных. И это совсем не удивительно. Радует только то, что та-
кую функцию нужно написать один раз, а дальше можно пользоваться ей по мере
необходимости.
Как уже упоминалось, кодирование заключается в том, что некоторые неалфавитно-
цифровые символы (в том числе и "русские" буквы, которые тоже считаются неалфа-
витными) преобразуются в форму %XX, где XX — код символа в шестнадцатеричной
системе счисления. Далее представлена функция на Си, которая умеет декодировать
подобные данные и приводить их к нормальному представлению.
Мы не можем сначала все данные (например, полученные из стандартного по-
тока ввода) декодировать, а уж потом работать с ними (в частности, разбивать
по месту вхождения символов & и =). Действительно, вдруг после перекоди-
ровки появятся символы & и =, которые могут быть введены пользователем?
Как мы тогда узнаем, разделяют ли они параметры или просто набраны с кла-
виатуры? Очевидно, никак. Поэтому такой способ нам не подходит, и придется
работать с каждым значением отдельно, уже после разделения строки на час-
ти.
\n\n(Добавление)
Итак, приходим к следующему алгоритму: сначала разбиваем строку параметров на
блоки (параметр=значение), затем из каждого блока выделяем имя параметра и его
значение (обособленные символом =), а уж потом для них вызываем функцию пере-
кодировки, приведенную ниже:
Листинг 3.5. Функция URL-декодирования
// указатель p всегда отмечает то место в строке, в которое
// будет помещен очередной декодированный символ
}
// иначе, если это "+", то заменяем его на " "
elseif(*st=='+')*p++=' ';
// а если не то, ни другое — оставляем как есть
else*p++=*st;
}while(*st++!=0);// пока не найдем нулевой код
}
Функция основана на том свойстве, что длина декодированных данных всегда мень-
ше, чем кодированных, а значит, всегда можно поместить результат в ту же строку,
не опасаясь ее переполнения. Конечно, примененный алгоритм далеко не оптимален,
т. к. использует довольно медлительную функцию sscanf() для перекодирования
каждого символа. Тем не менее, это самое простое, что можно придумать, вот почему
я так и сделал.
Итак, теперь мы можем слегка модифицировать предыдущий пример сценария, за-
ставив его перед выводом данных декодировать их. Попробуем написать это так:
Листинг 3.6. Получение POST-данных с URL-декодированием
Обратите внимание на строки, выделенные жирным шрифтом. Теперь мы используем
промежуточный буфер для хранения QUERY_STRING. Зачем? Попробуем поставить
все на место, т. е. не задействовать промежуточный буфер, а работать с переменной
окружения напрямую, как это было в листинге 3.5. Тогда в одних операционных сис-
темах этот код будет работать прекрасно, а в других — генерировать ошибку общей
защиты, что приведет к немедленному завершению работы сценария. В чем же дело?
Очень просто: переменная QueryString ссылается на значение переменной окруже-
ния QUERY_STRING, которая расположена в системной области памяти, а значит, дос-
тупна только для чтения. В то же время функция UrlDecode(), как я уже замечал,
помещает результат своей работы в ту же область памяти, где находится ее параметр,
что и вызывает ошибку.
Чтобы избавиться от указанного недостатка, мы и копируем значение переменной
окружения QUERY_STRING в область памяти, доступной сценарию для записи — на-
пример, в какой-нибудь буфер, а потом уже преобразовываем его. Что и было сделано
в последнем сценарии.
Несколько однообразно и запутанно, не так ли? Да, пожалуй. Но, как говорится, "это
даже хорошо, что пока нам плохо" — тем больше будет причин предпочитать PHP
другим языкам программирования (так как в PHP эти проблемы изжиты как класс).
de'vovan
Отправлено: 28 Февраля, 2007 - 13:41:33
Новичок
Покинул форум
Сообщений всего: 37
Дата рег-ции: Дек. 2006 Откуда: Ейск
Помог: 0 раз(а)
Дааа уж... !
Спасибо вам огромное за проделанную работу по объяснению! Я несколько раз перечитал все это и немного не понял: это на языке СИ (мне бы на PHP)?
А неужели все так сложно, я наверное плохо разъяснил вопрос , имелось в виду вот что: у меня на сайте будут, например, ссылки вида <a href="?content=news&id=10 и т.д.>новость №10</a>. Вопрос: каким образом обрабатывать такой запрос(ссылки такого вида)? Как на основании полученных данных делать вывод опр. данных.
Для пояснения, расскажу как делаю я:
Куча ссылок типа href=?news=10, а обрабатываю так: if (isset($_GET['baza']
{
if (!empty($_GET['baza']))
{
$id = $_GET['news'];
<!-- делаю вывод новости из базы данных news по id=10 -->
}
}
Даже мне ясно что крайне каряво, поэтому и спрашиваю, как правельно?
Сразу прошу прощения, я наверно ваще ламер!
-SCHATTEN-
Отправлено: 28 Февраля, 2007 - 14:32:59
Пользователь
Покинул форум
Сообщений всего: 615
Дата рег-ции: Июль 2006 Откуда: Оттуда !
Помог: 0 раз(а)
Ну почему коряво ? Всё правильно, ты берешь из строки запроса номер новости и выводишь новость по этому номеру из БД.
de'vovan
Отправлено: 28 Февраля, 2007 - 21:19:38
Новичок
Покинул форум
Сообщений всего: 37
Дата рег-ции: Дек. 2006 Откуда: Ейск
Помог: 0 раз(а)
Спасибо за помощь!
Я тут придумал кое-что по теме, что скажите?
Имеем ссылки типа href="?content=module_...¶metr=valye"
При нажатии по ссылке открываем папку module_... и передаем файлу index.php параметр со значением valye (Что-то типа модулей в CMSке). Возможен ли такой вариант принципа работы динамического сайта с 1 страницей? И если возможно, каким образом можно передать параметр?
P.S. надеюсь я не сильно в дебри полез, просто очень уж нужен механизм построения динамического сайта.
de'vovan
Отправлено: 02 Марта, 2007 - 11:30:30
Новичок
Покинул форум
Сообщений всего: 37
Дата рег-ции: Дек. 2006 Откуда: Ейск
Помог: 0 раз(а)
Ребят, вы где?
Может кто оценит мою задумку, или, хоть вкратце поделится своим способом (построения динамического сайта, когда есть только одна страница) ?
Оочень надо
-SCHATTEN-
Отправлено: 02 Марта, 2007 - 11:45:21
Пользователь
Покинул форум
Сообщений всего: 615
Дата рег-ции: Июль 2006 Откуда: Оттуда !
Помог: 0 раз(а)
Зачем тебе это надо ? сделай простой сайт... Возьми книгу по CGI и почитай там как устроена строка адреса и как с ней работать...
+ стоит про работу с файлами в РНР почитать.
de'vovan
Отправлено: 02 Марта, 2007 - 11:55:03
Новичок
Покинул форум
Сообщений всего: 37
Дата рег-ции: Дек. 2006 Откуда: Ейск
Помог: 0 раз(а)
-SCHATTEN- пишет:
Зачем тебе это надо ? сделай простой сайт... Возьми книгу по CGI и почитай там как устроена строка адреса и как с ней работать...
Sorry, не понял, вы имеете в виду, что так вовсе и не правельно? Просто я хочу делать как надо - скорость выполнения и принцип работы скрипта на высоте(как сказал а?). Интересно как делают профи?
Что касается простого сайта, его я уже сделал, надо же идти дальше!
-SCHATTEN-
Отправлено: 02 Марта, 2007 - 11:58:08
Пользователь
Покинул форум
Сообщений всего: 615
Дата рег-ции: Июль 2006 Откуда: Оттуда !
Помог: 0 раз(а)
Смотри в соседней теме, я там примерно обьяснил, далше сами додумывайте.
Ато обленитесь совсем =)))
de'vovan
Отправлено: 02 Марта, 2007 - 12:26:00
Новичок
Покинул форум
Сообщений всего: 37
Дата рег-ции: Дек. 2006 Откуда: Ейск
Помог: 0 раз(а)
-SCHATTEN- пишет:
Смотри в соседней теме, я там примерно обьяснил, далше сами додумывайте.
Ато обленитесь совсем =)))
И на том спасибо!.........
-SCHATTEN-
Отправлено: 02 Марта, 2007 - 16:43:27
Пользователь
Покинул форум
Сообщений всего: 615
Дата рег-ции: Июль 2006 Откуда: Оттуда !
Помог: 0 раз(а)
de'vovan
В твоем случае ты можешь в адресной строке передовать имена файлов, и папки где они лежат.
ну например : index.php?dir=modul&file=filename&....
$fo=file_get_contents("./$dir/$file.php");//помещаешь содержимое файла в переменную
echo$fo// выводишь содержимое
Я надеюсь ход мыслей понятен... Скрипт сочинял находу и не проверял, может немного с сиснаксисом ошибся...
de'vovan
Отправлено: 02 Марта, 2007 - 22:53:16
Новичок
Покинул форум
Сообщений всего: 37
Дата рег-ции: Дек. 2006 Откуда: Ейск
Помог: 0 раз(а)
Спасибки, скрипт не проблема, главное сама идея!
Вопрос на засыпку: у меня скрипт правки статей автоматом проставляет экранирование для двойных кавычек, что бы небыло ошибок при записи в БД. На локалке все было путем, а у хостера символы экранирования остаются и записываются в БД как текст, что сильно портит вид, например, фотки не отображаются. Что можно сделать?
-SCHATTEN-
Отправлено: 03 Марта, 2007 - 15:26:17
Пользователь
Покинул форум
Сообщений всего: 615
Дата рег-ции: Июль 2006 Откуда: Оттуда !
Помог: 0 раз(а)
Если честно никогда не сталкивался... даже представления не имею о этой проблеме... попробуй убрать скрипт который экранирует и написать все запросы правильно ....
Dagdamor
Отправлено: 03 Марта, 2007 - 15:38:04
Новичок
Покинул форум
Сообщений всего: 15
Дата рег-ции: Февр. 2007 Откуда: Барнаул
Помог: 0 раз(а)
de'vovan
Попробуй на хостинге создать в корневой папке сайта файл .htaccess, а в нем написать такую строку:
php_flag magic_quotes_gpc On
Если не поможет, попробуй тоже самое с Off вместо On.
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.