PHP PHP 7PHP 8

PHP: file_get_contents failed to open stream

  • Обновлено
  • Чтение ≈ 4 минуты
  • Нужны права администратора

Краткий ответ

«file_get_contents(): failed to open stream» говорит, что PHP не смог открыть файл или URL. Причина указана в конце сообщения: No such file or directory, Permission denied, HTTP request failed! 403/404 или отключённый allow_url_fopen.

В этой статье
  1. Читаем сообщение с конца
  2. Пошаговое решение для новичка
  3. Если открывается локальный файл
  4. Если открывается URL
  5. Ловушки, из-за которых ошибка «плавает»
failed to open stream
Warning: file_get_contents(https://example.com/data.json): Failed to open stream: HTTP request failed! HTTP/1.1 403 Forbidden
По-русскиНе удалось открыть поток: после двоеточия PHP пишет конкретную причину отказа.

#Читаем сообщение с конца

Предупреждение всегда состоит из имени функции, адреса и причины после «Failed to open stream:». Именно причина определяет решение, поэтому начинайте с неё:

  • No such file or directory — файла нет по этому пути или путь относительный и считается от другой папки;
  • Permission denied — у пользователя PHP (www-data, nginx, apache) нет прав на чтение файла или папки;
  • HTTP request failed! HTTP/1.1 403 / 404 / 500 — удалённый сервер отказал или адрес неверный;
  • Unable to find the wrapper «https» или allow_url_fopen is disabled — PHP собран без OpenSSL либо хостинг запрещает открывать URL как файлы;
  • SSL operation failed — проблема с сертификатом удалённого сайта или нет списка корневых сертификатов на сервере.

#Пошаговое решение для новичка

  1. Прочитайте настоящую причину предупрежденияНайдите в сообщении PHP точную строку после Failed to open stream: No such file, Permission denied, 403 Forbidden, certificate verify failed или timed out. Запишите путь, адрес и время ошибки. Разные сообщения требуют разных решений: сначала проверьте именно свою причину.
  2. Проверьте путь и доступ к локальному файлуДля локального файла постройте абсолютный путь через __DIR__, проверьте is_file() и is_readable(). На сервере используйте namei -l /путь/к/файлу и проверку чтения от имени реально используемого PHP-процесса. Не делайте chmod 777 и не меняйте владельца всего сайта.
  3. Проверьте запрос по сетиЕсли адрес начинается с https://, выполните curl -vI https://адрес, посмотрите код ответа, перенаправления и сертификат. HTTP 403 означает отказ самого удалённого сервера, который не устраняется включением allow_url_fopen. Проверьте разрешённые заголовки, авторизацию и ограничения API.
  4. Исправьте и подтвердите результатМеняйте только выявленную настройку — путь, права конкретного файла, доступ к API или доверенную цепочку сертификата. На тестовом запросе проверьте успешный возврат данных и отсутствие предупреждения в журнале PHP. Не отключайте проверку сертификата и не выводите секреты доступа в общедоступные журналы.

#Если открывается локальный файл

Относительный путь data/config.json PHP ищет от текущей рабочей папки, а она может отличаться от папки скрипта. Надёжнее строить путь от __DIR__. Права проверьте от имени пользователя веб-сервера:

read.php
Абсолютный путь и проверка перед чтением
$path = __DIR__ . '/data/config.json';
if (!is_readable($path)) {
    exit('Файл не найден или нет прав: ' . $path);
}
$text = file_get_contents($path);
Linux · Терминал (Bash)КомандаНужен sudo
Проверяем путь и права: у каждой папки на пути должен быть бит x, у файла — r
namei -l /var/www/site/data/config.json
sudo -u www-data test -r /var/www/site/data/config.json && echo "читается" || echo "нет доступа"
Linux · Терминал (Bash)С осторожностьюНужен sudo
Передать файл пользователю веб-сервера (путь и пользователя замените на свои)
# Сначала установите реального пользователя веб-PHP и проверьте права:
namei -l /var/www/site/data/config.json
# Владельца и режим изменяйте только для подтверждённого файла,
# если это соответствует принятой модели прав сайта.
# Не выполняйте рекурсивный chown/chmod и не задавайте 777.

Команда может изменить состояние системы или её настройки. Проверьте параметры и последствия перед запуском.

#Если открывается URL

Ответ HTTP 403 означает, что удалённый сервер отклонил запрос. Причиной могут быть отсутствие авторизации, ограничения по IP, защита от ботов или требования к заголовкам. User-Agent изменяйте только если это разрешено правилами API; он не гарантирует доступ. Проверьте документацию API и его журналы, а не пытайтесь обойти защиту перебором заголовков.

fetch.php
Запрос с User-Agent и таймаутом, ошибки не скрываются
$ctx = stream_context_create([
    'http' => [
        'method'        => 'GET',
        'header'        => "User-Agent: MyApp/1.0\r\nAccept: application/json\r\n",
        'timeout'       => 10,
        'ignore_errors' => true,
    ],
]);
$body = file_get_contents('https://example.com/data.json', false, $ctx);
echo $http_response_header[0] ?? 'нет ответа';

Если allow_url_fopen выключен (на части хостингов), используйте cURL — он работает независимо от этой настройки:

Linux · Терминал (Bash)Команда
Проверка настроек PHP и расширений
php -r "var_dump(ini_get('allow_url_fopen'), extension_loaded('openssl'), extension_loaded('curl'));"
curl -sS -I https://example.com/data.json

#Ловушки, из-за которых ошибка «плавает»

Если скрипт работает у вас и падает на хостинге, сравните окружение: версия PHP, allow_url_fopen, наличие OpenSSL и исходящий доступ с сервера (часть хостингов закрывает исходящие соединения на нестандартные порты). Ошибка только по утрам или раз в несколько запросов чаще означает лимиты удалённого API: он отвечает 429 или 403 при частых обращениях, поэтому добавьте кэширование результата в файл на 5–10 минут. Для редиректов file_get_contents следует по ним сам, но не больше 20 раз; кириллические адреса и пробелы в URL сначала кодируйте через rawurlencode() для частей пути и http_build_query() для параметров.

Для проблем с сертификатом на сервере установите корневые сертификаты (sudo apt install ca-certificates на Debian и Ubuntu) и проверьте директиву openssl.cafile в php.ini. Отключать проверку сертификата (verify_peer => false) нельзя: запрос станет уязвимым для подмены.

Так эту ошибку тоже называют

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.