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 запроса

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: объясните плиз
de'vovan
Отправлено: 28 Февраля, 2007 - 07:06:15
Post Id



Новичок


Покинул форум
Сообщений всего: 37
Дата рег-ции: Дек. 2006  
Откуда: Ейск


Помог: 0 раз(а)




Здраствуйте, у меня небольшая проблемка, я знаю что на многих сайтах ссылки url имеют вид
CODE (text):
скопировать код в буфер обмена
  1. http://forum.php.su/post.php?action=new&forum=1
, объясните пожалуйста принцип работы таких конструкций, просто хочется научиться делать "как надо".

Как я понимаю, url записывается в переменную $str = $_SERVER['QUERY_STRING'];, затем разбивается функцией parse_str(); для получения масива. А что дальше, как по полученному массиву строить страницу, выводить контент?

Надеюсь я понятно объяснил, если возможно, ответьте как можно подробнее, буду признателен за помощь!Улыбка
 
 Top
-SCHATTEN-
Отправлено: 28 Февраля, 2007 - 08:40:06
Post Id



Пользователь


Покинул форум
Сообщений всего: 615
Дата рег-ции: Июль 2006  
Откуда: Оттуда !


Помог: 0 раз(а)




QUERY_STRING
Параметры, которые в URL указаны после вопросительного знака. Напомню, что они
доступны как при методе GET, так и при методе POST (если в последнем случае они
были определены в атрибуте action тэга <form>).

Передача параметров методом GET
Тут все просто. Все параметры передаются единой строкой (а именно, точно такой
же, какая была задана в URL после ?) в переменной QUERY_STRING. Единственная
проблема — то, что все данные поступят URL-кодированными. Так что нам понадо-
бится функция декодирования. Но это отдельная тема, пока мы не будем ее касаться.
Для того чтобы узнать значения полученных переменных в Си, нужно воспользовать-
ся функцией getenv(). Вот пример сценария на Си, который это обеспечивает.
Листинг 3.2. Работа с переменными окружения
PHP:
скопировать код в буфер обмена
  1. #include <stdio.h> // Включаем функции ввода/вывода
  2. #include <stdlib.h> // Включаем функцию getenv()
  3. void main(void) {
  4. // получаем значение переменной окружения REMOTE_ADDR
  5. char *RemoteAddr = getenv("REMOTE_ADDR");
  6. // ... и еще QUERY_STRING
  7. char *QueryString = getenv("QUERY_STRING");
  8. // печатаем заголовок
  9. printf("Content-type: text/htmlnn");
  10. // печатаем документ
  11. printf("<html><body>");
  12. printf("<h1>Здравствуйте. Мы знаем о вас все!</h1>");
  13. printf("Ваш IP-адрес: %s
  14. ",RemoteAddr);
  15. printf("Вот параметры, которые Вы указали: %s",QueryString);
  16. printf("</body></html>");
  17. }

Откомпилируем сценарий и поместим его в "CGI-каталог". Теперь в адресной строке
введем:
PHP:
скопировать код в буфер обмена
  1. http://www.myhost.com/cgi-bin/script.cgi?a=1&b=2
  2. Мы получим примерно такой документ:
  3. Здравствуйте. Мы знаем о Вас все!
  4. Ваш IP-адрес: 192.232.01.23
  5. Вот параметры, которые Вы указали: a=1&b=2
  6.  

Передача параметров методом POST
В отличие от метода GET, здесь параметры передаются сценарию не через перемен-
ные окружения, а через стандартный поток ввода (в Си он называется stdin). То
есть программа должна работать так, будто никакого сервера не существует, а она
читает данные, которые вводит пользователь с клавиатуры. (Конечно, на самом деле
никакой клавиатуры нет и быть не может, а заправляет всем сервер, который "изо-
бражает из себя" клавиатуру.)
Следует заметить очень важную деталь: то, что был использован метод POST,
вовсе не означает, что не был применен также и метод GET. Иными словами,
метод POST подразумевает также возможность передачи данных через URL-
строку. Эти данные будут, как обычно, помещены в переменную окружения
QUERY_STRING.
Но как же узнать, сколько именно данных переслал пользователь методом POST? До
каких пор нам читать входной поток? Для этого служит переменная окружения
CONTENT_LENGTH, в которой хранится строка с десятичным представлением числа
переданных байтов данных (разумеется, перед использованием ее надо перевести в
обычное число).
Модифицируем предыдущий пример так, чтобы он принимал POST-данные, а также
выводил и GET-информацию, если она задана:
Листинг 3.3. Получение данных POST
PHP:
скопировать код в буфер обмена
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. void main(void) {
  4. // извлекаем значения переменных окружения
  5. char *RemoteAddr = getenv("REMOTE_ADDR");
  6. char *ContentLength = getenv("CONTENT_LENGTH");
  7. char *QueryString = getenv("QUERY_STRING");
  8. // вычисляем длину данных — переводим строку в число
  9. int NumBytes = atoi(ContentLength);
  10. // выделяем в свободной памяти буфер нужного размера
  11. char *Data = (char *)malloc(NumBytes + 1);
  12. // читаем данные из стандартного потока ввода
  13. fread(Data, 1, NumBytes, stdin);
  14. // добавляем нулевой код в конец строки
  15. // (в Си нулевой код сигнализирует о конце строки)
  16. Data[NumBytes] = 0;
  17. // выводим заголовок
  18. printf("Content-type: text/htmlnn");
  19. // выводим документ
  20. printf("<html><body>");
  21. printf("<h1>Здравствуйте. Мы знаем о вас все!</h1>");
  22. printf("Ваш IP-адрес: %s
  23. ",RemoteAddr);
  24. printf("Количество байтов данных: %d
  25. ",NumBytes);
  26. printf("Вот параметры, которые Вы указали: %s
  27. ",Data);
  28. printf("А вот то, что мы получили через URL: %s",
  29. QueryString);
  30. printf("</body></html>");
  31. }

Странслируем этот сценарий и запишем то, что получилось, под именем script.cgi
в каталог, видимый извне как /cgi-bin/. Откроем в браузере следующий HTML-
файл с формой:
Листинг 3.4. POST-форма
PHP:
скопировать код в буфер обмена
  1. <html><body>
  2. <form action=/cgi-bin/script.cgi?param=value method=post>
  3. Name1: <input type=text name="name1">
  4.  
  5. Name2: <input type=text name="name2">
  6.  
  7. <input type=submit value="Запустить сценарий!">
  8. </form>
  9. </body></html>

Теперь, если набрать в полях ввода какой-нибудь текст и нажать кнопку, получим
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-декодирования
PHP:
скопировать код в буфер обмена
  1. // Функция преобразует строку данных st в нормальное представление.
  2. // Результат помещается в ту же строку, что была передана в параметрах.
  3. void UrlDecode(char *st) {
  4. char *p=st; // указывает на текущий символ строки
  5. char hex[3]; // временный буфер для хранения %XX
  6. int code; // преобразованный код
  7. // запускаем цикл, пока не кончится строка (то есть, пока не
  8. // появится символ с кодом 0, см. ниже)
  9. do {
  10. // Если это %-код ...
  11. if(*st == '%') { // тогда копируем его во временный буфер
  12. hex[0]=*(++st); hex[1]=*(++st); hex[2]=0;
  13. // переводим его в число
  14. sscanf(hex,"%X",&code);
  15. // и записываем обратно в строку
  16. *p++=(char)code;
  17. // указатель p всегда отмечает то место в строке, в которое
  18. // будет помещен очередной декодированный символ
  19. }
  20. // иначе, если это "+", то заменяем его на " "
  21. else if(*st=='+') *p++=' ';
  22. // а если не то, ни другое — оставляем как есть
  23. else *p++=*st;
  24. } while(*st++!=0); // пока не найдем нулевой код
  25. }

Функция основана на том свойстве, что длина декодированных данных всегда мень-
ше, чем кодированных, а значит, всегда можно поместить результат в ту же строку,
не опасаясь ее переполнения. Конечно, примененный алгоритм далеко не оптимален,
т. к. использует довольно медлительную функцию sscanf() для перекодирования
каждого символа. Тем не менее, это самое простое, что можно придумать, вот почему
я так и сделал.
Итак, теперь мы можем слегка модифицировать предыдущий пример сценария, за-
ставив его перед выводом данных декодировать их. Попробуем написать это так:
Листинг 3.6. Получение POST-данных с URL-декодированием
PHP:
скопировать код в буфер обмена
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. void main(void) {
  4. // получаем значения переменных окружения
  5. char *RemoteAddr = getenv("REMOTE_ADDR");
  6. char *ContentLength = getenv("CONTENT_LENGTH");
  7. // выделяем память для буфера QUERY_STRING
  8. char *QueryString = malloc(strlen(getenv("QUERY_STRING")) + 1);
  9. // копируем QUERY_STRING в созданный буфер
  10. strcpy(QueryString, getenv("QUERY_STRING"));
  11. // декодируем QUERY_STRING
  12. UrlDecode(QueryString);
  13. // вычисляем количество байтов данных — переводим строку в число
  14. int NumBytes = atoi(ContentLength);
  15. // выделяем в свободной памяти буфер нужного размера
  16. char *Data = (char*)malloc(NumBytes + 1);
  17. // читаем данные из стандартного потока ввода
  18. fread(Data, 1, NumBytes, stdin);
  19. // добавляем нулевой код в конец строки
  20. // (в Си нулевой код сигнализирует о конце строки)
  21. Data[NumBytes] = 0;
  22. // декодируем данные (хоть это и не совсем осмысленно, но выполняем
  23. // сразу для всех POST-данных, не разбивая их на параметры)
  24. UrlDecode(Data);
  25. // выводим заголовок
  26. printf("Content-type: text/htmlnn");
  27. // выводим документ
  28. printf("<html><body>");
  29. printf("<h1>Здравствуйте. Мы знаем о Вас все!</h1>");
  30. printf("Ваш IP-адрес: %s
  31. ",RemoteAddr);
  32. printf("Количество байтов данных: %d
  33. ", NumBytes);
  34. printf("Вот параметры, которые Вы указали: %s
  35. ",Data);
  36. printf("А вот то, что мы получили через URL: %s",
  37. QueryString);
  38. printf("</body></html>");
  39. }

Обратите внимание на строки, выделенные жирным шрифтом. Теперь мы используем
промежуточный буфер для хранения QUERY_STRING. Зачем? Попробуем поставить
все на место, т. е. не задействовать промежуточный буфер, а работать с переменной
окружения напрямую, как это было в листинге 3.5. Тогда в одних операционных сис-
темах этот код будет работать прекрасно, а в других — генерировать ошибку общей
защиты, что приведет к немедленному завершению работы сценария. В чем же дело?
Очень просто: переменная QueryString ссылается на значение переменной окруже-
ния QUERY_STRING, которая расположена в системной области памяти, а значит, дос-
тупна только для чтения. В то же время функция UrlDecode(), как я уже замечал,
помещает результат своей работы в ту же область памяти, где находится ее параметр,
что и вызывает ошибку.
Чтобы избавиться от указанного недостатка, мы и копируем значение переменной
окружения QUERY_STRING в область памяти, доступной сценарию для записи — на-
пример, в какой-нибудь буфер, а потом уже преобразовываем его. Что и было сделано
в последнем сценарии.
Несколько однообразно и запутанно, не так ли? Да, пожалуй. Но, как говорится, "это
даже хорошо, что пока нам плохо" — тем больше будет причин предпочитать PHP
другим языкам программирования (так как в PHP эти проблемы изжиты как класс).
 
 Top
de'vovan
Отправлено: 28 Февраля, 2007 - 13:41:33
Post Id



Новичок


Покинул форум
Сообщений всего: 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 -->
}
}

Даже мне ясно что крайне каряво, поэтому и спрашиваю, как правельно?
Сразу прошу прощения, я наверно ваще ламерПодмигивание!
 
 Top
-SCHATTEN-
Отправлено: 28 Февраля, 2007 - 14:32:59
Post Id



Пользователь


Покинул форум
Сообщений всего: 615
Дата рег-ции: Июль 2006  
Откуда: Оттуда !


Помог: 0 раз(а)




Ну почему коряво ? Всё правильно, ты берешь из строки запроса номер новости и выводишь новость по этому номеру из БД.
 
 Top
de'vovan
Отправлено: 28 Февраля, 2007 - 21:19:38
Post Id



Новичок


Покинул форум
Сообщений всего: 37
Дата рег-ции: Дек. 2006  
Откуда: Ейск


Помог: 0 раз(а)




Спасибо за помощь!
Я тут придумал кое-что по теме, что скажите?
Имеем ссылки типа href="?content=module_...&parametr=valye"
При нажатии по ссылке открываем папку module_... и передаем файлу index.php параметр со значением valye (Что-то типа модулей в CMSке). Возможен ли такой вариант принципа работы динамического сайта с 1 страницей? И если возможно, каким образом можно передать параметр?

P.S. надеюсь я не сильно в дебри полез, просто очень уж нужен механизм построения динамического сайта.

 
 Top
de'vovan
Отправлено: 02 Марта, 2007 - 11:30:30
Post Id



Новичок


Покинул форум
Сообщений всего: 37
Дата рег-ции: Дек. 2006  
Откуда: Ейск


Помог: 0 раз(а)




Ребят, вы где?А?!
Может кто оценит мою задумку, или, хоть вкратце поделится своим способом (построения динамического сайта, когда есть только одна страница) ?
Оочень надоРастерялся
 
 Top
-SCHATTEN-
Отправлено: 02 Марта, 2007 - 11:45:21
Post Id



Пользователь


Покинул форум
Сообщений всего: 615
Дата рег-ции: Июль 2006  
Откуда: Оттуда !


Помог: 0 раз(а)




Зачем тебе это надо ? сделай простой сайт... Возьми книгу по CGI и почитай там как устроена строка адреса и как с ней работать...
+ стоит про работу с файлами в РНР почитать.
 
 Top
de'vovan
Отправлено: 02 Марта, 2007 - 11:55:03
Post Id



Новичок


Покинул форум
Сообщений всего: 37
Дата рег-ции: Дек. 2006  
Откуда: Ейск


Помог: 0 раз(а)




-SCHATTEN- пишет:
Зачем тебе это надо ? сделай простой сайт... Возьми книгу по CGI и почитай там как устроена строка адреса и как с ней работать...

Sorry, не понял, вы имеете в виду, что так вовсе и не правельно? Просто я хочу делать как надо - скорость выполнения и принцип работы скрипта на высоте(как сказал а?). Интересно как делают профи?
Что касается простого сайта, его я уже сделал, надо же идти дальше!Радость
 
 Top
-SCHATTEN-
Отправлено: 02 Марта, 2007 - 11:58:08
Post Id



Пользователь


Покинул форум
Сообщений всего: 615
Дата рег-ции: Июль 2006  
Откуда: Оттуда !


Помог: 0 раз(а)




Смотри в соседней теме, я там примерно обьяснил, далше сами додумывайте. Язычок
Ато обленитесь совсем =)))Радость
 
 Top
de'vovan
Отправлено: 02 Марта, 2007 - 12:26:00
Post Id



Новичок


Покинул форум
Сообщений всего: 37
Дата рег-ции: Дек. 2006  
Откуда: Ейск


Помог: 0 раз(а)




-SCHATTEN- пишет:
Смотри в соседней теме, я там примерно обьяснил, далше сами додумывайте. Язычок
Ато обленитесь совсем =)))Радость

И на том спасибо!.........Улыбка
 
 Top
-SCHATTEN-
Отправлено: 02 Марта, 2007 - 16:43:27
Post Id



Пользователь


Покинул форум
Сообщений всего: 615
Дата рег-ции: Июль 2006  
Откуда: Оттуда !


Помог: 0 раз(а)




de'vovan
В твоем случае ты можешь в адресной строке передовать имена файлов, и папки где они лежат.
ну например : index.php?dir=modul&file=filename&....
PHP:
скопировать код в буфер обмена
  1.  
  2. $dir = $_GET['dir'];
  3. $file = $_GET['file'];
  4. $fo = file_get_contents("./$dir/$file.php"); //помещаешь содержимое файла в переменную
  5. echo $fo // выводишь содержимое
  6.  


Я надеюсь ход мыслей понятен... Скрипт сочинял находу и не проверял, может немного с сиснаксисом ошибся...
 
 Top
de'vovan
Отправлено: 02 Марта, 2007 - 22:53:16
Post Id



Новичок


Покинул форум
Сообщений всего: 37
Дата рег-ции: Дек. 2006  
Откуда: Ейск


Помог: 0 раз(а)




Спасибки, скрипт не проблема, главное сама идея!
Вопрос на засыпку: у меня скрипт правки статей автоматом проставляет экранирование для двойных кавычек, что бы небыло ошибок при записи в БД. На локалке все было путем, а у хостера символы экранирования остаются и записываются в БД как текст, что сильно портит вид, например, фотки не отображаются. Что можно сделать?Растерялся

 
 Top
-SCHATTEN-
Отправлено: 03 Марта, 2007 - 15:26:17
Post Id



Пользователь


Покинул форум
Сообщений всего: 615
Дата рег-ции: Июль 2006  
Откуда: Оттуда !


Помог: 0 раз(а)




Если честно никогда не сталкивался... даже представления не имею о этой проблеме... попробуй убрать скрипт который экранирует и написать все запросы правильно ....
 
 Top
Dagdamor
Отправлено: 03 Марта, 2007 - 15:38:04
Post Id



Новичок


Покинул форум
Сообщений всего: 15
Дата рег-ции: Февр. 2007  
Откуда: Барнаул


Помог: 0 раз(а)




de'vovan
Попробуй на хостинге создать в корневой папке сайта файл .htaccess, а в нем написать такую строку:
php_flag magic_quotes_gpc On
Если не поможет, попробуй тоже самое с Off вместо On.
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Программирование на PHP »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB