Файлоимитатор своими руками


Прислал: Сергей Парижский [ 05.02.2008 @ 12:34 ]
Раздел:: [ Статьи по PHP ]


В этой статье я хочу разобрать разные способы использования РНР для манипуляций с файлами и директориями.


Для открытия файла служит функция fopen(), принимающая два аргумента — имя файла и режим, в котором его следует открыть. В результате возвращается дескриптор файла, с помощью которого мы будем работать с файлом далее. В таблице приведены все возможные режимы открытия файла.

1

При открытии файла часто используют функцию die(), которая выводит соответствующее сообщение, если произошла ошибка при открытии файла. Например:

$fp=fopen("1.txt","r") or die ("Ошибка при открытии файла 1.txt");

Теперь если при попытке открыть файл 1.txt в режиме чтения окажется, что такого файла нет, то будет выведено сообщение Ошибка при открытии файла 1.txt. Вообще, перед попыткой открытия файла неплохо делать проверку его существования. Это можно осуществить функциями file_exists() и is_file(). Они обе возвращают true, если файл существует и false, если файл не найден. Пример использования:

<?php
if (file_exists("1.txt")) echo "Файл существует!";
else echo "Файл не найден!";
?>

Если файл 1.txt существует, то мы получим соответствующее сообщение, в противном случае в браузере выведется строка Файл не найден.

После окончания работы с файлом его следует закрыть с помощью функции flose(). В качестве аргумента она принимает дескриптор файла.

Теперь давайте разберемся, каким образом мы можем читать и записывать в файл. Для того чтобы считать данные из бинарного файла, следует использовать функцию fread(), принимающую два аргумента — дескриптор файла и количество символов, которые нужно считать.

Создайте файл 1.txt, в котором напишите: Привет! Затем попробуйте считать его с помощью следующего сценария:

<?php
$fp=fopen("1.txt","r");
$s=fread($fp,7);
echo $s;
fclose($fp);
?>

В браузере выведется текст: Привет! Если мы изменим второй параметр (7) на 4, то увидим только часть текста, а именно первые четыре символа — Прив. Так как мы не можем всегда точно знать, сколько символов в файле, который мы хотим прочитать, то в качестве второго аргумента лучше указывать соответствующую функцию, которая и будет возвращать нужное нам значение.

Используем функцию FileSize(). В качестве параметра она принимает дескриптор файла, так как ничего больше ей знать не требуется. Перепишем наш пример с использованием этой функции:

<?php
$fp=fopen("1.txt","r");
$s=fraead($fp, filesize("1.txt"));
echo $s;
fclose($fp);
?>

Чтобы считывать файл не в бинарном, а в текстовом режиме, следует использовать функцию fgets($fp, $length–1). Она принимает два параметра — дескриптор файла и количество символов в строке минус 1 байт. Вот как выглядит сценарий считывания текстового файла с помощью функции fgets:

<?php
$fp=fopen("1.txt","r");
while (!feof($fp))
{
$s=fgets($fp,255);
echo $s;
}
fclose($fp);
?>

Здесь мы считываем файл построчно с помощью цикла while. Цикл будет выполняться до тех пор, пока не достигнет конца файла. Это обеспечивает функция feof(), которая возвращает true при достижении конца файла, указанного как аргумент.

Запись в файл в бинарном режиме осуществляется с помощью функции fwrite(). У нее есть два аргумента, первый указывает на файл, в который мы будем записывать, а второй является текстом, который мы заносим в этот файл. Запишем строку Привет в файл 1.txt:

<?php
$fp=fopen("1.txt","w");
fwrite($fp,"Привет");
fclose($fp);
?>

Для того чтобы произвести аналогичные действия в текстовом режиме, нужно воспользоваться функцией fputs($fp, $txt). Аналогично функции fwrite: первый аргумент является дескриптором файла, а второй — текстом, который мы будем записывать. Пример записи:

<?php
$fp=fopen("1.txt","w");
fputs($fp,"Привет");
fclose($fp);
?>

Перед тем как манипулировать с файлами можно также производить дополнительные проверки. Например, проверять не только сам факт существования открываемого файла, но и наличие права на чтение или запись в этот файл. Например, вы не обладаете правами администратора и вам нельзя читать все файлы — чтобы не возникло ошибки, лучше проверить перед чтением файла, позволено ли нам это делать. Для этого используется две функции: is_writeable() и is_readable(). Они проверяют возможность записи и чтения из файла соответственно. В качестве аргумента принимают путь к файлу. Возвращают true, если все в порядке, или false, если имеются какие-то ограничения. Вот пример сценария, который осуществляет проверку на возможность чтения и записи:

<?php
$fp=fopen("1.txt","w+");
if (is_writeable("1.txt")) echo "Allow write!";
else echo "Denied write ";
if (is_readable("1.txt")) echo "Allow read!";
else echo "Denied read!";
fclose($fp);
?>

Если запись в файл разрешена, то мы увидим текст Allow write!, иначе выведется текст Denied write. Аналогично будет и с чтением файла — Allow read при разрешенном чтении и Denied read при запрете на чтение.

Для перемещения по файлу можно воспользоваться функцией fseek(). Функция принимает три аргумента — дескриптор файла, число символов, на которое нужно сместиться, последний же параметр указывает, откуда начинать смещение указателя. С первыми двумя параметрами все понятно, третий аргумент может принимать следующие значения:

• начинать смещение с начала файла;

• с текущей позиции;

• с конца файла.

Для примера напишем сценарий, который будет находить символ, который находится посередине в файле, а затем будет вставлять вместо него знак восклицания:

<?php
$fp=fopen("1.txt","r+");
fseek($fp, (filesize("1.txt") / 2), 0);
fwrite($fp,"!");
flush($fp);
fseek($fp, 0, 0);
$s=fread($fp, filesize("1.txt"));
echo $s;
fclose($fp);
?>

После открытия файла в режиме r+, чтобы можно было работать с файлом, перемещаем указатель на середину. Сделали мы это с помощью деления количества символов в файле на 2. Затем мы записываем на это место знак восклицания. Тут вызывается пока незнакомая вам функция flush, предназначенная для принудительного сохранения файла. После того как мы сделали все необходимое и сохранили результат, перемещаем указатель на начало файла и считываем его. Кстати, для этого можно было воспользоваться специальной функцией rewind($fp), она перемещает указатель на начальную позицию. Для примера напишите в файле 1.txt текст «RIP» — после работы сценария текст в файле изменится на «R!P».

Чтобы узнать, в какой позиции находится указатель, нужно вызвать функцию ftell($fp). Она возвращает номер от начала, где находится в данный момент указатель.

Функция file() полезна при работе с массивами. Она принимает имя файла как аргумент и возвращает массив, элементы которого являются строками этого файла. Все просто и удобно. Создайте файл 1.txt c таким содержимым:

ноль
один
два
три
четыре
пять

После этого напишите и выполните следующий сценарий:

<?php
$fp=fopen("1.txt","r+");
$mass=file("1.txt");
foreach($mass as $index => $value)
{
echo("$index = $value <br>");
}
fclose($fp);
?>

Таким образом построился массив $mass, и в окне браузера вы должны увидеть:

0 = ноль
1 = один
2 = два
3 = три
4 = четыре
5 = пять

Заметьте: все что нам понадобилось для построения данного массива, это вызвать функцию file(). Далее с помощью цикла foreach мы просто-напросто организовали вывод массива.

Теперь давайте разберемся, как манипулировать файлами на сервере. Для того чтобы скопировать файл, следует воспользоваться функцией copy(). Она принимает два аргумента — файл, который нужно скопировать, и файл, в который нужно копировать. Возвращает true, если файл был успешно скопирован, или false, если произошла какая-то ошибка при копировании файла. Если файл, в который мы копируем, уже существует, то он будет перезаписан. Пример:

<?
$check=copy("1.txt","2.txt");
if ($check) echo "Успешно скопировано!";
else echo "Ошибка";
?>

Мы копируем файл 1.txt в файл 2.txt, если операция пройдет успешно, то мы увидим в окне браузера текст «Успешно скопировано!», иначе будет выдано сообщение «Ошибка».

Для удаления файла используется функция unlink(). В качестве аргумента она принимает имя файла, который нужно удалить.

Чтобы переименовать файл, можно воспользоваться функцией rename(). Она принимает два параметра — имя файла, который следует переименовать и новое имя файла. Если файл с таким именем уже существует, то он не будет перезаписан, а функция rename() просто вернет false.

Закончив с файлами, разберем, каким образом мы сможем работать с каталогами. Для того чтобы создать новый каталог следует вызвать функцию mkdir(), в качестве аргумента следует указать имя нового каталога. Параметром также (правда необязательным) является задания прав доступа для нового каталога — если не указать это значение самостоятельно, то права будут назначены в зависимости от настроек операционной системы.

Для удаления каталога служит функция rmdir(). Как аргумент принимает имя каталога. Указанный каталог может быть удален только в том случае, если он не содержит файлов.

Для изменения текущего каталога можно воспользоваться функцией chdir(). В качестве аргумента она принимает имя каталога, куда нужно перейти.

Для того чтобы узнать имя текущего каталога следует вызвать функцию getcwd(). Она не принимает параметров и возвращает полный путь к текущему каталогу.

Напишем небольшой сценарий, который будет выводить содержимое некоторого каталога Shell:

<?php
$dd=opendir("Shell");
while (true){
$cur=readdir($dd);
if ($cur=="") break;
echo $cur."<br>";
}
closedir($dd);
?>

Здесь мы открываем каталог Shell, затем создаем бесконечный цикл, в котором считываем и выводим имя каждого файла. Перед тем как считать новый файл мы проверяем, есть ли еще файл для считывания. Если файлов больше нет, то прерываем цикл и закрываем каталог. Вывод этого сценария выглядит примерно следующим образом: рис. 1.

Через PHP-сценарии, разумеется, можно запускать внешние программы и выполнять действия в командной строке. Для этого в PHP существует целый ряд команд.

Например, встроенная в PHP функция для запуска внешний программ system(). Она принимает имя программы, которую нужно выполнить. В этом случае управление сценарию будет передано только после окончания работы программы. Например, напишем сценарий для отправки сообщений по сети в Windows XP. Это можно осуществить при выполнении команды net send в командной строке. Синтаксис команды таков: net send ip_получателя "сообщение для отправки". Давайте напишем такой сценарий:

<?php
$ip="127.0.0.1";
$sms="Привет!";
system("net send $ip $sms");
?>

В браузере вы должны увидеть текст Сообщение успешно отправлено 127.0.0.1. Как видите, функция system() еще и перенаправляет вывод программы в браузер. На компьютере, IP-адрес которого вы указали, должно появится соответствующее окно с приветствием.

2

Если вы не хотите, чтобы выходные данные программы посылались автоматически в браузер, можно воспользоваться функцией exec(). Она принимает только один обязательный параметр — программу, которую нужно выполнить. Давайте перепишем прошлый пример с использованием функции exec:

<?php
$ip="127.0.0.1";
$sms="Привет!";
exec("net send $ip $sms");
?>

Теперь при выполнении сценария мы не увидим в браузере ничего, но тем не менее сообщение будет отправлено. Выходные данные программы, которую исполняет функция exec(), можно поместить в массив. Давайте перепишем пример, но теперь будем выводить выходные данные в браузер:

<?php
$ip="127.0.0.1";
$sms="Привет!";
exec("net send $ip $sms",$end);
echo $end[0];
?>

Для выполнения команд достаточно просто написать команду в обратных апострофах. Давайте рассмотрим написание сценария, который будет выводить информацию о сети. Мы будем получать ее с помощью утилиты ipconfig. Для этого достаточно написать две строки:

<?php
$net_info = `ipconfig`;
echo $net_info;
?>

Так как ipconfig заключена в обратные апострофы, то она пойдет на выполнение, а вывод команды занесется в переменную $net_info. Затем мы просто выводим значение переменной в браузер.

Явный минус всех этих способов состоит в том, что пока программа не закончит свою работу, мы ничего не увидим в браузере. То есть управление сценарию передается только при окончании работы программы. Это не очень удобно при выводе программой рисунка или большого куска текста, когда мы не можем процесс загрузки на экране «живьем». Чтобы избежать подобных проблем, следует воспользоваться функцией PassThru(). Она принимает как параметр только программу для запуска.

Еще одна проблема, связанная с использованием подобных функций — проблема безопасности. С помощью данного сценария можно выполнить и такую команду: dir c:windows или что-то похуже, например del c:windows*.exe (таким образом можно будет удалить все файлы с расширением .exe с каталога Windows). Чтобы этого не произошло, для запуска внешних программ можно использовать функцию escapeshellcmd(). Она принимает один аргумент — команду, которую нужно выполнить. Если мы попытаемся выполнить dir c:windows, то функция, перед тем как выполнить команду, уберет все «опасные» символы. После этого команда будет иметь вид: dir c:windows и, конечно же, ничего интересного, кроме сообщения о несуществующем каталоге, не выведет.
Сайт автора ( http://webscript.ru///www.HeeL.org.ua )
Мой Компьютер ( http://webscript.ru///mycomp.com.ua )