РНР 5 в подлиннике

Страница 48 из 554


98

Часть I. Основы Web-программирования

Если нужно указать браузеру, что в какой-то форме следует применять другой формат передачи, следует в соответствующем теге <form> задать атрибут enctype=muitipart/form--data. (Кстати говоря, если этот атрибут не указан, то форма

считается обычной, ЧТО эквивалентно enctype=application/x-www-form-urlencoded —

именно так обозначается привычный нам формат передачи.) После этого данные, поступившие от нашей формы, будут выглядеть как несколько блоков информации (по одному на элемент формы). Каждый такой блок очень напоминает HTTP-формат "заголовки—данные", используемый при традиционном формате передачи. Выглядит блок примерно так (\п, как всегда, обозначает символ перевода строки):

-----------------Идентификатор_начала\п

Content-Disposition: form-data; пате="имя"\п \п

значение\п

Например, пусть у нас есть форма, представленная листингом 3.7.

; Листинг 3.7. Файл multipart.htm

<form action="upload.cgi" enctype="multipart/form-data" method=post>

Name: <input type=text name="Name" value="Moe имя"><Ьг>

Box: <input type=checkbox name="Box" value=l checkedxbr>

Area: <input type=textarea пат'е="Агеа">Какой-то TeKCT</textareaXbr>

<input type=submit> </form>

Данные, поступившие после нажатия кнопки submit на сервер, будут иметь следующий вид:

----------------127462537625367\п

Content-Disposition: form-data; name="Name"\n \n

Мое имя\п

----------------127462537625367\n

Content-Disposition: form-data; name="Box"\n

\n

l\n

----------------127462537625367\n

Content-Disposition: form-data; name="Area"\n \n

Какой-то текст\п

Заметьте, что несколько дефисов и число (которое мы ранее назвали идентификатор_начала) предшествуют каждому блоку. Более того, строка из дефисов и этого числа служит своеобразным маркером, который разделяет блоки. Очевидно, эта строка должна быть уникальной во всех данных. Именно так ее и формирует браузер. Правда, сказанное означает, что сегодня идентификатор будет одним, а завтра, возможно, совсем другим. Так что нам придется, прежде чем анализировать данные, считать этот идентификатор в буфер (им будет последовательность символов до первого символа \п).

Гпава 3. CGI изнутри

99

Стандарт протокола HTTP регламентирует, что идентификатор начала также должен быть доступен через одну из переменных окружения. Но мы не помним и не хотим знать ее название — сейчас объясним, почему. Некоторые браузеры (особенно старые) путают этот идентификатор и присылают его непра-зильно— с двумя предшествующими минусами (а остальные— без них), так что сценарии, не рассчитывающие на такой подвох, перестанут работать. Никогда не полагайтесь на эту переменную окружения (даже если узнаете, как она называется)! Вместо этого читайте последовательность символов до первого перевода строки и воспринимайте именно ее как разделитель.

Далее алгоритм разбора должен быть следующим: в цикле мы пропускаем символы идентификатора и перевода строки, извлекаем подстроку имя="что-то" (не обращая внимания на Content-Disposition), дожидаемся двух символов перевода строки и затем считаем значением соответствующего поля все те данные, которые размещены до строки \пИдентифмкатор (или же до конца, если такой строки больше нет). Как видите, все довольно просто.

Стандарт HTTP предписывает, чтобы перевод строки содержал два символа— \r\n, а не один \п. Как вы уже, наверное, чувствуете, существуют браузеры, которые об этом и не догадываются и посылают только один \п. Так что, будьте готовы к тому, чтобы правильно обрабатывать и эту ситуацию.

Теперь вернемся к тому, с чего начали — к загрузке файлов. Сначала выясним, какой тег надо вставить в форму, чтобы в ней появился соответствующий элемент управления — поле ввода текста с кнопкой Browse справа. Таким тегом является разновидность <input>:

<input type=file пате=имя элемента

Пусть пользователь выбрал какой-то файл (скажем, с именем каталог\имя_фаша) и нажал кнопку отправки. В этом случае для нашего элемента формы создается один блок примерно такого вида1:

Content-Disposition: form-data; пате="имя_злемента"; ^ f±lename="каталог\лмя_файла"\п \п

Бинарные данные этого файла любой длины. Здесь могут быть совершенно любые байты без всякого ограничения.

Тег загрузки файла (file)

>

127462537625367\п

\п

Символ Ь означает перенос строки в книге, и его не следует вводить при наборе текста программы.




  Hostland.Ru

 «Бесплатный хостинг Hostland.Su» © 2006