Wie kann ich mit der Warnung der Funktion file_get_contents () in PHP umgehen?

312

Ich habe so einen PHP-Code geschrieben

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

Wenn ich jedoch "http: //" entferne $site, wird folgende Warnung angezeigt:

Warnung: file_get_contents (www.google.com) [function.file-get-content]: Stream konnte nicht geöffnet werden:

Ich habe es versucht tryund catchaber es hat nicht funktioniert.

Waseem
quelle
2
Auch ein interessanter Ansatz: stackoverflow.com/questions/6718598/…
Hugo Stieglitz
Siehe auch
Fr0zenFyr
Verwenden Sie try-catch mit set_error_handler-function wie hier angegeben stackoverflow.com/a/3406181/1046909
MingalevME
2
Wenn Sie http: // aus der URL entfernen, suchen Sie auf Ihrer lokalen Festplatte nach einer Datei "www.google.com".
Rauli Rajande
Wie kann dies so viel Aufmerksamkeit und positive Stimmen bekommen? Warum sollten Sie die Protokollinformationen entfernen? Schon 2008 hatten Sie FTP und HTTPS.
Daniel W.

Antworten:

507

Schritt 1: Überprüfen Sie den Rückkehrcode: if($content === FALSE) { // handle error here... }

Schritt 2: Unterdrücken Sie die Warnung, indem Sie einen Fehlerkontrolloperator (dh @) vor den Aufruf von file_get_contents () stellen : $content = @file_get_contents($site);

Roel
quelle
86
Denken Sie daran, einen strengen Vergleich zu verwenden: if ($ content === FALSE). Wenn die Datei "0" enthält, wird ein falsches Negativ ausgelöst.
Aram Kocharyan
7
Hallo, das hat bei mir nicht funktioniert. Wenn Sie @ hinzufügen, wird E_WARNING immer noch von einem globalen (nicht meinem) Fehlerbehandler abgefangen, und mein Skript stirbt, bevor ich die Möglichkeit habe, den Rückgabewert zu verarbeiten. Irgendwelche Ideen? tnx.
Sagi Mann
1
Nebeneffekt erkannt: Wenn die Datei nicht vorhanden ist, stoppt das Skript in der Zeile @file_get_contents.
Dax
Dies funktioniert bei mir nicht, auch wenn dies die richtige Lösung sein wird. Ich habe eine Timeout-Warnung ohne empfangene Daten, aber $ content === FALSE wird nicht "ausgelöst" ($ site wird von einem localhost-Server aufgerufen, beachten Sie, dass ich schnell Daten habe, wenn ich die URL in einen Browser einfüge).
Oliver
4
Obwohl die Antwort sehr alt ist, empfehle ich dennoch, Ihrer Antwort einen Hinweis hinzuzufügen, dass die Verwendung @die Leistung negativ beeinflussen kann. Siehe diese Antwort in einem verwandten Beitrag, der ziemlich gut erklärt.
Fr0zenFyr
148

Sie können Ihren Fehlerbehandler auch als anonyme Funktion festlegen , die eine Ausnahme aufruft, und diese Ausnahme mit try / catch ausführen.

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

Es scheint eine Menge Code zu sein, um einen kleinen Fehler abzufangen. Wenn Sie jedoch Ausnahmen in Ihrer gesamten App verwenden, müssen Sie dies nur einmal tun, ganz oben (z. B. in einer enthaltenen Konfigurationsdatei) Konvertieren Sie alle Ihre Fehler durchgehend in Ausnahmen.

enobrev
quelle
Es ist eine der größten PHP-Verbesserungen, die ich bisher gesehen habe. Vielen Dank enobrev
Tomasz Smykowski
@enobrev, Warum setzen Sie den gleichen Wert für die Fehlernummer und den Schweregrad?
Pacerier
Kein spezifischer Grund außer einem Mittel, etwas Nützliches in $ exception-> getCode () anzubieten, da set_error_handler (leider) keine Fehlernummernvariable anbietet.
Enobrev
1
@enobrev Vergessen Sie nicht, die Fehlerbehandlungsroutine in der anonymen Funktion wiederherzustellen, bevor Sie eine Ausnahme auslösen. Ausnahmen können behandelt werden, und in diesem Fall ist der Handler immer noch so eingestellt, dass diese bestimmte Ausnahme ausgelöst wird, die als unerwartet auftreten und ein seltsames, schwer zu debuggendes Verhalten hervorrufen kann, wenn ein weiterer Fehler bei der Ausnahmebehandlung auftritt.
Josef Sábl
1
Ich würde empfehlen, den Aufruf von restore_error_handler () in den endgültigen Block aufzunehmen
peschanko
67

Meine Lieblingsmethode ist ziemlich einfach:

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";
}

Ich fand dies nach dem Experimentieren mit dem try/catchvon @enobrev oben, aber dies ermöglicht weniger langen (und IMO, besser lesbaren) Code. Wir verwenden einfach error_get_last, um den Text des letzten Fehlers abzurufen, und geben bei einem Fehler file_get_contentsfalse zurück, sodass ein einfaches "Wenn" dies abfangen kann.

Laurie
quelle
2
Dies ist die einfachste und beste Lösung für dieses Problem! Vielleicht machen Sie es @file_get_contents, um die Fehlerberichterstattung an den Browser zu unterdrücken.
EDV
1
Ich gebe zu, dass dies unter allen Antworten die einzig vernünftige ist - wenn wir sie erweitern würden @file_get_contents, um die Warnung zu unterdrücken und den Ergebniswert mit zu testen === FALSE.
Kostix
11
Dies löst Fehler für erfolgreiche Anforderungen aus, die keinen Text zurückgeben, oder einen, der als falsch ausgewertet wird. Sollte seinif (false !== ($data = file_get_contents ()))
GordonM
Die Dokumentation macht es nicht klar, aber die Verwendung von @ kann error_get_lastmeiner Erfahrung nach nichts zurückgeben
Glenn Schmidt
33

Sie können ein @ voranstellen: $content = @file_get_contents($site);

Dies wird jede Warnung unterdrücken - sparsam verwenden! . Siehe Fehlerkontrolloperatoren

Bearbeiten: Wenn Sie das 'http: //' entfernen, suchen Sie nicht mehr nach einer Webseite, sondern nach einer Datei auf Ihrer Festplatte mit dem Namen "www.google .....".

Greg
quelle
Das ist das einzige, was wirklich funktioniert - ich konnte die Meldung "Stream konnte nicht geöffnet werden" auf keine andere Weise unterdrücken.
Olaf
21

Eine Alternative besteht darin, den Fehler zu unterdrücken und eine Ausnahme auszulösen, die Sie später abfangen können. Dies ist besonders nützlich, wenn Ihr Code mehrere Aufrufe von file_get_contents () enthält, da Sie nicht alle manuell unterdrücken und verarbeiten müssen. Stattdessen können mehrere Funktionen in einem einzigen Try / Catch-Block aufgerufen werden.

// 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
quelle
15

So habe ich es gemacht ... Kein Try-Catch-Block erforderlich ... Die beste Lösung ist immer die einfachste ... Viel Spaß!

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

quelle
4
-1: Dies funktioniert, wenn Sie einen 404-Fehler oder etwas anderes erhalten, aber nicht, wenn Sie überhaupt keine Verbindung zum Server herstellen (z. B. falscher Domainname). Ich denke, $http_response_headerwird in diesem Fall nicht aktualisiert, da keine HTTP-Antwort empfangen wird.
Nathan Reed
1
Wie @NathanReed sagte, sollten Sie überprüfen, ob $ content nicht falsch ist (mit ===), da dies zurückgegeben wird, wenn die Anfrage überhaupt keine Verbindung herstellen kann
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
quelle
Das funktioniert nicht. Wenn der $urlWert 404 nicht gefunden wird, wird weiterhin eine Warnung angezeigt.
Raptor
Right Raptor, ich habe die Antwort mit stream_context_create () verbessert. Nichts besseres ... "@" nicht empfohlen
RafaSashi
1
ignore_errorsWeist den HTTP-Kontext nur an, HTTP- Antwortstatuscodes> = 400 nicht als Fehler zu interpretieren . Dies ist zwar nur geringfügig verwandt, beantwortet jedoch nicht die Frage der PHP-Fehlerbehandlung.
Sonne
Danke für die ignore_errorsOption! Das habe ich gebraucht!
Modder
6

So gehe ich damit um:

$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
quelle
4

Am besten legen Sie Ihre eigenen Fehler- und Ausnahmehandler fest, die etwas Nützliches tun, z. B. das Protokollieren in einer Datei oder das Versenden kritischer E-Mails. http://www.php.net/set_error_handler


quelle
1

Sie könnten dieses Skript verwenden

$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
quelle
Dies erfordert einen strengen Vergleich: if ($url === true)...Wenn Sie als Antwort 0oder leer erhalten, wird ein Verbindungsfehler ausgelöst.
Daniel W.
1

Verwenden Sie seit PHP 4 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
quelle
1

Der einfachste Weg, dies zu tun, besteht darin, ein @ vor file_get_contents zu stellen, d.h. e.:

$content = @file_get_contents($site); 
Muhammad Adeel Malik
quelle
1

etwas wie das:

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
quelle
1
if (!file_get_contents($data)) {
  exit('<h1>ERROR MESSAGE</h1>');
} else {
      return file_get_contents($data);
}
Frank Rich
quelle
-2

Sie sollten die Funktion file_exists () verwenden, bevor Sie file_get_contents () verwenden. Auf diese Weise vermeiden Sie die PHP-Warnung.

$file = "path/to/file";

if(file_exists($file)){
  $content = file_get_contents($file);
}
Jesús Díaz
quelle
Dies würde nur funktionieren, wenn Sie eine lokale Datei aufrufen und die richtigen Berechtigungen haben, um die lokale Datei zu überprüfen, falls vorhanden
rubo77
-3

Ändern Sie die Datei php.ini

allow_url_fopen = On

allow_url_include = On
Antério Vieira
quelle
Tu das nicht. Insbesondere keine URL-Includes zulassen. Glaub mir nicht. Es wurde aus einem sehr guten Grund standardmäßig deaktiviert # c99.
Daniel W.
-3

Dadurch wird versucht, die Daten abzurufen. Wenn dies nicht funktioniert, wird der Fehler abgefangen und Sie können alles tun, was Sie innerhalb des Catch benötigen.

try {
    $content = file_get_contents($site);
} catch(\Exception $e) {
    return 'The file was not found';
}
Brad
quelle
-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
quelle
file_get_content löst nicht immer eine Ausnahme aus
marlar
Möchten Sie Ihre Antwort bearbeiten und uns mitteilen, dass zu welchen Zeiten der file_get_content Ausnahmen auslöst?
Ravinder Payal
1
Während dieser Code die Frage möglicherweise beantwortet, verbessert die Bereitstellung eines zusätzlichen Kontexts darüber, warum und / oder wie dieser Code die Frage beantwortet, ihren langfristigen Wert.
Jay Blanchard
-3

Sie sollten auch die einstellen

allow_url_use = On 

in Ihrem php.ini, um keine Warnungen mehr zu erhalten.

GHAV
quelle