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.


2
Auch ein interessanter Ansatz: stackoverflow.com/questions/6718598/…
Hugo Stieglitz


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


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.


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.


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 .....".


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

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

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
}

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

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


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

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

1

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

$content = @file_get_contents($site); 

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]);
}

1
if (!file_get_contents($data)) {
  exit('<h1>ERROR MESSAGE</h1>');
} else {
      return file_get_contents($data);
}

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

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

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

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

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.