Теперь, когда мы научились получать доступ и манипулировать данными, введенными пользователем в HTML-форму, можно приступить к рассмотрению способов сохранения этой информации с целью будущего ее использования. В большинстве случаев, включая пример, данные необходимо сохранять и позже загружать хи для использования. В рассматриваемом случае нужно записывать формы заказов клиентов в некоторое хранилище, чтобы позднее их можно было обслужить.
Мы рассмотрим, как созданную в предшествующем примере форму заказа клиента сначала записать в файл, а затем прочитать ее из файла. Мы рассмотрим также, почему это решение не всегда является наилучшим. При наличии большого количества заказов необходимо пользоваться системой управления базами данных, такой как MySQL.
Существует два основных способа хранения данных: в двумерных файлах и в базах данных.
Двумерный файл может иметь множество форматов, но в общем случае под двумерным, или плоским файлом (flat) мы будем понимать простой текстовой файл. В рассматриваемом ниже примере заказы клиентов записываются в текстовой файл, по одному заказу в каждой строке.
Этот способ весьма прост, в тоже время он ограничивает использование средств манипулировния данными. Если вам приходится иметь дело с информацией объема, который традиционно встречается в реальных приложениях, вы, скорее всего, отдадите предпочтение какой-то базе данных. Тем не менее, двумерные файлы находят достаточно широкое применение, поэтому в некоторых случаях нужно знать, как ими пользоваться.
Здесь мы будем пользоваться формой заказа, несколько измененной по сравнению с той , что была ранее. В изменившуюся форму, включим адрес доставки товара клиента.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Компания АВС. Исходная форма заказа запчастей</title>
</head>
<body>
<form action="processorder.php" method="post">
<table width="500" border="0">
<tr bgcolor="#000066">
<td width="200" style="color:#FFF">Наименование товара</td>
<td width="20" style="color:#FFF">Количество</td>
</tr>
<tr>
<td>Фильтры масленные</td>
<td><input name="filtr" type="text" size="3" maxlength="3"></td>
</tr>
<tr>
<td>Фильтры воздушные</td>
<td> <input name="filtr_v" type="text" size="3" maxlength="3"></td>
</tr>
<tr>
<td>Свечи зажигания</td>
<td> <input name="sparkqty" type="text" size="3" maxlength="3"></td>
</tr>
<tr>
<td>Адрес доставки</td>
<td> <input name="address" type="text" size="35" maxlength="70"></td>
</tr>
<tr>
<td colspan="2" align="center"><input name="" type="submit" value="Отправить заказ"></td>
</tr>
</table>
</form>
</body>
</html>
Поле формы, предназначенное для ввода адреса доставки, имеет имя address. В результате мы получим переменную, к которой в РНР-коде можно обращаться как к $_REQUEST ['addess'], $_POST ['addess'], $GET ['addess'] в зависимости от метода отправки данных формы.
Все поступающие заказы записываются в один и тот же файл. Затем создается интерфейс, чтобы служащие компании смогли просматривать полученные заказы.
Чтобы записать некоторые данные в файл, необходимо выполнить следующие три действия:
Аналогично, чтобы прочитать данные из файла, необходимо также выполнить три действия:
Если вы собираетесь читать данные из файла, то должны выбрать, какую часть файла следует считывать за один раз. Ниже мы рассмотрим эти действия более подробно.
Для открытия файла в РНР существует функция fopen (). При этом необходимо указать, как он будет использоваться. Способ использования носит название режима файла.
Операционная система установленная на сервере, должна знать, что вы намереваетесь делать с открываемым файлом. Она должна знать, может ли соответствующий файл быть открыт другим сценарием в то время, когда он уже открыт вашим сценарием, и обладаете ли вы (либо владелец сценария) правами на подобное его использование. По сути, режимы файла предоставляют операционной системе механизм выбора способа обработки запросов на доступ, поступающих от других пользователей или сценариев, а также метода проверки, имеете ли вы доступ и права на работу с конкретным файлом.
Открывая файл, вы должны принять во внимание три момента:
Функция fopen () поддерживает любые комбинации трех упомянутых вариантов.
Предположим, что требуется сохранить заказ клиента в файле заказов компании АВС. Этот файл можно открыть для записи с помощью следующего оператора:
$fp = fopen ("$DOCUMENT_ROOT/../orders/orders.txt", 'w');
При вызове функции fopen ()необходимо передать два или три параметра. Обычно используются два параметра, как показано в приведенной выше строке кода.
Первым параметром должен быть файл, который должен быть открыт. При этом можно указать путь к файлу, как было сделано в приведенной выше строке кода — файл orders.txt находится в каталоге orders/. Мы использовали встроенную РНР-переменную $_SERVER ['DOCUMENT_ROOT'], но поскольку полные имена переменных слишком громоздкие, ей было присвоено короткое имя.
Эта переменная указывает на основание дерева документов используемого вами веб-сервера. Кроме того, с помощью символа .. был обозначен "родительский каталог корневого каталога документов". Мы не хотим, чтобы этот файл был доступен в веб, кроме как только через предоставляемый нами интерфейс. Этот путь называется относительным, поскольку он описывает позицию в файловой системе относительно корня дерева документов.
Как и в случае коротких имен, которые присваиваются переменным формы, в начале сценария должна находиться следующая строка:
$DOCUMENT_ROOT =$_SERVER ['DOCUMENT_ROOT'];
которая скопирует содержимое переменной длинного стиля в переменную короткого стиля.
Подобно тому, как существуют различные способы доступа к данным формы, точно также существуют различные способы доступа к зарезервированным серверным переменным. В зависимости от настройки вашего сервера, вы можете получить доступ к корню дерева документов, воспользовавшись именами:
$_SERVER ['DOCUMENT_ROOT']
$DOCUMENT_ROOT
$HTTP_SERVER_VARS ['DOCUMENT_ROOT']
Как и для данных формы, первый стиль является наиболее предпочтительным.
Мы можем задать любой путь к файлу. Этот путь ведет от корневого каталога (/ в системе UNIX и, как правило, C:\ в системе Windows). На используемом сервере на базе UNIX таким путем будет /home/book/orders. Проблема, связанная подобным представлением пути, особенно если вы размещаете собственный сайт на чужом сервере, заключается в том, что абсолютный путь может меняться.
Если путь не указан, система создает файл или будет его искать в том же каталоге, в котором находится сам сценарий. Действия системы будут иными, если среда РНР функционирует в рамках той или иной оболочки CGI (общий шлюзовой интерфейс) и зависит от конфигурации сервера.
В среде UNIX в качестве разделителя каталогов используется левая косая черта (/). На Windows-платформах можно применять как левую, так и обратную косую черту (\). Если вы используете обратную косую черту, то она должна быть отменена (помечена как специальный символ), чтобы функция fopen () смогла правильно ее интерпретировать. С этой целью перед ней достаточно просто поместить еще один символ обратной косой черты, например так:
$fp = fopen ("$DOCUMENT_ROOT \\ ..\\orders\\orders.txt", 'w');
Обратную косую черту в пути применяют лишь очень немногие программисты, поскольку в результате код может функционировать только в Windows-средах. Если отдать предпочтение левой косой черте, то код может свободно работать в любой среде.
Второй вариант функции fopen () —это режим файла, этот параметр должен иметь строковой тип. Передаваемая функции строка указывает, что вы намерены делать с файлом. В данном случае в функции fopen () передается параметр 'w', что означает открытие файла для записи.
Таблица. Режимы файла для функции fopen ()
Режим | Значение |
r | Режим чтения. Открывает файл для чтения, начиная с начала файла. |
r+ | Режим чтения. Открывает файл для чтения и записи, начиная с начала файла. |
w | Режим записи. Открывает файл для записи, начиная с начала файла. Если файл уже существует, его содержимое удаляется. Если файл не существует, пытается создать его. |
w+ | Режим записи. Открывает файл для записи и чтения, начиная с начала файла. Если файл уже существует, его содержимое удаляется. Если файл не существует, пытается создать его. |
x | Режим осторожной записи. Открывает файл для записи, начиная с начала файла. Если файл уже существует, он не открывается, fopen () возвращает значение false, а РНР генерирует предупреждение. |
x+ | Режим осторожной записи. Открывает файл для записи и чтения, начиная с начала файла. Если файл уже существует, он не открывается, fopen () возвращает значение false, а РНР генерирует предупреждение. |
a | Режим добавления. Открывает файл только для добавления (записи), начиная с конца существующего содержимого, если таковое имеется. Если файл не существует, пытается его создать. |
a+ | Режим добавления. Открывает файл только для добавления (записи) и чтения, начиная с конца существующего содержимого, если таковое имеется. Если файл не существует, пытается его создать. |
b | Бинарный режим. Используется в сочетании с одним из остальных режимов. Вы можете воспользоваться этим режимом в тех случаях, когда файловая система различает бинарные и текстовые файлы. Операционная система Windows различает эти файлы, тогда как UNIX — нет. Разработчики РНР рекомендуют указывать этот режим для максимальной переносимости. Этот режим используется по умолчанию. |
t | Текстовый режим. Используется в сочетании с одним из остальных режимов. Этот режим актуален только для Windows-систем. Применять его не рекомендуется за исключением случаев, когда выполняется перенос существующего кола с опцией b. |
В рассматриваемом примере используемый режим файла зависит от установленной на сервере системы. выше была выбрана строка 'w', которая позволяет записывать в файл только один заказ. При приеме каждого нового заказа он будет перезаписывать ранее сохраненный заказ. Скорее всего это не совсем удачное решение, поэтому целесообразно установить режим добавления (и, как рекомендуется бинарный режим):
$fp = fopen ("DOCUMENT_ROOT/ .. /orders/orders.txt", 'ab');
Третий параметр функции fopen () является необязательным. Вы можете воспользоваться этим параметром, если требуется искать файл с помощью include_path (настройка конфигурации РНР). Если этот так, установите значение третьего параметра равным true. В этом случае отпадает необходимость задавать имя каталога или путь:
$fp = fopen ("orders.txt, 'ab', true);
Четвертый параметр функции fopen () также необязательный. Функция fopen ()позволяет предварять имена файлов наименованием протокола (таким как http://) и открывать их в удаленных местоположениях. Некоторые протоколы допускают дополнительный параметр.
Когда функция fopen () успешно открывает файл, она возвращает указатель на файл и сохраняет его в специальной переменной, в данном случае $fp. Эта переменная впоследствии используется для доступа к файлу, когда необходимо выполнить чтение или запись.