Справочники, инструменты, документация

PHP: Проверка существования файла

Во избежание неожиданных падений сайта, вызванных недоступностью запрашиваемого на стороне back-end содержимого, следует добавить проверки существования файлов и назначить какие-либо действия, производимые, если требуемые документы окажутся недоступны. Для этих целей подойдёт встроенный функционал PHP, имеющий простой синтаксис.

Описание функции file_exists($file)

Функция file_exists() введена в PHP 4. Единственное заметное изменение пришлось на пятую спецификацию языка, когда в качестве расположения файла стало можно указывать протоколы по типу http://, https://, ftp://и обёртки вроде glob://, phar:// и подобных.

В качестве ответа возвращается значение вида «Булев тип», относящейся к простейшему типу хранения данных в программировании. Другими словами, в результате проверки с использованием file_exists() придёт false («ложь») или true («истина»).

Из-за особенностей Windows перед macOS и UNIX-системами, если сервер запущен на данной ОС, пути файлов должны указываться через обратный слеш (), а не обычный (/). Зато в названия каталогов можно добавлять пробелы и заглавные буквы. Также важно отметить, что при запуске скрипта с file_exists() на платформе с 32-битной разрядностью возможны ошибки при проверке документов, чьи размеры превышают 2 гигабайта. Функция также доступна для папок.

Проверка файла

<?
// Проверим, есть ли в папке /shop/ заглавная страница под названием index.php.
if(file_exists($_SERVER['DOCUMENT_ROOT'].'/shop/index.php')) {
echo true;
} else {
echo false;
}
// Результат: 1 либо 0 (зависит от сайта)

Проверка директории по URL

<?
// Проверим, есть ли папка /about/ на внешнем ресурсе
if(file_exists('https://example.net/about/')) {
echo 'На сайте есть папка about';
} else {
echo 'На сайте нет папки about! Возможно, её никогда и не было';
}
// Результат: папка не найдена

Проверка существования файла по URL функцией fopen

В PHP существует функция fopen, с помощью которой можно открыть указанный URL. Что мы делаем? Пытаемся открыть файл, и если нам это удается, значит, файл существует, а противном же случае – файла нет. Реализация:

$file = "https://www.yandex.com/logo.png"; // Ссылка на файл
if(@fopen($file, "r")) {
    echo "Файл существует!";
} else {
    echo "Файл отсутствует!";
}

А что, если мы имеем не один файл, а несколько, так сказать, массив ссылок? Эта задача как раз и стояла изначально передо мной. И решение уже такой задачи следующее:

$images_all = [
    "https://www.yandex.com/logo.png",
    "https://www.yandex.com/logo_1.png",
    "https://www.yandex.com/logo_2.png",
    "https://www.yandex.com/logo_3.png",
    "https://www.yandex.com/logo_4.png",
    "https://www.yandex.com/logo_5.png"
];  // Исходный массив ссылок

foreach($images_all as $image) {
    if(@fopen($image, "r")) {
        echo $image;
    }
}

В этом случае мы получаем список только тех файлов, которые существуют.

Проверка существования локального файла

Под словом «локальный» подразумевается, что скрипт и файлы для проверки находятся на одном сервере. Если у вас довольно большой массив ссылок – этот вариант самый лучший для решения задачи, так как мы делаем не запрос на сторонний сервер, а сканирование указанных директорий.

В этом способе используется функция «file_exists», и по аналогии с предыдущим вариантом просто заменяется часть скрипта:

$file = "/logo.png"; // Ссылка на файл
if(file_exists($file)) {
    echo "Файл существует!";
} else {
    echo "Файл отсутствует!";
}

И то же самое для массива ссылок:

$images_all = [
    "/logo.png",
    "/logo_1.png",
    "/logo_2.png",
    "/logo_3.png",
    "/logo_4.png",
    "/logo_5.png"
];  // Исходный массив ссылок

foreach($images_all as $image) {
    if(file_exists($image)) {
        echo $image;
    }
}

На что стоит обратить внимание? На то, что этот способ удобен для прогонки файлов, находящихся в пределах нашей файловой системы. Поэтому все ссылки желательно указывать относительные.