Su método con get_headers
y solicitando la primera línea de respuesta devolverá el código de estado del redireccionamiento (si lo hay) y lo más importante, que va a hacer una petición GET que transferir el archivo completo.
Solo necesita una solicitud HEAD y luego analizar los encabezados y devolver el último código de estado. Lo que sigue es un ejemplo de código que hace esto, se trata de utilizar $http_response_header
en lugar de get_headers
, pero el formato de la matriz es el mismo:
$url = 'http://example.com/';
$options['http'] = array(
'method' => "HEAD",
'ignore_errors' => 1,
);
$context = stream_context_create($options);
$body = file_get_contents($url, NULL, $context);
$responses = parse_http_response_header($http_response_header);
$code = $responses[0]['status']['code']; // last status code
echo "Status code (after all redirects): $code<br>\n";
$number = count($responses);
$redirects = $number - 1;
echo "Number of responses: $number ($redirects Redirect(s))<br>\n";
if ($redirects)
{
$from = $url;
foreach (array_reverse($responses) as $response)
{
if (!isset($response['fields']['LOCATION']))
break;
$location = $response['fields']['LOCATION'];
$code = $response['status']['code'];
echo " * $from -- $code --> $location<br>\n";
$from = $location;
}
echo "<br>\n";
}
/**
* parse_http_response_header
*
* @param array $headers as in $http_response_header
* @return array status and headers grouped by response, last first
*/
function parse_http_response_header(array $headers)
{
$responses = array();
$buffer = NULL;
foreach ($headers as $header)
{
if ('HTTP/' === substr($header, 0, 5))
{
// add buffer on top of all responses
if ($buffer) array_unshift($responses, $buffer);
$buffer = array();
list($version, $code, $phrase) = explode(' ', $header, 3) + array('', FALSE, '');
$buffer['status'] = array(
'line' => $header,
'version' => $version,
'code' => (int) $code,
'phrase' => $phrase
);
$fields = &$buffer['fields'];
$fields = array();
continue;
}
list($name, $value) = explode(': ', $header, 2) + array('', '');
// header-names are case insensitive
$name = strtoupper($name);
// values of multiple fields with the same name are normalized into
// a comma separated list (HTTP/1.0+1.1)
if (isset($fields[$name]))
{
$value = $fields[$name].','.$value;
}
$fields[$name] = $value;
}
unset($fields); // remove reference
array_unshift($responses, $buffer);
return $responses;
}
Para obtener más información, véase: HEAD first with PHP Streams, en el extremo que contiene código de ejemplo de cómo se puede haga la solicitud HEAD con get_headers
también.
relacionadas: How can one check to see if a remote file exists using PHP?
cURL puede seguir redirecciones bien. Puede leerlo en la documentación en lugar de temer sus suposiciones: http://php.net/manual/en/function.curl-setopt.php, busque 'CURLOPT_FOLLOWLOCATION' – Piskvor
He intentado curl con la opción CURLOPT_FOLLOWLOCATION. Una cosa es buscar una página en mi servidor local y cuando ingreso el nombre de usuario/contraseña en la página que obtengo del servidor, el servidor se confunde en la redirección. ¿Cómo resolver esto? –