ГЛАВА 6. РНР:ПАПКОПОТРОШИЛКА
При создании Интернет-ресурса, содержащего часто обновляющееся однотипное содержание, проблема быстроты и удобства обновления встает достаточно остро. Например, вы являетесь администратором сайта, на котором размещаются статьи разных авторов. В таком случае при поступлении новой статьи вам приходится, помимо размещения на web-сервере (или выделенном вам аккаунте) ее самой, еще и обновлять страницу со списком этих статей, добавив ссылку на новоразмещенную web-страницу со статьей - иначе ведь попасть на новую статью с сайта будет невозможно. А если статьи поступают часто? Да еще и не только поступают, но и удаляются, или в них меняется название? Тогда ведь для отслеживания правильности содержания приходится прилагать немало усилий.
Или другая ситуация - необходимо разместить на сайте новостную ленту. Простое решение напрашивается сразу: просто включать текст новостей в содержащую их страницу. Или, в.крайнем случае, писать новости в отдельном файле, а в web-страницу включать этот файл с помощью команды PHP include - тогда при обновлении новостей придется загружать на сервер только файл с новостями, а не всю страницу. Но все же... не так это и удобно! Каждый раз работать с файлом с гипертекстовой разметкой, каждый раз его загружать на сайт... А если вам надо поручить загрузку человеку, который совершенно не знает HTML? Текст-то он напишет, а вот вставить его в нужное место гипертекстовой разметки?
Или, наконец, третья ситуация - вы делаете файловый архив, и ваши друзья загружают на ваш сервер свои файлы. Как сделать так, чтобы они появлялись в списке доступных для посетителей файлов сразу же после их загрузки, без вашего участия, без необходимости вручную обновлять их список?
Приведенный ниже сценарий на языке РНР пригодится вам во всех трех случаях. Вкратце его алгоритм прост: при вызове содержащей его страницы он пробегает по всем файлам в указанной в сценарии директории и составляет их список. А с этим списком можно уже сделать все что хочется: либо включить их содержимое друг за другом в выводимую web-страницу, либо составить каталог файлов.
Итак - вот сценарий:
<?php
Сначала укажем сценарию имя папки, в которой содержатся подлежащие каталогизации или включению в другую страницу файлы:
$dirct="new";
Для того чтобы РНР мог работать с файлами из этой папки, необходимо указать ее дескриптор - некое "внутреннее имя", "поток вывода данных" (о том, почему приходится так делать, смотрите литературу по РНР и программированию, пока же просто примите к сведению). Для этого используется функция opendir (каталог), а получаемый с ее помощью дескриптор записывается в переменную $hdl:
$hdl=opendir($dirct);
Теперь запишем все имена содержащихся в ней файлов в массив $а [ ]. Согласно синтаксису РНР (см. гл. 3), для этого достаточно просто присваивать массиву $а [ ] различные значения - при этом автоматически в него будут добавляться новые члены, которым эти значения будут присваиваться. Для помещения имен файлов (с расширениями) из директории $dirct в массив используется функция readdir (имя каталога), работающая с дескриптором этой директории, записанным ранее в переменную $hdl с'помощью функции opendir.
Комментарий:
Функция readdir предназначена для вывода списка файлов и папок, содержащихся в указанном в ее параметре каталоге. При каждом своем вызове она выдает имя случайно выбранного файла (или вложенной папки) указанного каталога, каждый раз - новое, до тех пор, пока не перечислит имена всех файлов и вложенных папок.
Среди выданных функцией readdir имен будут и ссылки на текущий и родительский (т. е. включающий в себя текущий) каталог, обозначаемые соответственно одной и двумя точками (так уж работает web-сервер). Поскольку нас интересуют только файлы каталога, то данные ссылки из списка файлов следует исключить, добавив проверку состава имени файла.
while ($file = readdir($hdl))
if ( ($file!=".")&&($file!="..")) $a[]=$file;
}
Теперь закроем открытую папку, очистив дескриптор (так необходимо) - функцией closedir (каталог):
closedir($hdl);
Список имен файлов папки, помещенный теперь в массив $а, содержит эти имена в случайном порядке - так их выдает функция readdir. Однако массив можно отсортировать - функциями asort (по алфавиту - прямое) или rsort (по алфавиту - обратное: с z до а). Использование сортировки массива даст возможность включать имена файлов или их содержимое в определенном порядке - достаточно лишь называть их так, чтобы они сортировались нужным образом (скажем, новости удобно именовать датой - файлы с ними могут иметь имена типа 20020901 .php, 20020902.php, тогда при прямой сортировке самые свежие файлы окажутся внизу списка, при обратной -вверху).
rsort($a);
Ну а теперь будем выводить имена по одному с начала массива до конца и использовать их по своему усмотрению. Для этого применим оператор foreach (переменная as массив), который считывает в указанную в его параметрах переменную все элементы массива по очереди, выполняя каждый раз указанный после него в фигурных скобках код, в котором указанная переменная может использоваться:
foreach ($a as $value) {
Комментарий:
Оператор foreach будет работать только вРНР 4.0 и выше. Если вы можете использовать лишь РНРЗ, то вместо него можно использовать немного более громоздкий код - вначале определим размер полученного списка:
$l=sizeof($a);
а затем выполним нижеследующий цикл для каждого элемента массива с помощью цикла for, указав в его параметрах узнанную величину массива:
for ($k = 1; $k < $1; $k++)
Для удобства можно записать значение очередного элемента массива в переменную:
$value=$a[$k]; и получится практически полный аналог оператора for each.
Дальнейший текст сценария зависит от ваших потребностей (и одинаков как для оператора f oreach, так и при использовании цикла for).
Чтобы вывести простой список файлов в папке $dirct, состоящий из гиперссылок на них, можно использовать такую команду, поместив ее в это место сценария:
echo ("<a href = $dirct/$value>$value</axbr>") ;
Чтобы вставить в страницу содержимое всех файлов в папке Sdirct, можно применить команду include:
include ("$dirct/$value");
Данный способ, например, используется при выводе ленты обьяв-лений и новостей на уже упоминавшемся сайте www.harchikov.ru. в корневом каталоге сайта создана папка news, а на его заглавной странице размещен вышеприведенный сценарий (второй вариант -с использованием команды include)/Для помещения на сайт нового объявления администратору достаточно набрать его текст (при необходимости использовав html-разметку, но можно и без нее), поместить этот текст в файл, назвать файл цифровой записью даты создания объявления (для удобства работы и сортировки) и разместить его в папке news на сайте. Никакой редакции каких-либо страниц сайта не требуется. Для удаления объявления с сайта достаточно просто удалить файл с ним из папки news, и впредь выдаваемые посетителям страницы не будут включать в себя его содержимое. Весь процесс нетрудно поручить даже секретарше или полному "чайнику".
Однако для составления списка статей информации только об именах файлов мало. Ведь в таком списке желательно указать хотя бы название статьи и имя ее автора. Чтобы это сделать, можно, например, указывать эти данные в тэгах meta, включаемые в каждый файл со статьей, а узнать содержимое данных тэгов можно с помощью функции get_meta_tags (имя файла).
Комментарий:
функция get__meta_tags (имя файла) создает массив, элементов (В РНР компоненты массива могут иметь не только числовой индекс, но и имена, такой массив называется ассоциативным. Подробнее - в гл. 3.) которого соответствуют названиям мета-тэгов указанного в параметре функции файла (если, конечно, тако-дъге тэги там есть), а значения этих элементов - соответствующим значениям мета-тэгов.
Например, положим, что названия статей будем писать в мета-тэгах zagol, а имена авторов - в мета-тэгах author (т. е. в раздел <head> каждого файла со статьей нужно будет добавить строчки <meta name="zagol" content="3arоловок статьи "><meta name="author" content="ABTop статьи">). Тогда строки сценария, вытаскивающие из файла содержимое этих тэгов и помещающие их на страницу, будут выглядеть так:
$m=get_meta_tags("$dirct/$value");
echo "<a href=$dirct/$value>$m[zagol]</a> $m[author]<br>";
Использование этого способа иллюстрируется в примере на рис.6.1. В папке duel находится файл index.php сданным сценарием, а в папке stats - статьи. В каждом файле со статьей присутствуют мета-тэги zagol и author, в которых указаны названия статей и их авторы. При вызове файла index.php находящийся в нем сценарий пробегает по всем файлам в папке stats, вытаскивает из них мета-тэги и отображает их на странице. Номера в названиях файлов со статьями используются для установки очередности вывода ссылок на них.
Ну и конец сценария:
}
? >
Рис. 6.1. Публикация статей - одной закачкой. Без всяких иных изменений
При небольшой доработке возможности использования сценария можно серьезно расширить - скажем, генерировать с его помощью списки файлов в любой директории, а не только в указанной. Для этого следует убрать из сценария строку, жестко задавающую имя папки -в приведенном примере $dirct="new";, а значение переменной с именем подлежащей "потрошению" папки с файлами - $dirct -задавать через ссылку для вызова страницы. Если статьи разных номеров журнала помещаются в отдельные папки (например, соответственно называющиеся newsl, news2), то для того чтобы использовать одну и ту же страницу со сценарием для вывода оглавлений различных номеров, нужно указывать имя папки в передаваемой через адресную строку переменной, а впоследствии именно эту переменную использовать в сценарии в качестве имени "потрошимой" папки. Например, ссылки на той странице, откуда происходит переход на страницу со сценарием, могут выглядеть так:
glav.php?dirct=newsl, oglav.php?dirct=news2
и т. д., где oglav.php - страница со сценарием, a $dirct - переменная, в которую записывается имя папки (рис. 6.2).
Рис. 6.2. Один скрипт - на все папки
Таким образом, РНР может снять с web-мастера массу рутинного труда и позволит ему сосредоточиться непосредственно на содержимом сайта, что наверняка послужит только на пользу посетителям.
Данный сценарий, столь подробно разобранный в этой главе, будет нередко использоваться в последующих главах. Поэтому изучите его повнимательнее.
|