Как я могу обработать предупреждение функции file_get_contents () в PHP?

Я написал такой PHP-код

$site = "http://www.google.com";
$content = file_get_content($site);
echo $content;

Но когда я удаляю http: // из $site, я получаю следующее предупреждение:

Warning: file_get_contents(www.google.com) [function.file-get-contents]: failed to open stream:

Я пробовал try и catch, но ничего не вышло.

Тоже интересный подход: stackoverflow.com/questions/6718598/…

Hugo Stieglitz 19.06.2012 17:15

Связанный: stackoverflow.com/q/2002610

Fr0zenFyr 30.06.2015 22:35

Используйте try-catch с функцией set_error_handler, как сказано здесь stackoverflow.com/a/3406181/1046909

MingalevME 09.02.2017 15:05

Если вы удалите http: // из url, значит, вы ищете файл www.google.com на вашем локальном диске.

Rauli Rajande 14.12.2017 14:52

Как это может привлечь столько внимания и голосов? Зачем вам удалять информацию о протоколе. Даже в 2008 году у вас были FTP и HTTPS.

Daniel W. 13.03.2018 15:54
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
326
5
341 641
20
Перейти к ответу Данный вопрос помечен как решенный

Ответы 20

Вы можете добавить @: $content = @file_get_contents($site);

Это подавит любое предупреждение - используйте экономно!. См. Операторы контроля ошибок

Обновлено: когда вы удаляете http: //, вы больше ищете не веб-страницу, а файл на вашем диске под названием «www.google .....»

Это единственное, что действительно работает - я не мог каким-либо другим способом подавить сообщение «Не удалось открыть поток».

Olaf 25.09.2017 16:06
Ответ принят как подходящий

Шаг 1: проверьте код возврата: if ($content === FALSE) { // handle error here... }

Шаг 2: подавите предупреждение, поместив оператор контроля ошибок (т.е. @) перед вызовом file_get_contents (): $content = @file_get_contents($site);

Не забудьте использовать строгое сравнение: if ($ content === FALSE). Если файл содержит «0», то это вызовет ложноотрицательный результат.

Aram Kocharyan 24.06.2011 07:48

Привет, это не сработало для меня, добавление @ по-прежнему приводит к тому, что E_WARNING перехватывается каким-то глобальным (не моим) обработчиком ошибок, и мой скрипт умирает, прежде чем у меня будет возможность обработать возвращаемое значение. Есть идеи? tnx.

Sagi Mann 22.11.2012 10:51

Обнаружен побочный эффект: если файл не существует, сценарий останавливается на строке @file_get_contents.

Dax 23.12.2012 17:42

Это не работает для меня, даже если это будет правильное решение. У меня есть предупреждение о тайм-ауте без получения данных, но $ content === FALSE не "запускается" ($ site вызывается с сервера localhost, обратите внимание, что у меня есть данные быстро, если я вставляю URL-адрес в браузер).

Oliver 24.12.2014 15:39

Хотя ответ очень старый, я все же предлагаю добавить к вашему ответу примечание о том, что использование @ может отрицательно сказаться на производительности. См. этот ответ в соответствующей публикации, которая довольно хорошо объясняет.

Fr0zenFyr 30.06.2015 22:35

@ Fr0zenFyr Есть ли у вас какие-либо данные о производительности, подтверждающие вашу претензию?

Sven 06.06.2016 18:09

И как узнать, в чем была настоящая ошибка? errno из локальной операции или код состояния HTTP из удаленного?

Mikhail T. 16.05.2017 23:03

Пожалуйста, @file_get_contents работает, но это ужасная практика. Гораздо правильнее решение с обработчиком ошибок. Избегайте этого решения.

Raphaël Gonçalves 11.12.2017 13:44

не делай этого. Вы просто подавляете предупреждение об ошибке. это не обработка ошибок! это создаст проблемы при отладке.

helle 15.07.2019 11:56

Лучше всего было бы установить свои собственные обработчики ошибок и исключений, которые будут делать что-то полезное, например, регистрировать их в файле или отправлять по электронной почте важные. http://www.php.net/set_error_handler

Вот как я это сделал ... Нет необходимости в блоке try-catch ... Лучшее решение - всегда самое простое ... Наслаждайтесь!

$content = @file_get_contents("http://www.google.com");
if (strpos($http_response_header[0], "200")) { 
   echo "SUCCESS";
} else { 
   echo "FAILED";
} 

-1: это работает, если вы получаете ошибку 404 или что-то в этом роде, но не если вы вообще не можете подключиться к серверу (например, неправильное доменное имя). Я думаю, что $http_response_header в этом случае не обновляется, так как HTTP-ответ не получен.

Nathan Reed 24.03.2013 05:50

Как сказал @NathanReed, вы должны проверить, что $ content не является ложным (с ===), поскольку это то, что возвращается, если запрос вообще не может подключиться

Seb 20.01.2014 13:25

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

set_error_handler(
    function ($severity, $message, $file, $line) {
        throw new ErrorException($message, $severity, $severity, $file, $line);
    }
);

try {
    file_get_contents('www.google.com');
}
catch (Exception $e) {
    echo $e->getMessage();
}

restore_error_handler();

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

@enobrev, почему вы ставите одинаковое значение и для номера ошибки, и для серьезности?

Pacerier 16.07.2013 22:38

Нет особой причины, кроме возможности предложить что-то полезное в $ exception-> getCode (), поскольку set_error_handler не предлагает переменную номера ошибки (к сожалению).

enobrev 16.07.2013 23:42

Думаю, это может быть более верный ответ для PHP5.

James P. 30.09.2013 00:52

У меня есть предупреждение о тайм-ауте, которое не улавливается таким образом

Oliver 24.12.2014 15:44

Может кто-нибудь объяснить мне, почему для этого недостаточно простого улова?

vaso123 01.10.2015 16:48

@lolka_bolka, потому что file_get_contents не генерирует исключение, а вместо этого выдает ошибку php. Итак, в этом примере настраивается «обработчик ошибок», который улавливает большинство экземпляров возникающих ошибок php и вместо этого преобразует эти ошибки в исключения. Вот более современный пример из документации: php.net/manual/en/…

enobrev 01.10.2015 20:23

Это единственный правильный ответ, потому что при использовании @file_get_contents PHP все еще отправляет ошибку в stderr, затем идет журнал ошибок nginx: 2017/02/09 15:00:17 [ошибка] 4982 # 0: * 16548967 FastCGI отправлено в stderr: «Сообщение PHP: предупреждение PHP: file_get_contents (SOME_MY_URL): не удалось открыть поток: сбой HTTP-запроса! HTTP / 1.1 404 не найден в /path/to/public/index.php в строке 15», клиент: 10.24.1.36, сервер : my-server1, запрос: «GET SOME_MY_URL HTTP / 1.1», хост: «MY_HOST»

MingalevME 09.02.2017 15:02

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

Josef Sábl 23.10.2017 11:57

Я бы рекомендовал включить вызов restore_error_handler () в блок finally

peschanko 07.04.2019 13:00

Одна альтернатива - подавить ошибку, а также выбросить исключение, которое вы можете поймать позже. Это особенно полезно, если в вашем коде есть несколько вызовов file_get_contents (), поскольку вам не нужно подавлять и обрабатывать их все вручную. Вместо этого можно сделать несколько вызовов этой функции в одном блоке try / catch.

// Returns the contents of a file
function file_contents($path) {
    $str = @file_get_contents($path);
    if ($str === FALSE) {
        throw new Exception("Cannot access '$path' to read contents.");
    } else {
        return $str;
    }
}

// Example
try {
    file_contents("a");
    file_contents("b");
    file_contents("c");
} catch (Exception $e) {
    // Deal with it.
    echo "Error: " , $e->getMessage();
}

Вы можете использовать этот скрипт

$url = @file_get_contents("http://www.itreb.info");
if ($url) {
    // if url is true execute this 
    echo $url;
} else {
    // if not exceute this 
    echo "connection error";
}

Это требует строгого сравнения: if ($url === true)..., потому что, если вы получите в качестве ответа 0 или пустой, это приведет к ошибке соединения.

Daniel W. 13.03.2018 16:00

Мой любимый способ сделать это довольно просто:

if (false !== ($data = file_get_contents("http://www.google.com"))) {
      $error = error_get_last();
      echo "HTTP request failed. Error was: " . $error['message'];
} else {
      echo "Everything went better than expected";
}

Я обнаружил это после экспериментов с try/catch из @enobrev выше, но это позволяет использовать менее длинный (и IMO, более читаемый) код. Мы просто используем error_get_last для получения текста последней ошибки, а file_get_contents возвращает false в случае ошибки, так что простое «если» может это уловить.

Это самое простое и лучшее решение этой проблемы! Может быть, сделать это @file_get_contents, чтобы подавить сообщение об ошибке браузеру.

EDP 30.12.2015 11:36

Я признаю, что среди всех ответов это единственный разумный - если бы мы расширили его, чтобы использовать @file_get_contents для подавления предупреждения и, проверьте значение результата с помощью === FALSE.

kostix 10.02.2016 16:01

Это вызовет ошибки для успешных запросов, которые не возвращают тело или возвращают значение false. Должен быть if (false !== ($data = file_get_contents ()))

GordonM 06.06.2016 12:49

В документации это не проясняется, но, по моему опыту, использование @ может привести к тому, что error_get_last ничего не вернет.

Glenn Schmidt 30.01.2017 10:49

Первое условие - обратное. Если false не совпадает с результатом вызова file_get_contents, значит, он получил некоторое содержимое, и нам не следует искать ошибку. Я был сбит с толку, увидев ошибки из предыдущего теста или ошибку, что $ error имеет значение null, когда Google действительно был найден!

Robert 23.01.2021 20:15

Вот как я с этим справляюсь:

$this->response_body = @file_get_contents($this->url, false, $context);
if ($this->response_body === false) {
    $error = error_get_last();
    $error = explode(': ', $error['message']);
    $error = trim($error[2]) . PHP_EOL;
    fprintf(STDERR, 'Error: '. $error);
    die();
}
function custom_file_get_contents($url) {
    return file_get_contents(
        $url,
        false,
        stream_context_create(
            array(
                'http' => array(
                    'ignore_errors' => true
                )
            )
        )
    );
}

$content=FALSE;

if ($content=custom_file_get_contents($url)) {
    //play with the result
} else {
    //handle the error
}

Это не работает. Если $url 404 не найден, предупреждение все равно появится.

Raptor 16.05.2014 07:16

Правильный Raptor, я улучшил ответ с помощью stream_context_create (); Ничего лучше ... "@" не рекомендуется

RafaSashi 16.05.2014 18:23
ignore_errors только указывает контексту HTTP не интерпретировать коды состояния ответа HTTP> = 400 как ошибки. Хотя это незначительно связано, это не отвечает на вопрос об обработке ошибок PHP.
sun 01.07.2014 20:51

Спасибо за вариант ignore_errors! Это то, что мне было нужно!

Modder 16.02.2020 20:25

Поскольку PHP 4 использует Отчет об ошибках():

$site = "http://www.google.com";
$old_error_reporting = error_reporting(E_ALL ^ E_WARNING);
$content = file_get_content($site);
error_reporting($old_error_reporting);
if ($content === FALSE) {
    echo "Error getting '$site'";
} else {
    echo $content;
}

Измените файл php.ini

allow_url_fopen = On

allow_url_include = On

Не делай этого. Особенно не допускайте включения URL. Не надо, поверь мне. По умолчанию он отключен по очень веской причине # c99.

Daniel W. 13.03.2018 15:58

Вы также должны установить

allow_url_use = On 

в вашем php.ini, чтобы перестать получать предупреждения.

Он попытается получить данные, если это не сработает, оно перехватит ошибку и позволит вам сделать все, что вам нужно, в пределах перехвата.

try {
    $content = file_get_contents($site);
} catch(\Exception $e) {
    return 'The file was not found';
}

Вы должны использовать функцию file_exists (), прежде чем использовать file_get_contents (). Таким образом вы избежите предупреждения php.

$file = "path/to/file";

if (file_exists($file)){
  $content = file_get_contents($file);
}

Это будет работать, только если вы вызовете локальный файл и у вас есть права на проверку локального файла, если он существует.

rubo77 30.01.2018 14:05
try {
   $site = "http://www.google.com";
   $content = file_get_content($site);
   echo $content;
} catch (ErrorException $e) {
    // fix the url

}

set_error_handler(function ($errorNumber, $errorText, $errorFile,$errorLine ) 
{
    throw new ErrorException($errorText, 0, $errorNumber, $errorFile, $errorLine);
});

file_get_content не всегда вызывает исключение

marlar 16.03.2017 14:28

Хотели бы вы отредактировать свой ответ и сообщить нам, в какое время file_get_content выдает исключения?

OldGaurd01 17.06.2017 21:11

Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, почему и / или как этот код отвечает на вопрос, улучшает его долгосрочную ценность.

Jay Blanchard 18.09.2017 15:29

Самый простой способ сделать это - просто добавить @ перед file_get_contents, i. e .:

$content = @file_get_contents($site); 

что-то вроде этого:

public function get($curl,$options){
    $context = stream_context_create($options);
    $file = @file_get_contents($curl, false, $context);
    $str1=$str2=$status=null;
    sscanf($http_response_header[0] ,'%s %d %s', $str1,$status, $str2);
    if ($status==200)
        return $file        
    else 
        throw new \Exception($http_response_header[0]);
}
if (!file_get_contents($data)) {
  exit('<h1>ERROR MESSAGE</h1>');
} else {
      return file_get_contents($data);
}

нет. вы должны === для проверки условий. не ==

Alp Altunel 07.11.2020 13:37

Не рекомендую запускать file_get_contents дважды. Достаточно один раз.

Juakali92 30.01.2021 23:19

Включите allow_url_fopen из cPanel или WHM, затем попробуйте, надеюсь, это исправит

Другие вопросы по теме