php - remove - ¿Cómo puedo saber dónde me redireccionarán utilizando cURL?
strip_tags wordpress (6)
A veces necesitas obtener encabezados HTTP pero al mismo tiempo no quieres devolver esos encabezados. **
Este esqueleto se encarga de las cookies y los redireccionamientos HTTP mediante la recursión. La idea principal aquí es evitar los encabezados HTTP de retorno al código del cliente.
Puedes construir una clase de rizo muy fuerte sobre él. Añadir funcionalidad POST, etc.
<?php
class curl {
static private $cookie_file = '''';
static private $user_agent = '''';
static private $max_redirects = 10;
static private $followlocation_allowed = true;
function __construct()
{
// set a file to store cookies
self::$cookie_file = ''cookies.txt'';
// set some general User Agent
self::$user_agent = ''Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'';
if ( ! file_exists(self::$cookie_file) || ! is_writable(self::$cookie_file))
{
throw new Exception(''Cookie file missing or not writable.'');
}
// check for PHP settings that unfits
// correct functioning of CURLOPT_FOLLOWLOCATION
if (ini_get(''open_basedir'') != '''' || ini_get(''safe_mode'') == ''On'')
{
self::$followlocation_allowed = false;
}
}
/**
* Main method for GET requests
* @param string $url URI to get
* @return string request''s body
*/
static public function get($url)
{
$process = curl_init($url);
self::_set_basic_options($process);
// this function is in charge of output request''s body
// so DO NOT include HTTP headers
curl_setopt($process, CURLOPT_HEADER, 0);
if (self::$followlocation_allowed)
{
// if PHP settings allow it use AUTOMATIC REDIRECTION
curl_setopt($process, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($process, CURLOPT_MAXREDIRS, self::$max_redirects);
}
else
{
curl_setopt($process, CURLOPT_FOLLOWLOCATION, false);
}
$return = curl_exec($process);
if ($return === false)
{
throw new Exception(''Curl error: '' . curl_error($process));
}
// test for redirection HTTP codes
$code = curl_getinfo($process, CURLINFO_HTTP_CODE);
if ($code == 301 || $code == 302)
{
curl_close($process);
try
{
// go to extract new Location URI
$location = self::_parse_redirection_header($url);
}
catch (Exception $e)
{
throw $e;
}
// IMPORTANT return
return self::get($location);
}
curl_close($process);
return $return;
}
static function _set_basic_options($process)
{
curl_setopt($process, CURLOPT_USERAGENT, self::$user_agent);
curl_setopt($process, CURLOPT_COOKIEFILE, self::$cookie_file);
curl_setopt($process, CURLOPT_COOKIEJAR, self::$cookie_file);
curl_setopt($process, CURLOPT_RETURNTRANSFER, 1);
// curl_setopt($process, CURLOPT_VERBOSE, 1);
// curl_setopt($process, CURLOPT_SSL_VERIFYHOST, false);
// curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false);
}
static function _parse_redirection_header($url)
{
$process = curl_init($url);
self::_set_basic_options($process);
// NOW we need to parse HTTP headers
curl_setopt($process, CURLOPT_HEADER, 1);
$return = curl_exec($process);
if ($return === false)
{
throw new Exception(''Curl error: '' . curl_error($process));
}
curl_close($process);
if ( ! preg_match(''#Location: (.*)#'', $return, $location))
{
throw new Exception(''No Location found'');
}
if (self::$max_redirects-- <= 0)
{
throw new Exception(''Max redirections reached trying to get: '' . $url);
}
return trim($location[1]);
}
}
Estoy tratando de hacer que Curl siga una redirección, pero no puedo hacer que funcione bien. Tengo una cadena que quiero enviar como un parámetro GET a un servidor y obtengo la URL resultante.
Ejemplo:
String = Kobold Vermin
Url = www.wowhead.com/search?q=Kobold+Worker
Si va a esa url, lo redireccionará a "www.wowhead.com/npc=257". Quiero que Curl devuelva esta URL a mi código PHP para que pueda extraer el "npc = 257" y usarlo.
Código actual:
function npcID($name) {
$urltopost = "http://www.wowhead.com/search?q=" . $name;
$ch = curl_init();
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_URL, $urltopost);
curl_setopt($ch, CURLOPT_REFERER, "http://www.wowhead.com");
curl_setopt($ch, CURLOPT_HTTPHEADER, Array("Content-Type:application/x-www-form-urlencoded"));
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
return curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
}
Sin embargo, esto devuelve www.wowhead.com/search?q=Kobold+Worker y no www.wowhead.com/npc=257 .
Sospecho que PHP está volviendo antes de que ocurra la redirección externa. ¿Cómo puedo arreglar esto?
Agregue esta línea para curizar la inizialización
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
y usa getinfo antes de curl_close
$redirectURL = curl_getinfo($ch,CURLINFO_EFFECTIVE_URL );
es:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_USERAGENT,''Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13'');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,0);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
$html = curl_exec($ch);
$redirectURL = curl_getinfo($ch,CURLINFO_EFFECTIVE_URL );
curl_close($ch);
La respuesta anterior no funcionó para mí en uno de mis servidores, algo relacionado con basedir, así que rehice un poco. El siguiente código funciona en todos mis servidores.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$a = curl_exec($ch);
curl_close( $ch );
// the returned headers
$headers = explode("/n",$a);
// if there is no redirection this will be the final url
$redir = $url;
// loop through the headers and check for a Location: str
$j = count($headers);
for($i = 0; $i < $j; $i++){
// if we find the Location header strip it and fill the redir var
if(strpos($headers[$i],"Location:") !== false){
$redir = trim(str_replace("Location:","",$headers[$i]));
break;
}
}
// do whatever you want with the result
echo redir;
La respuesta elegida aquí es decente, pero es sensible a mayúsculas y minúsculas, no protege contra la location:
relativa location:
encabezados (que hacen algunos sitios) o páginas que realmente pueden tener la frase Location:
en su contenido ... (que actualmente zillow).
Un poco descuidado, pero un par de ediciones rápidas para hacer esto un poco más inteligente son:
function getOriginalURL($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
$httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// if it''s not a redirection (3XX), move along
if ($httpStatus < 300 || $httpStatus >= 400)
return $url;
// look for a location: header to find the target URL
if(preg_match(''/location: (.*)/i'', $result, $r)) {
$location = trim($r[1]);
// if the location is a relative URL, attempt to make it absolute
if (preg_match(''/^//(.*)/'', $location)) {
$urlParts = parse_url($url);
if ($urlParts[''scheme''])
$baseURL = $urlParts[''scheme''].''://'';
if ($urlParts[''host''])
$baseURL .= $urlParts[''host''];
if ($urlParts[''port''])
$baseURL .= '':''.$urlParts[''port''];
return $baseURL.$location;
}
return $location;
}
return $url;
}
Tenga en cuenta que esto solo va a 1 redirección profunda. Para profundizar, realmente necesitas obtener el contenido y seguir los redireccionamientos.
Para hacer que cURL siga una redirección, use:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
Erm ... No creo que estés ejecutando el rizo ... Intenta:
curl_exec($ch);
... después de establecer las opciones, y antes de la llamada curl_getinfo()
.
EDITAR: Si solo quieres saber hacia dónde se redirige una página, usaría el consejo here , y simplemente usar Curl para tomar los encabezados y extraer el encabezado Location: de ellos:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
if (preg_match(''~Location: (.*)~i'', $result, $match)) {
$location = trim($match[1]);
}
Puedes usar:
$redirectURL = curl_getinfo($ch,CURLINFO_REDIRECT_URL);