¿Cómo puedo manejar la advertencia de la función file_get_contents () en PHP?


312

Escribí un código PHP como este

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

Pero cuando elimino "http: //" $siterecibo la siguiente advertencia:

Advertencia: file_get_contents (www.google.com) [function.file-get-contents]: no se pudo abrir la transmisión:

Lo intenté tryy catchno funcionó.


2
También un enfoque interesante: stackoverflow.com/questions/6718598/…
Hugo Stieglitz


Use try-catch con set_error_handler-function como se dice aquí stackoverflow.com/a/3406181/1046909
MingalevME

2
Si elimina http: // de la url, está buscando un archivo "www.google.com" en su disco local.
Rauli Rajande

¿Cómo puede esto obtener tanta atención y votos positivos? ¿Por qué eliminarías la información del protocolo? Incluso en 2008, tenía FTP y HTTPS.
Daniel W.

Respuestas:


507

Paso 1: verifique el código de retorno: if($content === FALSE) { // handle error here... }

Paso 2: suprima la advertencia colocando un operador de control de errores (es decir @) delante de la llamada para file_get_contents () : $content = @file_get_contents($site);


86
Recuerde usar una comparación estricta: if ($ content === FALSE). Si el archivo contiene "0", entonces disparará un falso negativo.
Aram Kocharyan

77
Hola, esto no funcionó para mí, agregar @ todavía hace que E_WARNING sea detectado por un controlador de errores global (no el mío), y mi script muere antes de que tenga la oportunidad de manejar el valor de retorno. ¿Algunas ideas? tnx.
Sagi Mann

1
Efecto secundario detectado: si el archivo no existe, el script se detiene en la línea @file_get_contents.
Dax

Esto no funciona para mí, incluso si esta es la solución correcta. Tengo una advertencia de tiempo de espera sin datos recibidos, pero $ content === FALSE no se "activa" ($ sitio se llama desde un servidor localhost, tenga en cuenta que tengo datos rápidamente si me pego la URL en un navegador).
Oliver

44
Aunque la respuesta es muy antigua, aún sugiero agregar una nota a su respuesta de que el uso @puede afectar negativamente el rendimiento. Vea esta respuesta en una publicación relacionada que explica bastante bien.
Fr0zenFyr

148

También puede configurar su controlador de errores como una función anónima que llama a una excepción y usar un try / catch en esa excepción.

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

Parece una gran cantidad de código para detectar un pequeño error, pero si usa excepciones en toda su aplicación, solo necesitaría hacer esto una vez, en la parte superior (en un archivo de configuración incluido, por ejemplo), y lo hará Convierta todos sus errores a Excepciones en todo momento.


Es una de las mejores mejoras de PHP que he visto hasta ahora. Gracias enobrev
Tomasz Smykowski

@enobrev, ¿por qué pones el mismo valor tanto para el número de error como para la gravedad?
Pacerier

No hay una razón específica además de un medio para ofrecer algo útil en $ exception-> getCode (), ya que set_error_handler no ofrece una variable de número de error (desafortunadamente).
enobrev

1
@enobrev No olvide restaurar el controlador de errores dentro de la función anónima antes de lanzar una excepción. Se puede manejar la excepción y, en ese caso, el controlador aún está configurado para lanzar esta excepción particular que puede ser inesperada e introducir un comportamiento extraño y difícil de depurar cuando hay otro error en el manejo de excepciones.
Josef Sábl

1
Recomendaría incluir la llamada restore_error_handler () en finalmente bloquear
peschanko

67

Mi forma favorita de hacer esto es bastante simple:

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

Encontré esto después de experimentar con el try/catch@enobrev anterior, pero esto permite un código menos extenso (e IMO, más legible). Simplemente utilizamos error_get_lastpara obtener el texto del último error y file_get_contentsdevuelve falso en caso de error, por lo que un simple "si" puede captar eso.


2
¡Esta es la mejor y más fácil solución para este problema! Tal vez haga que @file_get_contentssuprima el informe de errores al navegador.
EDP

1
Admito que, entre todas las respuestas, esta es la única sensata: si la aumentamos para usarla @file_get_contentspara suprimir la advertencia y probar el valor del resultado usando === FALSE.
kostix

11
Esto activará errores para solicitudes exitosas que no devuelven un cuerpo, o devuelve uno que se evalúa como falso. Debería serif (false !== ($data = file_get_contents ()))
GordonM

La documentación no lo deja claro, pero usar @ puede hacer error_get_lastque no devuelva nada en mi experiencia
Glenn Schmidt

33

Puedes anteponer una @: $content = @file_get_contents($site);

Esto eliminará cualquier advertencia. ¡Úselo con moderación! . Ver operadores de control de errores

Editar: cuando elimina el 'http: //' ya no busca una página web, sino un archivo en su disco llamado "www.google ....."


Eso es lo único que realmente funciona: no pude suprimir el mensaje "no se pudo abrir la transmisión" de ninguna otra manera.
Olaf

21

Una alternativa es suprimir el error y también lanzar una excepción que puede detectar más adelante. Esto es especialmente útil si hay múltiples llamadas a file_get_contents () en su código, ya que no necesita suprimirlas y manejarlas todas manualmente. En cambio, se pueden hacer varias llamadas a esta función en un solo bloque 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();
}

15

Así es como lo hice ... No es necesario el bloque try-catch ... La mejor solución es siempre la más simple ... ¡Disfruta!

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

44
-1: esto funciona si obtiene un error 404 o algo así, pero no si no logra conectarse al servidor (por ejemplo, un nombre de dominio incorrecto). Creo que $http_response_headerno se actualiza en ese caso, ya que no se recibe respuesta HTTP.
Nathan Reed

1
Como dijo @NathanReed, debe verificar que el contenido de $ no es falso (con ===), ya que eso es lo que se devuelve si la solicitud no se conecta en absoluto
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
}

Esto no funciona Si $urlno se encuentra el 404, aún aparecerá la advertencia.
Raptor

Right Raptor, he mejorado la respuesta con stream_context_create (); Nada mejor ... "@" no recomendado
RafaSashi

1
ignore_errorssolo indica al contexto HTTP que no interprete los códigos de estado de respuesta HTTP > = 400 como errores. Si bien está marginalmente relacionado, eso no responde a la pregunta sobre el manejo de errores de PHP.
dom

Gracias por la ignore_errorsopción! ¡Esto es lo que necesitaba!
Modder

6

Así es como manejo eso:

$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

Lo mejor sería configurar sus propios controladores de errores y excepciones, que harán algo útil como registrarlo en un archivo o enviar correos electrónicos críticos. http://www.php.net/set_error_handler


1

Podrías usar este script

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

Esto necesita una comparación estricta: if ($url === true)...porque si se obtiene como respuesta 0o está vacío, aumenta el error de conexión.
Daniel W.

1

Desde PHP 4 use 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

La manera más simple de hacer esto es anteponer una @ antes de file_get_contents, i. mi.:

$content = @file_get_contents($site); 

1

algo como esto:

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

Debe usar la función file_exists () antes de usar file_get_contents (). De esta manera evitarás la advertencia de php.

$file = "path/to/file";

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

Esto solo funcionaría si llama a un archivo local y tiene los permisos correctos para verificar el archivo local si existe
rubo77

-3

Cambiar el archivo php.ini

allow_url_fopen = On

allow_url_include = On

No hagas esto. Especialmente no permitir url incluye. No, créeme Ha sido deshabilitado por defecto por una muy buena razón # c99.
Daniel W.

-3

Esto intentará obtener los datos, si no funciona, detectará el error y le permitirá hacer todo lo que necesite dentro de la captura.

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 no siempre produce una excepción
marlar

¿Desea editar su respuesta y decirnos a qué horas file_get_content arroja excepciones?
Ravinder Payal

1
Si bien este código puede responder a la pregunta, proporcionar un contexto adicional con respecto a por qué y / o cómo este código responde a la pregunta mejora su valor a largo plazo.
Jay Blanchard

-3

También debe configurar el

allow_url_use = On 

en tu php.inipara dejar de recibir advertencias.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.