Наш чат в Telegram для обмена идеями, проектами, мыслями, людьми в сфере ИТ г.Ростова-на-Дону: @it_rostov

Работа с файлами

Работа с файлами - важный инструмент PHP.

Включение внешних файлов

В каждый PHP-документ можно включить файл с помощью инструкции include(). Её аргумент: путь к файлу. Этой инструкцией удобно пользоваться при наличии одинаковых кусков кода во многих PHP-программах. Содержимое включаемого файла обрабатывается как простой HTML-текст. Для того, чтобы содержимое этого файла обрабатывалось как PHP-программа, нужно обрамлять его открывающим и закрывающим тегами PHP.

Пример 1

<html>
<head>
    <title>Использование include()</title>
</head>
<body>
<?php
include("top.php");
echo "<h3>...Основная часть...</h3>";
?>
</body>
</html>

Включаемый файл top.php с PHP-программой:

echo "<h2>...Общее приветствие...</h1>"
РЕЗУЛЬТАТ ПРИМЕРА 1:

...Общее приветствие...

...Основная часть...

В данном случае результат будет тем же, если включаемый файл top.php содержит только строку HTML-текста:

<h2>...Общее приветствие...</h2>

Включаемые файлы могут возвращать значения подобно функциям. Использование оператора return прерывает выполнение этого файла так же, как и функции.

Пример 2

<html>
<head>
    <title>Использование инструкции include(), возвращающей значение</title>
</head>
<body>
<?php
$res = include("top.php");
echo "<h2>Включаемый файл вернул $res</h2>";
?>
</body>
</html>

Включаемый файл top.php с PHP-программой:

<?php
$a = 7 * 8;
return $a;
?>
РЕЗУЛЬТАТ ПРИМЕРА 2:

Включаемый файл вернул 56

Инструкцию include() можно использовать внутри цикла. В цикле include() выполняется при каждой итерации. Это можно использовать для включения нескольких файлов. Например:

for ($i=1; $i<=5; $i++)
  include("incfile{$i}.htm");

Определение имени включаемого файла и его загрузка производятся повторно при каждом вызове include(). Это означает, что если содержание включаемого файла с момента предыдущего вызова изменилось, то загрузится новое содержание.

Оператор include() также можно включать в тело условного оператора.

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

Для указания что файл нужно подключать только один раз используется оператор include_once()

Анализ файлов

PHP содержит множество функций, дающих информацию о файлах. Наиболее употребимыми являются:

  • file_exists() - определяет существование файла. Например:
    if ( !file_exists( "aaa.php" ) )
      echo "Внимание! Файл aaa.php не найден!";

  • is_file() - определяет, является ли исследуемый объект файлом. Например:
    if ( is_file( "bbb.txt" ) )
      echo "Можете не сомневаться, bbb.txt - это файл";

  • is_dir() - определяет, является ли исследуемый объект каталогом. Например:
    if ( is_dir( "/tmp" ) )
      echo "Действительно, /tmp - это каталог";

  • is_readable() - определяет, доступен ли файл для чтения. Например:
    if ( is_readable( "db.dbf" ) )
      echo "db.dbf можно читать";

  • is_writable() - определяет, доступен ли файл для записи. Например:
    if ( is_writable( "db.dbf" ) )
      echo "В db.dbf писать можно";

  • filesize() - определяет размер файла в байтах.
  • filemtime() - определяет дату и время последнего изменения файла.
  • fileatime() - определяет дату и время последнего обращения к файлу.

Время возвращается в формате Unix, т.е. представляет собой количество секунд, прошедших после 1 января 1970 г. В примере 2 это число преобразуется в понятный для человека формат с помощью функции date( ). Подробнее об этой функции можно узнать в разделе "Дополнительные возможности".

Пример 3

<html>
<head>
    <title>Информация о файле</title>
</head>
<body>
<?php
$file = "top.php";
infoFile ( $file );
function infoFile ( $f )
{
    if ( !file_exists( $f ) )
    {
        echo "$f не найден!";
        return;
    }
    echo "$f - ".( is_file( $f ) ? "" : "не " )."файл<br>";
    echo "$f - ".( is_dir( $f ) ? "" : "не " )."каталог<br>";
    echo "$f ".( is_readable( $f ) ? "" : "не " )."доступен для чтения<br>";
    echo "$f ".( is_writable( $f ) ? "" : "не " )."доступен для записи<br>";
    echo "размер $f в байтах - ".( filesize( $f ) )."<br>";
    echo "последнее изменение $f - ".( date( "d M Y H:i", filemtime( $f ) ) )."<br>";
    echo "последнее обращение к $f - ".( date( "d M Y H:i", fileatime( $f ) ) )."<br>";
}
?>
</body>
</html>
РЕЗУЛЬТАТ ПРИМЕРА 3:
top.php - файл top.php - не каталог top.php доступен для чтения top.php доступен для записи размер top.php в байтах - 732 последнее изменение top.php - 04 Oct 2005 20:21 последнее обращение к top.php - 20 Oct 2005 14:01

Внимание! С удаленными файлами эти функции не работают. Их можно применять только к локальной файловой системе.

Управление файлами

PHP содержит множество функций управления файлами. Наиболее употребимыми являются:

  • touch() - создает пустой файл с заданным именем. Если такой файл уже существует, то функция изменит дату модификации. Например:
    touch( "ex1.txt" );

  • copy() - копирует файл. Для копирования файлов в php применяется функция copy ($source, $result). Ей нужно передать лишь два параметра - источник $source и имя файла-копии - $result. Стоит отметить, что следует указывать полные адреса к файлам. Пример применения функции copy:
    <?php
    if (copy('Z:/home/site/www/file.txt', 'Z:/home/site/www/file2.txt'))
        { echo "Копирование успешно выполнено"; }
    else
        { echo "Ошибка при копировании"; }
    ?>

  • unlink() - удаляет заданный файл. Например:
    <?php
    if (unlink('filename.txt'))
        { echo "Файл удален"; }
    else
        { echo "Ошибка при удалении файла"; }
    ?>

  • fopen( ) - открывает локальный или удаленный файл и возвращает указатель на него. Указатель используется во всех операциях с содержимым файла. Аргументы: имя файла и режим открытия.
    rчтение. Указатель файла устанавливается на его начало
    r+чтение и запись. Указатель файла устанавливается на его начало
    wзапись. Указатель файла устанавливается на его начало. Все старое содержимое файла теряется. Если файл с указанным именем не существует, функция пытается его создать
    w+чтение и запись. Указатель файла устанавливается на его начало. Все старое содержимое файла теряется. Если файл с указанным именем не существует, функция пытается его создать
    aзапись. Указатель файла устанавливается на его конец. Если файл с указанным именем не существует, функция пытается его создать
    a+чтение и запись. Указатель файла устанавливается на его конец. Если файл с указанным именем не существует, функция пытается его создать

    Например:

    $fp = fopen( "http://www.php.net/", "r" ); // для чтения
    $fp = fopen( "ex1.txt", "w" );             // для записи
    $fp = fopen( "ex2.txt", "a" );             // для добавления в конец

    Если открыть файл не удалось, то можно прервать выполнение программы. Например:

    $fp = fopen( "ex1.txt", "w" ) or die ( "Не удалось открыть файл" );

  • fclose() - закрывает файл. Аргумент: указатель файла, полученный ранее от функции fopen(). Например:
    fclose( $fp );
  • feof() - проверка конца файла. Аргумент: указатель файла.
  • fgetc() - чтение очередного символа из файла. Аргумент: указатель файла.
  • fgets() - чтение очередной строки файла. Аргументы: указатель файла и длина считываемой строки. Операция прекращается либо после считывания указанного количества символов, либо после обнаружения конца строки или файла.

    Пример 4

    <html>
    <head>
        <title>Чтение строк из файла</title>
    </head>
    <body>
    <?php
    $fp = fopen( "ex1.txt", "r" ) or die ( "Не удалось открыть файл" );
    while ( ! feof ( $fp ) )
        echo ( fgets( $fp, 1024 ) )."<br>";
    ?>
    </body>
    </html>

  • fread() - общая функция чтения из файла. Аргументы: указатель файла и количество считываемых символов.
  • fseek() - отступ от начала файла. Аргументы: указатель файла и смещение.

    Пример 5

    <html>
    <head>
        <title>Вывод на экран второй половины файла</title>
    </head>
    <body>
    <?php
    $f = "ex1.txt";
    $fp = fopen( $f, "r" ) or die ( "Не удалось открыть $f" );
    $fsize = filesize( $f );
    $half = (int)( $fsize / 2 );
    fseek ( $fp, $half );
    echo ( fread( $fp, ($fsize - $half) ) );
    ?>
    </body>
    </html>

  • fputs() - запись строки в файл. Аргументы: указатель файла и строка.
  • fwrite() - полный аналог функции fputs( ).

    Пример 6

    <html>
    <head>
        <title>Запись и добавление в файл</title>
    </head>
    <body>
    <?php
    $fp = fopen( "ex2.txt", "w" ) or die ( "Не удалось открыть файл" );
    fputs( $fp, "Запись в файл\n" );
    fclose( $fp );
    $fp = fopen( "ex2.txt", "a" ) or die ( "Не удалось открыть файл" );
    fputs( $fp, "Добавление в конец файла" );
    fclose( $fp );
    ?>
    </body>
    </html>

  • flock() - блокирует файл, т.е. не позволяет другим пользователям читать этот файл или писать в него, пока тот, кто наложил блокировку не закончит работу с данным файлом. Аргументы: указатель файла и номер режима блокировки.
    1Можно читать, нельзя писать
    2Нельзя ни читать, ни писать
    3Снятие блокировки

    Пример 7

    <html>
    <head>
        <title>Блокировка файла</title>
    </head>
    <body>
    <?php
    $fp = fopen( "ex1.txt", "a" ) or die ( "Не удалось открыть файл" );
    flock( $fp, 2 ); // Полная блокировка
    // Запись в файл
    flock( $fp, 3 ); // Снятие блокировки
    fclose( $fp );
    ?>
    </body>
    </html>

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

В PHP версии >= 4.3.0 появились новые удобные функции работы с файлами:

Работа с каталогами

В PHP есть несколько функций для работы с каталогами:

  • mkdir() - создание каталога. Аргументы: путевое имя каталога и режим доступа. Режим доступа - восьмеричное число из трех цифр с ведущим нулем. Первая цифра - право доступа для владельца, вторая - для группы, третья - для всех остальных. В системе Windows режим доступа игнорируется. В системе UNIX определены следующие права доступа:
    0Нет доступа
    1Доступ для запуска
    2Доступ для записи
    3Доступ для записи и запуска
    4Доступ для чтения
    5Доступ для чтения и запуска
    6Доступ для чтения и записи
    7Полный доступ

    Например, право полного доступа для владельца, чтения и запуска для группы и запуска для всех остальных:

    mkdir( "testdir", 0751 );

  • rmdir() - удаление каталога. Аргумент: путевое имя каталога. Удалить можно лишь пустой каталог при наличии права на это. При успешном выполнении функция возвращает true.
  • opendir() - открытие каталога. Аргумент: путевое имя каталога. В случае возникновения ошибки функция возвращает false. Ошибка при открытии может быть вызвана тем, что каталог не существует или программа не имеет права его читать.
  • readdir() - чтение каталога. Аргумент: путевое имя каталога. Возвращает строку, содержащую имя найденного файла или подкаталога. По достижении конца каталога функция возвращает false.

    Пример 8

    <html>
    <head>
        <title>Чтение каталога</title>
    </head>
    <body>
    <?php
    $d = "testdir";
    $dh = opendir( $d ) or die ( "Не удалось открыть каталог $d" );
    while ( $f = readdir( $dh ) )
        echo "$f<br>";
    ?>
    </body>
    </html>

    Проверочное выражение цикла сработает не так, как хотелось бы, если в каталоге есть файл с именем "0". В таком случае имя "0" будет преобразовано в 0, что вызовет завершение цикла. Избежать подобного можно, если принять дополнительные меры безопасности, изменив проверочное выражение:

    gettype( $f = readdir( $dh ) ) != "boolean"

    Помимо использования функция fgetc() fgets() fgetss(), Вы можете использовать
    $file = file($filename). Она читает $filename в массив($file).

    Пример 9

    $file=file($filename);
    for ($i=0; $i<=count($file); $i++) {
    echo $file[$i], "<br />";
    }

Передача файла с сервера. Скачать файл. DownLoad

Ручной Download, или как скриптом открыть пользователю окошко сохранения файла. Чтобы в браузере открылся диалог "Сохранить файл" с названием файла file.dat, скрипт должен послать такие заголовки:

header("Content-Disposition: attachment; filename=file.dat");
header("Content-Type: application/x-force-download; name=\"file.dat\"");

Готовый пример отправки файла с диска:

<?php
$filename = "DownloadedFile.mp3";   // имя файл предложенное для сохранения в окне браузера
$myFile = $_SERVER['DOCUMENT_ROOT']."/my/file.mp3"; // файл на серевере

$mm_type="application/octet-stream";

header("Cache-Control: public, must-revalidate"); // кешировать
header("Pragma: hack");
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($myFile)) );
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary");

readfile($myFile); // прочитать файл и отправить в поток
?>

Не мешало бы также ссылаться на скрипт как http://.../download.php?file.dat, иначе браузеры, основанные на Mozilla, могут попытаться записать файл как file.dat.php. или указать атрибут download:

<a href="имя.php" download="file.dat">Скачать</a>

Примечание: Не используйте заголовок header("Cache-Control: no-cache") в таких скриптах, большинство версий Internet Explorer не смогут скачать файл.

Следующий пример скрипта демонстрирует как организовать поддержку докачки:

Предполагается, что $cd - путь к файлу, $fn - имя файла

<?php
$filename = $cd."/".$fn;
if (!file_exists($filename))
{
    header ("HTTP/1.0 404 Not Found");
    exit;
}
$fsize = filesize($filename);
$ftime = date("D, d M Y H:i:s T", filemtime($filename));
$fd = @fopen($filename, "rb");
if (!$fd){
    header ("HTTP/1.0 403 Forbidden");
    exit;
}
// Если запрашивающий агент поддерживает докачку
if ($HTTP_SERVER_VARS["HTTP_RANGE"]) {
    $range = $HTTP_SERVER_VARS["HTTP_RANGE"];
    $range = str_replace("bytes=", "", $range);
    $range = str_replace("-", "", $range);
    if ($range) {fseek($fd, $range);}
}
$content = fread($fd, filesize($filename));
fclose($fd);
if ($range) {
    header("HTTP/1.1 206 Partial Content");
}
else {
    header("HTTP/1.1 200 OK");
}
header("Content-Disposition: attachment; filename=$fn");
header("Last-Modified: $ftime");
header("Accept-Ranges: bytes");
header("Content-Length: ".($fsize-$range));
header("Content-Range: bytes $range-".($fsize -1)."/".$fsize);
header("Content-type: application/octet-stream");
print $content;
exit;
?>

Как передать файл на сервер?

Функции для работы с каталогами

  • chdir() - Сменить каталог

boolean chdir (string str)

Изменяет текущий каталог PHP на указанный в качестве параметра str. Возвращает TRUE в случае успешного завершения, FALSE в случае возникновения ошибки

  • chroot() - Сменить корневой каталог

boolean chroot (string str)

Изменяет корневой каталог текущего процесса на переданный в качестве параметра str. Возвращает TRUE в случае успешного завершения, FALSE в случае возникновения ошибки.

Замечание: Для Windows-платформ эта функция не реализована.

  • closedir() - Освободить дескриптор каталога

void closedir (resourse catalog)

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

dir - Класс directory

class dir
{
dir (string str)
string path
resource handle
string read (void)
void rewind (void)
void close (void)
}

Псевдо-объектно-ориентированный механизм для чтения каталога, переданного в параметре каталог. С момента открытия каталога становятся доступными два свойства класса. Свойство "handle" может быть использовано с другими функциями для работы с каталогами, например, с функциями readdir(), rewinddir() и closedir(). Свойство "path" содержит путь к открытому каталогу. Доступны три метода: read, rewind and close.

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

Пример кода

<?php
$d = dir("/etc");
echo "Дескриптор: ".$d->handle."<br>\n";
echo "Путь: ".$d->path."<br>\n";
while (false !== ($entry = $d->read())) {
    echo $entry."<br>\n";
}
$d->close();
?>

Замечание: Порядок, в котором метод "read" возвращает элементы каталога, зависит от операционной системы.

Замечание: Также, PHP автоматически определяет внутренний класс Directory, что означает, что вы не сможете определять собственные классы с таким же именем.

  • getcwd() - Получить имя текущего рабочего каталога

getcwd (void)

Возвращает имя текущего рабочего каталога.

resourse opendir (string path)

Возвращает дескриптор каталога для последующего использования с функциями closedir(), readdir() и rewinddir().

Если путь не существует или каталог, расположенный по указанному пути, не может быть открыт вследствие правовых ограничений или ошибок файловой системы, функция opendir() возвращает значение FALSE и генерирует сообщение PHP об ошибке уровня E_WARNING. Вы можете запретить вывод сообщения об ошибке, предварив имя функции opendir() символом '@'.

Пример кода

<?php
$dir = "/tmp/";
// Открыть заведомо существующий каталог
// и начать считывать его содержимое
if (is_dir($dir))
{
  if ($dh = opendir($dir))
  {
    while (($file = readdir($dh)) !== false)
    {
     print "Файл: $file : тип: " . filetype($dir . $file) . "\n";
    }
    closedir($dh);
  }
}
?>

Начиная с версии PHP 4.3.0, параметр путь может также являться любым URL'ом, обращение к которому приводит к получению списка его файлов и каталогов. Однако, данный способ работает только при использовании url-упаковщика file://. В версии PHP 5.0.0 была добавлена поддержка url-упаковщика ftp://.

  • readdir - Получить элемент каталога по его дескриптору

string readdir (resource catalog)

Возвращает имя следующего по порядку элемента каталога. Имена элементов возвращаются в порядке, зависящем от файловой системы.

Обратите внимание на способ проверки значения, возвращаемого функцией readdir() в приведенном ниже примере. В этом примере осуществляется проверка значения на идентичность (выражения идентичны, когда они равны и являются значениями одного типа - за более подробной информацией обратитесь к главе Операторы сравнения) значению FALSE, поскольку в ином случае, любой элемент каталога, чье имя может быть выражено как FALSE, остановит цикл (например, элемент с именем "0").

Пример кода

<?php
// Вывести список всех файлов в каталоге
// Оператор !== не существовал до версии 4.0.0-RC2
if ($handle = opendir('/path/to/files'))
{
    echo "Дескриптор каталога: $handle\n";
    echo "Файлы:\n";
    /* Именно этот способ чтения элементов
     каталога является правильным. */
    while (false !== ($file = readdir($handle)))
    {
        echo "$file\n";
    }
    // Этот способ НЕВЕРЕН.
    while ($file = readdir($handle))
    {
        echo "$file\n";
    }
    closedir($handle);
}
?>

Обратите внимание, что функция readdir() также возвращает элементы с именами, и, если вы не хотите получать эти значения, просто отбрасывайте их:

Пример кода

<?php
if ($handle = opendir('.'))
{
    while (false !== ($file = readdir($handle)))
    {
        if ($file != "." && $file != "..")
        {
            echo "$file\n";
        }
    }
    closedir($handle);
}
?>
  • rewinddir() - Сбросить дескриптор каталога

void rewinddir (resource catalog)

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

  • scandir() - Получить список файлов и каталогов, расположенных по указанному пути

array scandir (string catalog [, int order])

Возвращает массив, содержащий имена файлов и каталогов, расположенных по пути, переданном в параметре catalog. Если каталог не является таковым, функция возвращает логическое значение FALSE и генерирует сообщение об ошибке уровня E_WARNING.

По умолчанию, сортировка производится в алфавитном порядке по возрастанию. Если указан необязательный параметр order (равен 1), сортировка производится в алфавитном порядке по убыванию.

Пример кода

<?php
$dir    = '/tmp';
$files1 = scandir($dir);
$files2 = scandir($dir, 1);

print_r($files1);
print_r($files2);
?>

Результатом будет нечто вроде:

Array
(
    [0] => .
    [1] => ..
    [2] => bar.php
    [3] => foo.txt
    [4] => somedir
)
Array
(
    [0] => somedir
    [1] => foo.txt
    [2] => bar.php
    [3] => ..
    [4] => .
)

Пример кода

<?php
// Альтернативный вариант функции scandir() для PHP 4
$dir = "/tmp";
$dh  = opendir($dir);
while (false !== ($filename = readdir($dh)))
{
    $files[] = $filename;
}

sort($files);
print_r($files);
rsort($files);
print_r($files);
?>
РЕЗУЛЬТАТ ПРИМЕРА:
Array ( [0] => . [1] => .. [2] => bar.php [3] => foo.txt [4] => somedir ) Array ( [0] => somedir [1] => foo.txt [2] => bar.php [3] => .. [4] => . )

все функции PHP для работы с файлами

Ещё примеры работы с файлами и директориями на PHP

Читать дальше: Загрузка файла на сервер на PHP


.