redireccionar personalizar pagina not htaccess found error encontrada configurar php http validation http-headers http-status-code-404

personalizar - ¿Una manera fácil de probar una URL para 404 en PHP?



redireccionar error 404 htaccess (14)

Me estoy enseñando algunos raspados básicos y he descubierto que a veces las URL que introduzco en mi código devuelven 404, que encierra todo el resto de mi código.

Entonces necesito una prueba en la parte superior del código para verificar si la URL devuelve 404 o no.

Esto parece una tarea bastante directa, pero Google no me da ninguna respuesta. Me preocupa que esté buscando las cosas equivocadas.

Un blog me recomendó que use esto:

$valid = @fsockopen($url, 80, $errno, $errstr, 30);

y luego prueba para ver si $ válido si está vacío o no.

Pero creo que la URL que me está dando problemas tiene un redireccionamiento, por lo que $ valid está vacía para todos los valores. O tal vez estoy haciendo algo diferente.

También he investigado una "solicitud principal", pero todavía no he encontrado ejemplos de códigos reales con los que pueda jugar o probar.

Sugerencias? ¿Y qué es esto de curl?


Aquí hay una solución corta.

$handle = curl_init($uri); curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($handle,CURLOPT_HTTPHEADER,array ("Accept: application/rdf+xml")); curl_setopt($handle, CURLOPT_NOBODY, true); curl_exec($handle); $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE); if($httpCode == 200||$httpCode == 303) { echo "you might get a reply"; } curl_close($handle);

En su caso, puede cambiar application/rdf+xml a lo que sea que use.


Como sugiere Straight, investigue el uso de cURL. También puede estar interesado en configurar CURLOPT_NOBODY con curl_setopt para omitir la descarga de toda la página (solo desea los encabezados).


Como una sugerencia adicional a la gran respuesta aceptada:

Cuando uso una variación de la solución propuesta, recibí errores debido a la configuración de php ''max_execution_time''. Entonces lo que hice fue lo siguiente:

set_time_limit(120); $curl = curl_init($url); curl_setopt($curl, CURLOPT_NOBODY, true); $result = curl_exec($curl); set_time_limit(ini_get(''max_execution_time'')); curl_close($curl);

Primero configuro el límite de tiempo para una mayor cantidad de segundos, al final lo configuro nuevamente en el valor definido en la configuración de php.


Con el código de Strager, también puedes consultar CURLINFO_HTTP_CODE para ver otros códigos. Algunos sitios web no informan un 404, sino que simplemente redirigen a una página 404 personalizada y devuelven 302 (redirigir) o algo similar. Lo usé para verificar si existía un archivo real (por ejemplo, robots.txt) en el servidor o no. Claramente, este tipo de archivo no causaría una redirección si existiera, pero si no lo hiciera redirigiría a una página 404, que como dije antes puede no tener un código 404.

function is_404($url) { $handle = curl_init($url); curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE); /* Get the HTML or whatever is linked in $url. */ $response = curl_exec($handle); /* Check for 404 (file not found). */ $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE); curl_close($handle); /* If the document has loaded successfully without any redirection or error */ if ($httpCode >= 200 && $httpCode < 300) { return false; } else { return true; } }


Encontré esta respuesta here :

if(($twitter_XML_raw=file_get_contents($timeline))==false){ // Retrieve HTTP status code list($version,$status_code,$msg) = explode('' '',$http_response_header[0], 3); // Check the HTTP Status code switch($status_code) { case 200: $error_status="200: Success"; break; case 401: $error_status="401: Login failure. Try logging out and back in. Password are ONLY used when posting."; break; case 400: $error_status="400: Invalid request. You may have exceeded your rate limit."; break; case 404: $error_status="404: Not found. This shouldn''t happen. Please let me know what happened using the feedback link above."; break; case 500: $error_status="500: Twitter servers replied with an error. Hopefully they''ll be OK soon!"; break; case 502: $error_status="502: Twitter servers may be down or being upgraded. Hopefully they''ll be OK soon!"; break; case 503: $error_status="503: Twitter service unavailable. Hopefully they''ll be OK soon!"; break; default: $error_status="Undocumented error: " . $status_code; break; }

Esencialmente, utiliza el método "obtener contenido de archivos" para recuperar la URL, que rellena automáticamente la variable del encabezado de respuesta http con el código de estado.


Esto le dará verdadero si url no devuelve 200 OK

function check_404($url) { $headers=get_headers($url, 1); if ($headers[0]!=''HTTP/1.1 200 OK'') return true; else return false; }


Para detectar todos los errores: 4XX y 5XX, utilizo este pequeño script:

function URLIsValid($URL){ $headers = @get_headers($URL); preg_match("/ [45][0-9]{2} /", (string)$headers[0] , $match); return count($match) === 0; }


Puede usar este código también para ver el estado de cualquier enlace:

<?php function get_url_status($url, $timeout = 10) { $ch = curl_init(); // set cURL options $opts = array(CURLOPT_RETURNTRANSFER => true, // do not output to browser CURLOPT_URL => $url, // set URL CURLOPT_NOBODY => true, // do a HEAD request only CURLOPT_TIMEOUT => $timeout); // set timeout curl_setopt_array($ch, $opts); curl_exec($ch); // do it! $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); // find HTTP status curl_close($ch); // close handle echo $status; //or return $status; //example checking if ($status == ''302'') { echo ''HEY, redirection'';} } get_url_status(''http://yourpage.comm''); ?>


Si ejecuta php5, puede usar:

$url = ''http://www.example.com''; print_r(get_headers($url, 1));

Alternativamente con php4 un usuario ha contribuido con lo siguiente:

/** This is a modified version of code from "stuart at sixletterwords dot com", at 14-Sep-2005 04:52. This version tries to emulate get_headers() function at PHP4. I think it works fairly well, and is simple. It is not the best emulation available, but it works. Features: - supports (and requires) full URLs. - supports changing of default port in URL. - stops downloading from socket as soon as end-of-headers is detected. Limitations: - only gets the root URL (see line with "GET / HTTP/1.1"). - don''t support HTTPS (nor the default HTTPS port). */ if(!function_exists(''get_headers'')) { function get_headers($url,$format=0) { $url=parse_url($url); $end = "/r/n/r/n"; $fp = fsockopen($url[''host''], (empty($url[''port''])?80:$url[''port'']), $errno, $errstr, 30); if ($fp) { $out = "GET / HTTP/1.1/r/n"; $out .= "Host: ".$url[''host'']."/r/n"; $out .= "Connection: Close/r/n/r/n"; $var = ''''; fwrite($fp, $out); while (!feof($fp)) { $var.=fgets($fp, 1280); if(strpos($var,$end)) break; } fclose($fp); $var=preg_replace("//r/n/r/n.*/$/",'''',$var); $var=explode("/r/n",$var); if($format) { foreach($var as $i) { if(preg_match(''/^([a-zA-Z -]+): +(.*)$/'',$i,$parts)) $v[$parts[1]]=$parts[2]; } return $v; } else return $var; } } }

Ambos tendrían un resultado similar a:

Array ( [0] => HTTP/1.1 200 OK [Date] => Sat, 29 May 2004 12:28:14 GMT [Server] => Apache/1.3.27 (Unix) (Red-Hat/Linux) [Last-Modified] => Wed, 08 Jan 2003 23:11:55 GMT [ETag] => "3f80f-1b6-3e1cb03b" [Accept-Ranges] => bytes [Content-Length] => 438 [Connection] => close [Content-Type] => text/html )

Por lo tanto, puede verificar que la respuesta del encabezado sea correcta, por ejemplo:

$headers = get_headers($url, 1); if ($headers[0] == ''HTTP/1.1 200 OK'') { //valid } if ($headers[0] == ''HTTP/1.1 301 Moved Permanently'') { //moved or redirect page }

Códigos y definiciones del W3C


Si está buscando una solución más fácil y la que puede probar de una vez en php5, haga

file_get_contents(''www.yoursite.com''); //and check by echoing echo $http_response_header[0];


Si está utilizando enlaces curl de PHP, puede verificar el código de error usando curl_getinfo como tal:

$handle = curl_init($url); curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE); /* Get the HTML or whatever is linked in $url. */ $response = curl_exec($handle); /* Check for 404 (file not found). */ $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE); if($httpCode == 404) { /* Handle 404 here. */ } curl_close($handle); /* Handle $response here. */


adenda; probó esos 3 métodos considerando el desempeño.

El resultado, al menos en mi entorno de prueba:

Curl gana

Esta prueba se realiza bajo la consideración de que solo se necesitan los encabezados (nobody). Pruébate:

$url = "http://de.wikipedia.org/wiki/Pinocchio"; $start_time = microtime(TRUE); $headers = get_headers($url); echo $headers[0]."<br>"; $end_time = microtime(TRUE); echo $end_time - $start_time."<br>"; $start_time = microtime(TRUE); $response = file_get_contents($url); echo $http_response_header[0]."<br>"; $end_time = microtime(TRUE); echo $end_time - $start_time."<br>"; $start_time = microtime(TRUE); $handle = curl_init($url); curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($handle, CURLOPT_NOBODY, 1); // and *only* get the header /* Get the HTML or whatever is linked in $url. */ $response = curl_exec($handle); /* Check for 404 (file not found). */ $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE); // if($httpCode == 404) { // /* Handle 404 here. */ // } echo $httpCode."<br>"; curl_close($handle); $end_time = microtime(TRUE); echo $end_time - $start_time."<br>";


esto es solo una parte del código, la esperanza funciona para ti

$ch = @curl_init(); @curl_setopt($ch, CURLOPT_URL, ''http://example.com''); @curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1"); @curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); @curl_setopt($ch, CURLOPT_TIMEOUT, 10); $response = @curl_exec($ch); $errno = @curl_errno($ch); $error = @curl_error($ch); $response = $response; $info = @curl_getinfo($ch); return $info[''http_code''];


<?php $url= ''www.something.com''; $ch = curl_init($url); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_NOBODY, true); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.4"); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_TIMEOUT,10); curl_setopt($ch, CURLOPT_ENCODING, "gzip"); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); $output = curl_exec($ch); $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $httpcode; ?>