§9. Расширения для работы с файловой системой
9.1. Понятие файла.
Любой сайт в конечном итоге представляет собой обычный набор файлов. А поскольку сайты хранятся на сервере, то в PHP предусмотрен полный набор функций для работы с файлами и каталогами. Практически все они находятся в разделе 'Расширения для работы с файловой системой' и позволяют выполнять с файлами такие операции, как создание, удаление, переименование, перемещение, чтение, запись, перезапись и многие другие полезные операции. Что же такое файл?
Файл (от англ. file) – это именованная область данных на носителе информации.
Имена файлов нужны для того, чтобы точно знать, к какой области данных осуществляется запрос. При этом большинство операционных систем в целях однозначности не допускает использование двух файлов с полностью идентичными именами в одном каталоге. Что касается набора символов, которые разрешается использовать для имен файлов, а также максимально допустимой длины имен файлов, то они зависят от используемой файловой системы. Например, Windows допускает использование в имени файла заглавных и строчных букв, цифр, некоторых знаков препинания и пробела, но запрещает использование символов '>', '<', '/', '\', '|', '?', '*', ':', ' " '. При этом максимально допустимая длина имен файлов в различных системах обычно не превышает 256 символов.
Для того, чтобы помочь системе определить тип файла и, соответственно, приложение для работы с ним, в имени файла обычно указывается его расширение, которое отделяется от остальной части имени точкой. Примерами расширений файлов могут служить: '.txt' – обычный текстовый файл, '.html' – файл, представляющий собой html-документ, '.js' – файл, содержащий код на языке JavaScript, '.jpg' – файл изображения в формате 'jpg' и огромное число других расширений.
Когда файлов становится слишком много, возникает необходимость их упорядочивания и группировки. Для этих целей используются каталоги или директории.
Каталог или директория (от англ. directory) – это специальный объект файловой системы, который используется для упрощения организации файлов. В графическом пользовательском интерфейсе каталоги также называют папками. В любом случае каталог представляет собой файл, содержащий записи о входящих в него файлах или других каталогах.
Каталог, прямо или косвенно включающий в себя все прочие каталоги и файлы, называется корневым. Обычно для его обозначения используется слэш '/'. Поэтому, когда в php-скрипте на сервере требуется прописать относительный путь от корневой папки сайта, его запись следует начинать с символа слэша.
Каталог, в котором находится текущий каталог, называется родительским каталогом. При построении относительного пути родительский каталог обозначается двумя точками, соответственно путь к нему из текущего каталога будет иметь вид '../'.
Как было сказано выше, большинство операционных систем не разрешает использование двух файлов с полностью идентичными именами в одном каталоге. В то же время вполне допустимо создавать для одного и того же файла несколько имен при помощи жестких ссылок.
Жёсткими ссылками или хардлинками (от англ. hard link) называют различные имена одного и того же файла, которые могут создаваться в пределах одного физического носителя.
После создания жесткой ссылки сказать где 'настоящий' файл, а где хардлинк невозможно, так как они полностью равноправны. Сама же область данных существует до тех пор, пока не будут удалены полностью все имена. Кроме того, при редактировании файла через одну из ссылок на него, содержимое по другим ссылкам также изменяется.
Как следует из определения, создание жестких ссылок одного и того же файла на разных физических носителях (например, жестких дисках) невозможно. Однако данное ограничение можно обойти при помощи символических ссылок.
Символическая ссылка или симлинк (от англ. symbolic link) – это специальный файл в файловой системе, содержащий в себе ссылку на другой файл или директорию, в том числе, и расположенный на другом физическом носителе.
Символьная ссылка занимает ровно столько места в файловой системе, сколько требуется для записи её содержимого, которое представляет собой строку, содержащую путь к определенному файлу или каталогу. Если символьная ссылка указывает на файл, который не существует, ее называют битой. При попытке обращения к файлу посредством битой ссылки обычно выводится соответствующее предупреждение.
9.2. Операции, не связанные с открытием файла.
К операциям, не требующим открытия файла, относятся операции, которые не пытаются получить доступ к содержимому файла и рассматривают его как минимальную целую единицу информации. Примерами могут служить: создание, переименование, копирование, удаление, перенос на другой носитель информации, создание жестких или символьных ссылок, а также получение или редактирование атрибутов файла. Рассмотрим некоторые из функций PHP, позволяющие выполнять над файлами перечисленные операции (см. пример 9.1).
<?php //is_file() - true, если файл существует и является обычным файлом, иначе - false //Также смотрите is_link(), is_dir(), file_exists() //В качестве аргумента передается строка с абсолютным или относительным адресом файла //Выведет bool(true), если файл существует в директории с данным скриптом var_dump(is_file('example_9_1.php')); //touch() - создает пустой файл и устанавливает дату модификации (доступа) файла //Если файл уже существует, то функция просто изменит дату модификации файла //Возвращает true в случае успеха, иначе - false. //Создаст файл test.php в директории на уровень выше директории со скриптом touch('../test.php'); //link() - создает жесткую ссылку и возвращает true в случае успеха, иначе - false //В качестве аргументов передаются строки с относительными адресами //См. также linkinfo(), которая возвращает информацию о ссылке //symlink(), которая создаёт символическую ссылку, а также //readlink(), возвращающая путь к файлу, на который указывает символическая ссылка //Создает жесткую ссылку для файла test.php, находящегося в каталоге со скриптом //Ссылка будет расположена в каталоге, в котором расположен каталог со скриптом link('test.php', '../test_link.php'); //rename() - переименовывает файл или директорию и возвращает true в случае успеха, //иначе - false. В качестве аргументов передаются строки со старым и новым адресом файла //В случае необходимости, файл переносится между директориями //Переименовывает файл test.php, находящийся в каталоге со скриптом, в test_2.php и //и переносит его в каталог на уровень вверх rename('test.php', '../test_2.php'); //copy() - копирует содержимое файла в другой файл, возвращает true в случае успеха, //иначе - false. Содержимое целевого файла перезаписывается. В качестве аргументов //передаются строки с относительными или абсолютными адресами файлов //Копирует содержимое файла test.php в test_2.php, при этом оба файла находятся //в том же каталоге что и сам скрипт copy('test.php', 'test_2.php'); //unlink() - удаляет файл и возвращает true в случае успеха, иначе - false //В качестве аргумента передается строка с абсолютным или относительным адресом файла //Удаляет файл test.php, расположенный в каталоге со скриптом unlink('test.php'); //move_uploaded_file() - проверяет, является ли файл загруженным на сервер по //протоколу HTTP POST и в случае успеха перемещает загруженный файл в новое место, //возвращая при этом true, иначе - false. Будет рассмотрена в следующем //параграфе в примере 10.13 (незабываем про официальный справочник) //см. также is_uploaded_file() //filesize() - возвращает размер указанного файла в байтах или false в случае ошибки //см. также filetype(), которая возвращает тип файла echo filesize('test.php'); //Выведет что-то вроде 547 (т.е. байтов) //pathinfo() - возвращает информацию о пути к файлу в виде ассоциативного массива с //элементами 'dirname', 'basename', 'extension' (если есть) и 'filename' //Если указан дополнительный параметр PATHINFO_DIRNAME, PATHINFO_BASENAME, //PATHINFO_EXTENSION или PATHINFO_FILENAME, то возвращается соответствующая строка //см. также dirname() - возвращает имя родительского каталога из указанного пути //basename() - возвращает последний компонент имени из указанного пути //realpath() - возвращает канонизированный абсолютный путь к файлу echo pathinfo('test.php', PATHINFO_EXTENSION); //Выведет 'php' echo pathinfo('test.php')['extension']; //Также выведет 'php' //is_readable() - проверяет существование файла и доступен ли он для чтения и //возвращает true в случае успеха, иначе - false //См. также is_writable(), которая проверяет доступен ли файл для записи var_dump(is_readable('test.php')); //Выведет bool(true) или же bool(false) //fileatime() - возвращает время последнего доступа к файлу или false при ошибке //см. также filemtime() - возвращает время последнего изменения файла //stat() - возвращает информацию о файле echo fileatime('test.php'); //Выведет временную метку Unix, например, 1460029142 ?>
Пример 9.1. Выполнение операций, не связанных с открытием файла
Индексный дескриптор (англ. inode) – это структура данных, в которой хранится метаинформация о стандартных файлах, каталогах или других объектах файловой системы, кроме имени и непосредственно самих данных.
Каждый файл имеет свой индексный дескриптор, идентифицируемый по уникальному номеру в файловой системе, в которой располагается этот файл. Обычно индексные дескрипторы хранят информацию о режиме доступа (чтение, запись, запуск на выполнение), принадлежности владельцу (пользователю или группе), и типе файла. Получить индексный дескриптор файла можно при помощи функции fileinode(), а текущего скрипта при помощи функции getmyinode() (см. функцию в разделе PHP опции/Информационные Функции).
9.3. Редактирование содержимого файла.
Редактирование содержимого файла подразумевает осуществление таких операций, как открытие и закрытие файла, чтение и запись, получение текущего значения файлового указателя и его перемещение в соответствии с заданными параметрами, сброс файлового буфера и некоторые другие операции. При этом, используя для редактирования соответствующие функции PHP, нужно иметь также и некоторое представление о понятиях, которые имеют непосредственное отношение к работе с файлами. Приведем краткое описание наиболее важных из них.
- Файловый дескриптор (от англ. file descriptor) – неотрицательное целое число, которое операционная система возвращает при открытии файла (в случае, если это возможно) и с помощью которого выполняются все остальные файловые операции. По завершении операций и закрытии файла дескриптор теряет смысл.
- Файловый указатель – число, указывающее величину смещения относительно нулевого байта в файле. Обычно по этому адресу осуществляется чтение/запись, если конечно вызов операции чтения/записи не предусматривает указание адреса. При выполнении операций чтения/записи файловый указатель смещается на число прочитанных/записанных байт. В результате последовательный вызов операций чтения позволяет прочитать весь файл не обращая внимания на его размер.
- Файловый буфер – специально выделенный участок памяти (буфер), в котором операционная система осуществляет кэширование файловых операций. При закрытии файла буфер сбрасывается.
- Режим доступа – режим устанавливающий разрешения на чтение и запись файла при его открытии.
Прежде, чем приступить к редактированию содержимого файла, его нужно открыть. Делается это при помощи функции fopen(), которой в качестве обязательных аргументов передаются строки с именем открываемого файла и режимом доступа, принимающего одно из следующих значений:
- 'r' – открывает файл только для чтения и помещает указатель в начало файла;
- 'r+' – открывает файл для чтения и записи и помещает указатель в начало файла;
- 'w' – открывает файл только для записи, помещает указатель в начало файла и обрезает файл до нулевой длины; если файл не существует – пытается его создать;
- 'w+' – открывает файл для чтения и записи, помещает указатель в начало файла и обрезает файл до нулевой длины; если файл не существует – пытается его создать;
- 'a' – открывает файл только для записи и помещает указатель в конец файла; если файл не существует – пытается его создать;
- 'a+' – открывает файл для чтения и записи и помещает указатель в конец файла; если файл не существует – пытается его создать;
- 'x' – создаёт и открывает файл только для записи и помещает указатель в начало файла; если файл уже существует, вызов fopen() закончится неудачей, вернёт FALSE и выведет ошибку; если же файл не существует, то функция попытается его создать;
- 'x+' – создаёт и открывает файл для чтения и записи и помещает указатель в начало файла; если файл уже существует, вызов fopen() закончится неудачей, вернёт FALSE и выведет ошибку; если же файл не существует, то функция попытается его создать;
- 'c' – открывает файл только для записи, помещает указатель в начало файла, но сам файл при этом в отличие от режима доступа 'w' не обрезается, а вызов к этой функции не вызывает ошибку; если файл не существует, то он создается;
- 'c+' – открывает файл для чтения и записи, помещает указатель в начало файла, но сам файл при этом в отличие от режима доступа 'w+' не обрезается, а вызов к этой функции не вызывает ошибку; если файл не существует, то он создается.
Поскольку различные операционные системы имеют собственные соглашения по обозначению конца строки, следует быть внимательным при записи данных в текстовый файл, правильно устанавливая символы конца строки в соответствии с операционной системой, под которой работает скрипт: '\n' для Unix/Linux, '\r\n' для Windows и '\r' для Macintosh. Также рекомендуется при использовании данной функции устанавливать флаг трансляции, который может принимать два значения: 't', которое предназначено для автоматического перевода '\n' в '\r\n' в текстовых файлах в случае работы скрипта под Windows, и 'b', которое устанавливает бинарный режим обработки файла (например, изображения), не предусматривающий преобразования данных и оперирующий не символами, а байтами. Для задания любого из этих режимов, следует просто дописать соответствующий флаг в строке с режимом доступа, например, 'rb' или же 'wt'. Полагаться на первое значение не стоит, поэтому рекомендуется всегда применять бинарный режим обработки файлов, правильно обрабатывая символы конца перевода строк. Помочь в этом может, например, специальная константа PHP_EOL, которая содержит корректный символ конца строки, используемый на данной платформе.
Рассмотрим использование функции fopen() на примере 9.2.
<?php //Открываем файл, находящийся в корневой папке сайта, для чтения в бинарном режиме $handel=fopen('/test_1.txt', 'rb') //Поднимаемся на уровень вверх из папки со скриптом и открываем файл для записи $handel=fopen('../test_2.txt', 'w') //Открываем файл на сервере для чтения и записи в бинарном режиме $handel=fopen('http://localhost/belarusweb/test_3.txt', 'r+b') ?>
Пример 9.2. Использование функции fopen()
После того, как файл будет успешно открыт, fopen() вернет дескриптор файла, который будет доступен другим функциям для работы с содержимым файла вплоть до его закрытия при помощи функции fclose(). Пусть, например, у нас имеется обычный текстовый файл test.txt (см. пример 9.3).
Я текстовый файл.
Пример 9.3. Содержимое текстового файла test.txt
Рассмотрим на его примере некоторые имеющиеся возможности для чтения файлов (см. пример 9.4).
<?php echo '-------- fgets() -------- <br><br>'; //Используем функцию fopen() и откроем файл в режиме бинарного чтения (по байтам) $handle=fopen('test_4.txt', 'rb'); //Функция feof() проверяет достигнут ли конец файла и возвращает true, если указатель //файла указывает на конец файла, иначе возвращает false. В качестве аргумента //принимает дискриптор файла, поэтому для удобства мы его сохранили в переменной //Цикл будет закончен при достижении конца файла while(!feof($handle)){ //fgets() считывает строку из файла, аргументом служит дескриптор файла. Также //посмотрите fgetss(), которая считывает строку, но при этом отбрасывает html-теги echo fgets($handle).'<br>'; //Выведет все три строки файла test.txt } //После завершения работы с файлом не забываем закрыть его fclose($handle); echo '<br><br>'; echo '-------- fgetc() -------- <br><br>'; //Теперь продемонстрируем посимвольное чтение открытого файла //Используем функцию fopen() и откроем файл в режиме бинарного чтения $handle=fopen('test_4.txt', 'rb'); //Здесь мы в качестве примера изменили условие, присвоив переменной дескриптор файла //fgetc() считывает по одному символу и возвращает false при достижении конца файла $my_text=''; while($fc=fgetc($handle)){ $my_text.=$fc; //За цикл все символы файла будут занесены в переменную } //Т.к. переносы строк в HTML преобразуются в пробелы, то для вывода в браузер мы //используем nl2br(), которая вставляет '<br>' перед символами переноса строк echo nl2br($my_text); //Также выведет все три строки файла test.txt //После завершения работы с файлом не забываем закрыть его fclose($handle); echo '<br><br>'; echo '-------- fread() -------- <br><br>'; //Для чтения заданного объема файла в бинарно-безопасном режиме используется //функция fread(), которая возвращает прочтенную строку или false в случае ошибки //Используем функцию fopen() и откроем файл в режиме бинарного чтения (как всегда) $handle=fopen('test_4.txt', 'rb'); //Аргументами являются файловый дескриптор и требуемый размер (мы считываем весь файл) $my_text=fread($handle, filesize('test_4.txt')); //Т.к. переносы строк не работают в HTML, то для правильного вывода в браузер можно //опять использовать nl2br(), которая вставляет '<br>' перед символами переноса строк //echo nl2br($my_text); //Также выведет все три строки файла test.txt //Но мы в качестве примера используем str_replace("". PHP_EOL ."", "<br>", $my_text) echo str_replace("". PHP_EOL ."", "<br>", $my_text); //После завершения работы с файлом не забываем закрыть его fclose($handle); echo '<br><br>'; echo '-------- fseek() -------- <br><br>'; //Для смещения файлового указателя в нужную позицию (указывается в байтах) используется //fseek(), которая возвращает 0 в случае успеха и -1 при возникновении ошибки //Также смотрите ftell(), которая сообщает текущую позицию чтения/записи файла и //rewind(), которая сбрасывает курсор файлового указателя в начало файла //Используем функцию fopen() и откроем файл в режиме бинарного чтения $handle=fopen('test_4.txt', 'rb'); //Начнем считывать файл с середины, для этого сместим указатель в середину файла fseek($handle, filesize('test_4.txt')/2); //Поскольку нужно считать половину файла, размер чтения также будет равен половине $my_text=fread($handle, filesize('test_4.txt')/2); //Выведет лишь часть файла, где первым символом будет 'кракозябра' из-за того, что //указатель попал между байтами, отвечающими за многобайтовый символ echo nl2br($my_text); //После завершения работы с файлом не забываем закрыть его fclose($handle); echo '<br><br>'; echo '-------- file_get_contents() -------- <br><br>'; //Если файл нужно просто прочитать, то это можно сделать за одну операцию при помощи //file_get_contents(), которая считывает содержимое файла в строку и возвращает ее в //случае успеха, иначе - false. При этом не нужно открывать файл при помощи fopen(). //Также см. file(), которая читает содержимое файла и помещает его в массив echo nl2br(file_get_contents('test_4.txt')); //Опять получим 3 строки файла echo '<br><br>'; ?>
Пример 9.4. Чтение содержимого файлов
Имеются в PHP и функции для записи данных в файл (см. пример 9.5). При этом следует помнить, что при открытии файла для записи нужно выбирать соответствующий режим записи. Например, если данные должны быть дописаны в файл, а не перезаписаны, то режим 'w' не подойдет, поскольку в этом случае файловый указатель будет помещен в начало файла, а сам файл будет урезан до нулевой длины.
<?php echo '-------- fwrite() -------- <br><br>'; //Используем функцию fopen() и откроем файл в бинарном режиме записи и чтения $handle=fopen('test_4.txt', 'a+b'); //fwrite() (или же fputs()) - записывает строку указанной длины в файл //Возвращает количество записанных байт или false в случае ошибки //Т.к. в режиме 'a+b' указатель помещается в конец файла, то данные будут не //перезаписаны, а также добавлены в конец файла fwrite($handle, PHP_EOL .'Еще строка текста.'); //Чтобы прочитать измененный файл, вернем указатель в начало файла rewind($handle); //Выведем обновленное содержимое файла на экран echo nl2br(fread($handle, 10000)); //После завершения работы с файлом не забываем закрыть его fclose($handle); echo '<br><br>'; echo '-------- file_put_contents() -------- <br><br>'; //file_put_contents() - записывает строку в файл. При этом открывать файл не нужно. //Записываемые данные, которые могут быть строкой, массивом или ресурсом, передаются //вторым аргументом. По умолчанию файл будет перезаписан, однако в качестве 3-го //аргумента можно передать дополнительный флаг FILE_APPEND (данные записываются в //конец файла). Одновременно можно указать FILE_USE_INCLUDE_PATH - файл будет //дополнительно искаться в подключаемых директориях, и LOCK_EX - файл будет //блокирован на время записи. Функция возвращает количество записанных байт //или false в случае ошибки. В примере указанная строка будет дописана в конец файла, //а сам файл на время записи будет заблокирован file_put_contents('test_4.txt', PHP_EOL .'Еще строка текста.', FILE_APPEND|LOCK_EX); //Выведем обновленное содержимое на экран echo nl2br(file_get_contents('test_4.txt')); echo '<br><br>'; echo '-------- flock() -------- <br><br>'; //flock () - блокирует файл, не позволяя другим пользователям читать файл или //записывать данные в него. Для этого в качестве второго аргумента используются //флаги LOCK_SH - разделяемая блокировка (чтение), LOCK_EX - эксклюзивная //блокировка (запись), LOCK_UN - снятие блокировки (разделяемой или эксклюзивной) //Возвращает true в случае успешного завершения, иначе - false //Откроем файл в режиме чтения и записи $handle=fopen('test_4.txt', 'a+b'); //Если файл удачно заблокируется, то начнем перезапись if(flock($handle, LOCK_EX)){ //Функция ftruncate() урезает файл до указанной длинны (см. справочник) ftruncate($handle, 0); //Записываем данные fwrite($handle, PHP_EOL .'Новый текст.'); //Отпираем файл flock($handle, LOCK_UN); }else{ echo "Попробуйте обратиться к файлу позже!"; } //Вернем указатель в начало файла rewind($handle); //Выведем измененное содержимое файла на экран echo nl2br(fread($handle, 10000)); //После завершения работы с файлом не забываем закрыть его fclose($handle); ?>
Пример 9.5. Запись данных в файл
9.4. Работа с каталогами.
Практически все функции для работы с каталогами собраны в подразделе 'Расширения для работы с файловой системой'-> 'Функции для работы с каталогами '. Но прежде, чем работать с каталогом, он должен быть создан. Сделать это можно при помощи функции mkdir(), которая в качестве обязательного аргумента принимает строку с путевым именем каталога, а в качестве необязательных аргументов может принимать режим доступа и логический аргумент, который разрешает или запрещает создание вложенных директорий. Режим доступа представляет собой восьмеричное число из трех цифр с ведущим нулем, где первая цифра задает право доступа для владельца, вторая – для группы, третья – для всех остальных. Отметим, что в системе Windows режим доступа игнорируется, а вот в UNIX определены следующие права доступа: 0 – доступ запрещен, 1 – доступ для запуска, 2 – доступ для записи, 3 – доступ для записи и запуска, 4 – доступ для чтения, 5 – доступ для чтения и запуска, 6 – доступ для чтения и записи, 7 – полный доступ. По умолчанию режим доступа имеет значение 0777, что означает самые широкие права. Использование данной функции, а также некоторых других, предназначенных для работы с каталогами, показано в примере 9.6.
<?php echo '-------- mkdir() -------- <br><br>'; //mkdir() - создаёт директорию. Возвращает true в случае успеха, иначе - false //См. также rmdir(), которая удаляет указанную директорию и возвращает true|false mkdir('php_dir'); //Создали директорию в папке со скриптом echo '<br><br>'; echo '-------- opendir(), readdir(), closedir() -------- <br><br>'; //opendir() - возвращает дескриптор каталога в случае успеха, иначе - false //readdir() - возвращает имя следующего по порядку элемента каталога, иначе - false. //Элементы возвращаются в том порядке, в котором они хранятся в файловой системе //При этом следует иметь в виду, что каждый каталог файловой системы имеет две //виртуальные директории '.' и '..', которые представляют, соответственно, //текущий и родительский каталоги и обычно возвращаются readdir() первыми //closedir() - освобождает дескриптор каталога //Также посмотрите rewinddir() - сбрасывает дескриптор каталога, //scandir()- возвращает в случае успеха массив имен файлов, найденных в указанной //директории или false в случае ошибки, glob() - находит файловые пути, совпадающие //с заданным шаблоном и возвращает их в массиве (или false в случае ошибки) //fnmatch() - проверяет совпадение имени файла с шаблоном и возвращает true|false //Для примера создадим в каталоге php_dir еще два каталога и два пустых файла mkdir('php_dir/dir_1'); mkdir('php_dir/dir_2'); //Опять же для примера, файлы создаем двумя разными способами touch('php_dir/file_1.txt'); fopen('php_dir/file_2.txt', 'w'); //Будем сохранять найденные файлы и папки в отдельные массивы $fls=array(); $drs=array(); if($dir_handle=opendir('php_dir')){ //Сканируем весь каталог while(($elem=readdir($dir_handle))!==false){ //Помещаем файлы в массив if(is_file('php_dir/'.$elem)){ $fls[]=$elem; //Помещаем каталоги в массив }else if(is_dir('php_dir/'.$elem)){ $drs[]=$elem; } } //Закроем дескриптор каталога после работы closedir($dir_handle); }else{ die('Извините, не удалось открыть каталог!'); } //Выведем имена всех найденных файлов на экран echo 'В каталоге присутствуют файлы: '.'<br>'; foreach($fls as $value ){ echo $value.'<br>'; } echo '<br>'; //Выведем имена всех вложенных директорий на экран echo 'Вложенные каталоги: '.'<br>'; foreach($drs as $value ){ echo $value.'<br>'; } echo '<br><br>'; echo '-------- getcwd() -------- <br><br>'; //getcwd() - возвращает имя текущего рабочего каталога, иначе - false //См. также chdir() - изменяет каталог и возвращает true|false echo getcwd().'<br>'; //На локальной машине вывело C:\xampp\htdocs\test\php chdir('php_dir'); echo getcwd(); //На локальной машине вывело C:\xampp\htdocs\test\php\php_dir echo '<br><br>'; ?>
Пример 9.6. Использование функций для работы с каталогами
9.5. Подключение внешних файлов.
В ходе работы над большими приложениями возникает необходимость в повторном использовании одних и тех же фрагментов кода в разных скриптах. В таких случаях многократно используемые куски кода удобно хранить в отдельных файлах, при необходимости подключая их к требуемому скрипту. Для этого предназначены операторы include, require, а также include_once и require_once. Первые два оператора включают и выполняют указанный файл с той лишь разницей, что оператор require в случае ошибки останавливает выполнение скрипта, в то время как оператор include всего лишь выдает предупреждение, продолжая выполнять скрипт дальше. Что касается второй пары операторов, то они включают код указанного файла только один раз, игнорируя попытки его повторного включения и выполнения. Пусть, например, у нас имеется файл inc_file.php, код которого показан в примере 9.7.
<?php //Определяем переменныево включаемом файле $str_1='Я была определена в глобальной области видимости подключаемого файла.'; $str_2='А я нахожусь в строке №'. __LINE__ .' подключаемого скрипта.'; //Определяем функцию во включаемом файле function my_func(){ $str_3='Я была определена в локальной области видимости подключаемого файла.'; echo $str_3; } ?>
Пример 9.7. Код подключаемого внешнего файла inc_file.php
Используем код данного файла в текущем скрипте, подключив его при помощи оператора include (см. пример 9.8). При этом будем считать, что оба файла находятся в одной папке.
<?php include 'inc_file.php'; //Выведет строку $str_1, т.к. переменная унаследовала глобальную область видимости echo $str_1.'<br>'; //Выведет 'А я нахожусь в строке №4 подключаемого скрипта.' echo $str_2.'<br>'; my_func(); //Выведет строку $str_3 ?>
Пример 9.8. Использование оператора include для подключения кода из внешнего файла
Отметим, что код включаемого файла наследует ту же область видимости переменных, что и строка, на которой произошло включение (см. примеры 9.8 и 9.9). Поэтому, если включение происходит внутри функции, весь код, содержащийся во включаемом файле, будет вести себя так, как будто он был определен внутри этой функции. Однако все функции и классы, объявленные во включаемом файле, будут доступны в глобальной области видимости текущего скрипта. Также следует быть внимательным с магическими константами (например, __LINE__), которые выполняются парсером перед тем, как происходит включение.
<?php function func_2(){ include 'inc_file.php'; } func_2(); //Вызываем функцию для активации включения //Выведет ошибку, т.к. переменная унаследовала локальную область видимости echo $str_1; //Выведет ошибку, т.к. переменная унаследовала локальную область видимости echo $str_2; //Функции и классы все равно доступны в глобальной области видимости my_func(); //Выведет строку $str_3 ?>
Пример 9.9. Использование оператора include внутри функции
В конце пункта добавим, что управляющие конструкции include_once и require_once следует использовать тогда, когда код подключаемого файла может быть выполнен во время выполнения скрипта более одного раза, что может вызвать ряд проблем в результате переопределения функций, переменных или повторном выполнении других операций.
Кстати, описание управляющих конструкций, перечисленных в данном пункте, можно найти в разделе 'Справочник языка' -> 'Управляющие конструкции'.
9.6. Определение прав доступа к файлам и папкам.
При размещении файлов сайта на веб-сервере Unix разработчик сталкивается с необходимостью определения прав доступа для каждого отдельного файла или каталога. Права доступа определяют кто и что может делать с данным файлом или каталогом. Существуют три основных вида прав доступа:
- чтение содержимого файла или просмотр перечня имен файлов в каталоге;
- запись файла или создание и удаление файлов из каталога;
- запуск файлов (например, скриптов) или доступ к файлам в каталоге.
Все перечисленные виды прав назначаются одной из трех групп пользователей (отношение пользователей к той или иной группе определяется сервером в момент их подключения к нему):
- 'user' (владелец файла) – это пользователь, который создает данный файл или папку, и затем подключается к серверу, например, по протоколу FTP под своим именем и паролем;
- 'group' (группа, к которой принадлежит владелец файла) – это другие пользователи, которые также подключаются к серверу по протоколу FTP и пытаются получить доступ к файлам или каталогам непосредственного владельца;
- 'other' (все остальные пользователи) – это все посетители сайта, которые заходят на него через свой браузер.
Сами права доступа обозначаются либо при помощи букв 'r' (чтение), 'w' (запись), 'x' (исполнение) в формате 'ixxxyyyzzz', либо при помощи трехзначного числа в восьмеричной системе счисления (цифры от 0 до 7) в формате '0nnn'. Первая группа букв или цифра устанавливают права для владельца файла, вторая – для группы, а третья – для всех остальных. Что касается первой буквы в символьном формате, то она указывает на то, что права доступа назначаются либо директории, тогда ставится буква 'd', либо обычному файлу, тогда ставится дефис '-'. Если вместо буквы указан дефис, то данный вид прав для соответствующей группы отсутствует. Например, файл с правами доступа '-rwxrwxrwx' или '0777' могут читать, записывать и запускать все группы пользователей, а вот директорию с правами доступа 'drwxr--r--' или '0744' может просматривать, удалять и создавать в ней файлы, а также получать доступ к файлам только владелец. Остальным группам разрешается лишь просмотр каталога. Реальный пример отображения прав доступа к файлам на хостинге показан на рис. 9.1.
Рис. 9.1. Пример отображения прав доступа на сервере
Нас будет интересовать числовой формат определения прав доступа к файлам и каталогам, расшифровка цифр которого представлена в таблице 9.1.
Числовой формат | Символьный формат | Права доступа |
---|---|---|
0 | --- | Права отсутствуют |
1 | --x | Только выполнение |
2 | -w- | Только запись |
3 | -wx | Запись и выполнение |
4 | r-- | Только чтение |
5 | r-x | Чтение и выполнение |
6 | rw- | Чтение и запись |
7 | rwx | Чтение, запись, выполнение |
Таблица 9.1. Таблица прав доступа в цифровом формате
Теперь, когда мы получили некоторое представление о правах доступа к файлам и каталогам, продемонстрируем определение прав доступа к файлу на примере 9.10.
<?php echo '-------- fileperms() -------- <br><br>'; //fileperms()- возвращает информацию о правах доступа в виде 10-го числа (или false) //После перевода в восьмеричное число, последние 4 цифры будут содержать сведения //о правах доступа, а также (на большинстве платформ) информацию о типе файла //Например, для файла test_2.php на рис. 9.1 получим 33188 или в 8-й 100644 echo substr(decoct(fileperms('test_2.php')), -4); //Выведет 0644 echo '<br><br>'; echo '-------- chmod() -------- <br><br>'; //chmod() - изменяет режим доступа к файлу и возвращает true|false chmod('test_2.php', 0777); //Разрешили всем все права chmod('test_2.php', 0744); //Владельцу все, остальным только чтение chmod('test_2.php', 0755); //Владельцу все, остальным чтение и запись ?>
Пример 9.10.
Также обратите внимание на функции chown(), chgrp(), umask(). Все они находятся в 'Функции для работы с файловой системой'-> 'Файловая система'.
Словарь новых английских слов
directory [dɪˈrɛkt(ə)ri] – каталог, справочник. hard [hɑːd] – жесткий, твердый. symbolic [sɪmˈbɒlɪk] – символический. touch [tʌtʃ] – касаться, трогать. node [nəʊd] – узел, пункт. descriptor [dɪˈskrɪptə] – дескриптор, идентификатор. replace [rɪˈpleɪs] – заменять. seek [siːk] – искать. tell [tel] – говорить, сообщать. put [pʊt] – помещать, класть. rewind [ˌriːˈwaɪnd] – перематывать. make [ˈmeɪk] – изготовлять, создавать. |
scan [skæn] – просматривать, сканировать. include [ɪnˈkluːd] – включать, содержать. require [rɪˈkwʌɪə] – требовать, приказывать. once [wʌns] – один раз, однажды. mode [məʊd] – форма, вид, способ. change [tʃeɪn(d)ʒ] – менять, изменять. owner [ˈəʊnə] – владелец, хозяин. flush [flʌʃ] – очищать, смывать. permission [pəˈmɪʃ(ə)n] – разрешение. stat [stat] – статистический. glob [ɡlɒb] – комок. |