Так сложилось, что большинство веб-разработчиков при создании веб-приложений используют в качестве операционной системы Windows, в то время как большинство серверов работает под управлением UNIX, которая имеет отличную от Windows систему прав и доступа.
В UNIX права доступа выставляются для трех групп:
Для каждой из групп права доступа задаются восьмеричным числом. При этом праву чтения соответствует цифра 4, праву записи — 2, а исполнению — 1. Общие права задаются суммой этих чисел. Так значение 6(4+2) обеспечивает возможность чтения и записи, а значение 7(4+2+1) представляет полный доступ к файлу или каталогу.
Для файлов наиболее приемлемые права доступа таковы: чтение и запись для владельца и чтение для всех остальных — 644. Для того чтобы иметь возможность "заходить" в каталог, для него необходимо выставить права доступа и на исполнение, поэтому для каталогов следует выставлять 755.
Для смены прав доступа в РНР предназначена функция chmod(), которая имеет следующий синтаксис:
dool chmod(string filename, int mode) —принимает в качестве первого параметра имя файла filename, в качестве второго mode — восьмеричное число, задающее права доступа к файлу.
Примечание. Восьмеричное число в РНР редваряется 0, например 0755. Число 755 не является восьмеричным и будет интерпретироваться как десятичное.
Пример.
<?php
/*Изменяем права доступа к файлу. Для указания принадлежности числа к восьмеричной системе, перед ним записывается 0*/
chmod("index.php", 0644);
?>
Если требуется изменить права доступа сразу ко всем файлам каталога, следует воспользоваться скриптом:
<?php
//открываем каталог
$dir = opendir("dir_name");
//в цикле считываем его содержимое
while(($file = readdir($dir))
{
//если текущий объект является файлом, изменяем права доступа
if(is_file($file)) chmod($file, 0644);
}
//закрываем каталог
closedir($dir);
?>
Создание каталога производится с помощью функции mkdir().
dool mkdir(string dirname, int mode) — создает каталог с именем dirname и правами доступа, определяемыми восьмеричным числом mode. В случае неудачи возвращает false.
Пример:
<?php
if(mkdir("test",0700)) echo "Каталог успешно создан";
else echo "Ошибка создания каталога";
?>
Удалить каталог можно с помощью функции rmdir().
bool rmdir(string dirname) — принимает имя каталога dirname и возвращает true в случае удачного удаления каталога и false при неудаче.
Пример:
<?php
if(rmdir("С:/temp/test")) echo "Каталог успешно удален";
?>
Функция rmdir() удаляет только пустые каталоги. Для удаления непустого каталога необходимо удалить все файлы, содержащиеся в нем.
Пример:
<?php
/*Рекурсивная функция удаления каталога с произвольной степенью вложенности*/
function full_del_dir($directory)
{
$dir=opendir($directory);
while(($file=readdir($dir)))
{
//если функция readdir() вернула файл, удалим его
if(is_file("$directory/$file")) unlink("$directory/$file");
/*если функция readdir() вернула каталог и он не равен текущему или родительскому, осуществляем рекурсивный вызов full_del_dir() для этого каталога*/
else if (is_dir("$directory/$file")&&
$file!="."&&
$file!="..")
{
full_del_dir("$directory/$file");
}
}
closedir($dir);
rmdir($directory);
echo "Каталог успешно удален";
}
full_del_dir("test");
?>
При рекурсивном вызове функции не следует передавать в качестве аргументов записи "." и "..".
Используя функции для работы с файлами, можно организовать редактирование файлов на сервере при помощи веб-интерфейса, код которого представлен ниже:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Редактирование файлов на сервере</title>
</head>
<body>
<?php
//файл 301.php
/*Если передано исправленное содержимое файла, открываем файл и перезаписываем его*/
if(isset($_POST['content']))
{
//открываем файл
$fd=@fopen($_POST['filename'],"w");
/*если файл не может быть открыт, сообщаем об этом предупреждением в окне браузера*/
if(!$fd) exit ("Такой файл отсутствует");
//перезаписываем содержимое файла
fwrite($fd, stripslashes($_POST['content']));
//закрываем файл
fclose($fd);
//помещаем в суперглобальный массив $_GET имя файла
$_GET['filename']=$_POST['filename'];
}
?>
<form action="301.php" method="get" name="first">
Имя файла<br><input name="filename" type="text" value="<?php echo $_GET['filename'];?>" size="25"><br>
<input name="" type="submit" value="Отправить">
</form>
<?php
//если в строке запроса передано имя файла, открываем его для редактирования
if(isset($_GET['filename']))
{
//откраваем файл
$fd=@fopen($_GET['filename'], "r");
/*если файл не может быть открыт сообщаем об этом предупреждением в окне браузера*/
if(!$fd) exit ("Такой файл отсутствует");
//помещаем содержимое файла в переменную $bufer
$bufer=fread($fd, filesize($_GET['filename']));
//закрываем файл
fclose($fd);
?>
<form action="301.php" method="post" name="second">
<textarea name="content" cols="76" rows="10"><?php echo $bufer;?></textarea><br>
<input name="filename" type="hidden" value="<?php echo $_GET['filename'];?>">
<input name="edit" type="submit" value="Редактировать">
</form>
<?php
}
?>
</body>
</html>
В окне веб-браузера это будет выглядеть примерно так:
При первой загрузке скрипта открывается форма first, имеющая единственное текстовое поле filename для имени файла и кнопку, отправляющую данные методом GET файлу 301.php, котором расположен этот скрипт. Если элемент суперглобального массива $_GET['filename'] не пуст, то происходит загрузка содержимого файла во временную переменную $bufer, содержимое которой помещается в текстовую область формы second.
Помимо текстовой области content, форма содержит скрытое поле filename, через которое передается имя файла. После редактирования и нажатия кнопки второй формы second данные повторно отправляются скрипту 301.php, но уже методом POST. В начале скрипта размещен обработчик, который в том случае, если элемент $_POST['content'] принимает не пустое значение, переписывает содержимое редактируемого файла. Для корректного поведения скрипта в конце обработчика имя файла из суперглобального массива $_POST переписываются в суперглобальный массив $_GET. Функция fopen() предваряется знаком @, который подавляет вывод предупреждений в окно браузера, в том случае если функция не может найти текстовой файл.
Часто присоздании веб-приложений, основанных на хранении информации в файлах, требуется изменение их содержимого. Решение такого рода задач осуществляется по единой схеме, представленной ниже.
<?php
//имя файла
$filename="text.txt";
//открываем файл
$fd=fopen($filename,"r");
//читаем его содержимое в буфер
$buffer=fread($fd, filesize($filename));
//закрываем файл
fclose($fd);
//редактируем содержимое переменной $buffer
//....
//записываем в файл новое содержимое
$fd=fopen($filename, "w");
//записываем содержимое строки $buffer
fwrite($fd, $buffer);
//закрываем файл
fclose($fd);
?>
Файл, над которым необходимо совершить преобразования, открывается, и его содержимое подвергается редактированию. Затем файл повторно открывается и перезаписывается уже измененным содержимым.
Рассмотрим пример. Пусть имеется текстовой файл proba.txt следующего содержания:
107 Разное
108 Экскурсии и туризм
109 Пищевые продукты
3202 Строительство
12345 Реклама
3245 Транспорт
Задача состоит в удалении цифр, в начале каждой строки файла, и выводе результата в окно браузера. Для решения этой задачи удобно использовать регулярные выражения.
<?php
//имя файла
$filename="proba.txt";
//помещаем содержимое файла в массив $line
$lines=file($filename);
//в цикле извлекаем из строки текстовую часть строки
foreach($lines as $line)
{
echo preg_replace("/\d{1,}\s([^\(]*)\s\(?.*/","\\1", $line);
echo "<br>";
}
?>
Рассмотрим следующую распространенную задачу, связанную в первую очередь ссозданием различных файловых счетчиков посещений и учета обращения к ресурсам. Пусть имеется текстовой файл count.txt следующего формата:
first=34
second=56
third=14
fourth=48
В задачу создаваемого скрипта будет входить увеличение числа при передаче скрипту в качестве параметра page левого значения из текстового файла count.txt. Эту проблему решает скрипт, представленный ниже, в котором используется функция обратного вызова.
<?php
//извлекаем из строки запроса параметр page
$page=$_GET['page'];
//имя файла
$filename="count.txt";
//открываем файл для чтения
$fd=fopen($filename, "r");
//читаем его содержимое в буфер
$bufer=fread($fd, filesize($filename));
//закрываем файл
fclose($fd);
// редактируем содержимое переменной
$bufer=preg_replace_callback("|($page=)([\d]+)|i", "increment_number", $bufer);
//открываем файл для записи
$fd=fopen($filename, "w");
//записываем содержимое строки $bufer
fwrite($fd, $bufer);
//закрываем файл
fclose($fd);
//функция обратного вызова
function increment_number($matches)
{
return $matches[1]. (++$matches[2]);
}
?>
Запускаем скрипт. Откроем файл count.txt. Результат работы скрипта:
first=35
second=57
third=15
fourth=49
Удаление данных из середины файла является достаточно распространенной задачей. Будем использовать рассмотренный в предыдущем примере файл count.txt, но теперь станем не увеличивать значение счетчика на единицу приобращениик странице, а уменьшать все числовые значения, причем, если число принимает значение 0, то его будем удалять из файла.
<?php
//имя файла
$filename="count.txt";
//получаем содержимое файла в виде массива строк
$lines=file($filename);
//в эту строку будем складывать новые строки файла
$data="";
//обработку данных производим в цикле
foreach($lines as $index=>$line)
{
$parent="|^([^ ]+)=([^\n]+)|i";
preg_match($parent, $line, $out);
//если число равно 0, то пропускаем цикл
//исключая тем самым строку из конечной строки $data
$out[2]--;
$data .="$out[1]=$out[2]\n";
echo "$out[1]=$out[2] <br>";
}
//записываем новые данные в файл
$fd=fopen($filename, "w");
fwrite($fd, $data);
fclose($fd);
?>
Запускаем скрипт. Результат работы скрипта:
first=35
second=57
third=15
fourth=48
При создании блока "Афоризм дня" или ленты "Анегдоты" часто встает задача выборки из текстового файла случайных строк. Для решения данной задачи необходимо использование функции rand(), которая имеет следующий синтаксис:
int rand([int min, int max]) — генерирует случайное целое число между двумя целочисленными параметрами min и max. Если необязательные параметры min и max не указаны, число выбирается из диапазона [0; RAND_MAX(32768)].
Примечание. Традиционно генератор случайных чисел инициировался временной отметкой вручную, в противном случае генератор всегда формировал одну и ту же последовательность случайных цифр. В РНР эту задачу выполняла функция srand(). Начиная с версии РНР 4.2, было принято решение делать это автоматически, и теперь в инициализации генератора нет необходимости, хотя это не возбраняется и оставлено для обратной совместимости со старым кодом.
Пусть имеется текстовой файл, в каждой строке которого содержатся данные для вывода в окно браузера. Будем для этого использовать файл count.txt, рассмотренный выше. Тогда задачу случайного вывода можно решить при помощи скрипта, представленного ниже.
<?php
//имя файла
$filename="count.txt";
//помещаем содержимое файла count.txt в массив $lines
$lines=file($filename);
//генерируем случайный индекс массива $lines
$index=rand(0, count($lines)-1);
//выводим строку с номером $index
echo $lines[$index];
?>
Результат работы скрипта может быть следующим:
second=56