159 votes

Faire friser suit les redirections ?

Je suis en train de faire du roulage suivre une redirection, mais je n'arrive pas à le faire fonctionner à droite. J'ai une chaîne que je veux envoyer un paramètre à un serveur et obtenir la URL.

Exemple:

String = Kobold Vermine
Url = www.wowhead.com/search?q=Kobold+Travailleur

Si vous allez à l'url il va vous rediriger vers "www.wowhead.com/npc=257". Je veux curl de retour cette URL dans mon code PHP pour que je puisse extraire le "npc=257" et de l'utiliser.

Code actuel:

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

Toutefois, cela renvoie www.wowhead.com/search?q=Kobold+Travailleur et pas www.wowhead.com/npc=257.

Je soupçonne que PHP est de retour avant la redirection externe qui se passe. Comment puis-je résoudre ce problème?

266voto

Matt Gibson Points 15086

Pour faire du roulage suivre une redirection, utilisez:

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

Hum... je ne pense pas que vous êtes réellement l'exécution de la boucle... à Essayer:

curl_exec($ch);

...après le réglage des options, et avant la curl_getinfo ().

EDIT: Si vous voulez juste savoir où se trouve une page de redirection, je préfère utiliser les conseils ici, et il suffit d'utiliser Curl pour saisir les en-têtes et de l'extrait de l'en-tête location: à partir de:

$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);
if(preg_match('#Location: (.*)#', $a, $r))
 $l = trim($r[1]);

8voto

GR1NN3R Points 61

La réponse ci-dessus n’a pas fonctionné pour moi sur un de mes serveurs, quelque chose à basedir, donc j’ai re-il haché un peu. Le code ci-dessous fonctionne sur tous mes serveurs.

5voto

broox Points 988

La réponse choisie ici est décent, mais sa casse, ne protège pas contre par rapport location: - têtes (que certains sites ne) ou les pages qui pourraient en fait avoir l'expression Location: dans leur contenu... (qui zillow ne le fait actuellement).

Un peu bâclée, mais quelques modifications rapides à faire de cela un peu plus intelligents sont:

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

Notez que cela ne va 1 la redirection de profondeur. Pour aller plus loin, vous avez vraiment besoin pour obtenir le contenu et suivre les redirections.

5voto

Igor Parra Points 3858

Parfois vous devez obtenir les en-têtes HTTP, mais en même temps vous ne voulez pas retour ces headers.

Ce squelette s’occupe de cookies et de redirections HTTP à l’aide de la récursivité. L’idée principale ici est d’éviter le retour des en-têtes HTTP au code client.

Vous pouvez créer une classe très forte courbure au-dessus de lui. Ajouter la fonctionnalité de message, etc..

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X