Jak poradzić sobie z ostrzeżeniem o funkcji file_get_contents () w PHP?

312

Napisałem taki kod PHP

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

Ale kiedy usuwam „http: //” z, pojawia $sitesię następujące ostrzeżenie:

Ostrzeżenie: file_get_contents (www.google.com) [function.file-get-content]: nie można otworzyć strumienia:

Próbowałem tryi catchale to nie działa.

Waseem
źródło
2
Również interesujące podejście: stackoverflow.com/questions/6718598/...
Hugo Stieglitz,
Powiązane: stackoverflow.com/q/2002610
Fr0zenFyr
Użyj try-catch z funkcją set_error_handler, jak powiedziano tutaj stackoverflow.com/a/3406181/1046909
MingalevME
2
Jeśli usuniesz http: // z adresu URL, to szukasz pliku „www.google.com” na dysku lokalnym.
Rauli Rajande
Jak to może zyskać tyle uwagi i entuzjazmu. Dlaczego miałbyś usunąć informacje o protokole. Nawet w 2008 roku miałeś FTP i HTTPS.
Daniel W.

Odpowiedzi:

507

Krok 1: Sprawdź kod powrotu: if($content === FALSE) { // handle error here... }

Krok 2: Pomiń ostrzeżenie, umieszczając operator kontroli błędów (tj. @) Przed wywołaniem file_get_contents () : $content = @file_get_contents($site);

Roel
źródło
86
Pamiętaj, aby stosować ścisłe porównanie: jeśli ($ content === FALSE) .Jeśli plik zawiera „0”, spowoduje to wygenerowanie fałszywego negatywu.
Aram Kocharyan
7
Cześć, to nie zadziałało dla mnie, dodanie @ nadal powoduje przechwycenie E_WARNING przez jakiś globalny (nie mój) moduł obsługi błędów, a mój skrypt umiera, zanim mam szansę obsłużyć zwracaną wartość. Jakieś pomysły? tnx.
Sagi Mann
1
Wykryto efekt uboczny: jeśli plik nie istnieje, skrypt zatrzymuje się na linii @ file_get_contents.
Dax,
To nie działa dla mnie, nawet jeśli będzie to właściwe rozwiązanie. Mam ostrzeżenie o przekroczeniu limitu czasu bez otrzymania danych, ale $ content === FALSE nie jest „wyzwalane” ($ site jest wywoływany z serwera localhost, zauważ, że mam dane szybko, jeśli wkleję sobie adres URL do przeglądarki).
Oliver
4
Chociaż odpowiedź jest bardzo stara, nadal sugeruję dodanie do odpowiedzi uwagi, że użycie @może negatywnie wpłynąć na wydajność. Zobacz tę odpowiedź na powiązany post, który wyjaśnia dość dobrze.
Fr0zenFyr
148

Możesz również ustawić swój moduł obsługi błędów jako anonimową funkcję, która wywołuje wyjątek i użyć try / catch dla tego wyjątku.

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();

Wygląda na to, że dużo kodu łapie jeden mały błąd, ale jeśli używasz wyjątków w całej aplikacji, musisz to zrobić tylko raz, na górze (na przykład w dołączonym pliku konfiguracyjnym), i to zrobi przekonwertować wszystkie swoje błędy na wyjątki.

enobrev
źródło
To jedno z największych ulepszeń PHP, jakie do tej pory widziałem. Dziękuję enobrev
Tomasz Smykowski
@enobrev, Dlaczego podajesz tę samą wartość zarówno dla numeru błędu, jak i ważności?
Pacerier
Nie ma konkretnego powodu poza sposobem oferowania czegoś użytecznego w $ wyjątek-> getCode (), ponieważ set_error_handler nie oferuje zmiennej numeru błędu (niestety).
enobrev
1
@enobrev Nie zapomnij przywrócić obsługi błędów w funkcji anonimowej przed zgłoszeniem wyjątku. Można obsłużyć wyjątek, w takim przypadku moduł obsługi jest nadal ustawiony na zgłoszenie tego wyjątku, który może okazać się nieoczekiwany i wprowadzić dziwne, trudne do debugowania zachowanie, gdy wystąpi inny błąd w obsłudze wyjątków.
Josef Sábl
1
Zalecałbym
67

Mój ulubiony sposób na zrobienie tego jest dość prosty:

if (!$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";
}

Znalazłem to po eksperymentach z try/catchpowyższym @enobrev, ale pozwala to na użycie mniej długiego (i IMO, bardziej czytelnego) kodu. Po prostu używamy, error_get_lastaby uzyskać tekst ostatniego błędu i file_get_contentszwraca błąd w przypadku niepowodzenia, więc proste „jeśli” może to złapać.

Laurie
źródło
2
To najłatwiejsze i najlepsze rozwiązanie tego problemu! Może to zrobić, @file_get_contentsaby ukryć zgłaszanie błędów do przeglądarki.
EDP
1
Przyznaję, że spośród wszystkich odpowiedzi jest to jedyna sensowna opcja - gdybyśmy ją rozszerzyli, @file_get_contentsaby wyłączyć ostrzeżenie i przetestować wartość wyniku za pomocą === FALSE.
kostix
11
Spowoduje to błędy dla udanych żądań, które nie zwracają treści lub zwracają wartość, która ma wartość false. Powinno byćif (false !== ($data = file_get_contents ()))
GordonM,
Dokumentacja nie wyjaśnia tego, ale użycie @ może spowodować, error_get_lastże nic nie zwróci z mojego doświadczenia
Glenn Schmidt
33

Możesz dodać @: $content = @file_get_contents($site);

Pominie to ostrzeżenie - używaj oszczędnie! . Zobacz Operatory kontroli błędów

Edycja: po usunięciu „http: //” nie szukasz już strony internetowej, ale plik na dysku o nazwie „www.google .....”

Greg
źródło
To jedyna rzecz, która naprawdę działa - nie mogłem w żaden sposób ukryć komunikatu „nie udało się otworzyć strumienia”.
Olaf
21

Jedną z możliwości jest wyeliminowanie błędu, a także zgłoszenie wyjątku, który można złapać później. Jest to szczególnie przydatne, jeśli w kodzie znajduje się wiele wywołań funkcji file_get_contents (), ponieważ nie trzeba tłumić i obsługiwać ich wszystkich ręcznie. Zamiast tego można wykonać kilka wywołań tej funkcji w jednym bloku 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();
}
Aram Kocharyan
źródło
15

Oto jak to zrobiłem ... Nie trzeba blokować try-catch ... Najlepsze rozwiązanie jest zawsze najprostsze ... Ciesz się!

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

źródło
4
-1: działa to, jeśli pojawi się błąd 404 lub coś, ale nie, jeśli w ogóle nie uda się połączyć z serwerem (np. Zła nazwa domeny). Myślę, że $http_response_headerw takim przypadku nie jest aktualizowany, ponieważ nie otrzymano odpowiedzi HTTP.
Nathan Reed
1
Jak powiedział @NathanReed, należy sprawdzić $ treść nie jest fałszem (z ===) jako, że to, co dostaje zwrot, jeżeli wniosek nie trafia do żadnego w ogóle
Seb
15
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
}
RafaSashi
źródło
To nie działa Jeśli $urlnie znaleziono 404, ostrzeżenie będzie nadal wyświetlane.
Raptor
Raptor, poprawiłem odpowiedź za pomocą stream_context_create (); Nic lepszego ... "@" nie jest zalecane
RafaSashi
1
ignore_errorsinstruuje tylko kontekst HTTP, aby nie interpretował kodów statusu odpowiedzi HTTP > = 400 jako błędów. Choć marginalnie spokrewniony, nie odpowiada na pytanie o obsługę błędów PHP.
niedz.
Dzięki za ignore_errorsopcję! Właśnie tego potrzebowałem!
Modder
6

Oto jak sobie z tym poradzić:

$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();
}
Jrm
źródło
4

Najlepiej byłoby ustawić własne procedury obsługi błędów i wyjątków, które zrobią coś pożytecznego, np. Zalogowanie do pliku lub przesłanie krytycznych wiadomości e-mail. http://www.php.net/set_error_handler


źródło
1

Możesz użyć tego skryptu

$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";
}
ogie
źródło
Wymaga to ścisłego porównania: if ($url === true)...ponieważ jeśli otrzymujesz odpowiedź 0lub jest pusty, powoduje to błąd połączenia.
Daniel W.
1

Ponieważ PHP 4 używa error_reporting () :

$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;
}
Bob Stein
źródło
1

Najprostszym sposobem na to jest po prostu wstawienie @ przed file_get_contents, tj. mi.:

$content = @file_get_contents($site); 
Muhammad Adeel Malik
źródło
1

coś takiego:

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]);
}
Michael de Oz
źródło
1
if (!file_get_contents($data)) {
  exit('<h1>ERROR MESSAGE</h1>');
} else {
      return file_get_contents($data);
}
Frank Rich
źródło
-2

Przed użyciem file_get_contents () należy użyć funkcji file_exists (). W ten sposób unikniesz ostrzeżenia php.

$file = "path/to/file";

if(file_exists($file)){
  $content = file_get_contents($file);
}
Jesús Díaz
źródło
Działałoby
-3

Zmień plik php.ini

allow_url_fopen = On

allow_url_include = On
Antério Vieira
źródło
Nie rób tego Szczególnie nie zezwalaj na dołączanie adresów URL. Nie wierz mi. Został on domyślnie wyłączony z bardzo dobrego powodu # c99.
Daniel W.
-3

Spróbuje to uzyskać dane, jeśli to nie zadziała, złapie błąd i pozwoli ci zrobić wszystko, czego potrzebujesz w ramach tego połowu.

try {
    $content = file_get_contents($site);
} catch(\Exception $e) {
    return 'The file was not found';
}
Ćwiek
źródło
-3
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);
});
kta
źródło
file_get_content nie zawsze rzuca wyjątek
marlar
Czy chcesz edytować swoją odpowiedź i powiedzieć nam, o której godzinie file_get_content zgłasza wyjątki?
Ravinder Payal
1
Chociaż ten kod może odpowiedzieć na pytanie, zapewnienie dodatkowego kontekstu dotyczącego tego, dlaczego i / lub jak ten kod odpowiada na pytanie, poprawia jego długoterminową wartość.
Jay Blanchard
-3

Powinieneś także ustawić

allow_url_use = On 

W twojej php.iniprzestać otrzymywać ostrzeżenia.

GHAV
źródło