PHP e cURL: inviare richieste HTTP con gestione di redirect e URL finali

by theArchitect
SHARE
PHP e cURL: inviare richieste HTTP con gestione di redirect e URL finali
© Guida-HTML5.it

Introduzione

Quando si usa cURL in PHP, spesso ci si concentra solo sull’invio della richiesta e sulla lettura della risposta. In realtà, un aspetto molto utile e molto pratico è la gestione dei redirect HTTP, cioè quei casi in cui un URL risponde con un codice come 301 o 302 e indica al client di proseguire verso un altro indirizzo.

Questo scenario è comune in applicazioni reali: link abbreviati, pagine spostate, endpoint che cambiano versione, servizi esterni che reindirizzano da HTTP a HTTPS. Se non gestisci correttamente i redirect, potresti salvare URL sbagliati, perdere informazioni utili oppure fermarti alla prima risposta senza raggiungere la risorsa finale.

In questo tutorial vedremo come usare cURL in PHP per:

  • seguire automaticamente i redirect;
  • ottenere l’URL finale dopo tutti i passaggi;
  • distinguere tra URL iniziale e URL effettivamente raggiunto;
  • gestire in modo sicuro i casi in cui il redirect non è consentito o non funziona.

Codice completo

<?php
/**
 * Esempio pratico: eseguire una richiesta HTTP con cURL
 * seguendo i redirect e recuperando l´URL finale.
 */

function fetchWithRedirects(string $url): array
{
    $ch = curl_init();

    curl_setopt_array($ch, [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,   // segue i redirect 301, 302, 307, 308
        CURLOPT_MAXREDIRS => 5,            // limite di sicurezza
        CURLOPT_TIMEOUT => 15,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_HEADER => true,           // include header + body nella risposta
        CURLOPT_USERAGENT => ´PHP cURL Redirect Tutorial/1.0´,
    ]);

    $response = curl_exec($ch);

    if ($response === false) {
        $error = curl_error($ch);
        $errno = curl_errno($ch);
        curl_close($ch);

        return [
            ´success´ => false,
            ´error´ => "Errore cURL ($errno): $error",
        ];
    }

    $info = curl_getinfo($ch);

    // Separiamo header e body usando la dimensione dell´header finale.
    // Nota: con redirect multipli, curl_getinfo(´header_size´) si riferisce
    // all´ultimo blocco di header ricevuto.
    $headerSize = $info[´header_size´];
    $headers = substr($response, 0, $headerSize);
    $body = substr($response, $headerSize);

    curl_close($ch);

    return [
        ´success´ => true,
        ´requested_url´ => $url,
        ´final_url´ => $info[´url´] ?? $url,
        ´http_code´ => $info[´http_code´] ?? 0,
        ´redirect_count´ => $info[´redirect_count´] ?? 0,
        ´content_type´ => $info[´content_type´] ?? ´´,
        ´headers´ => $headers,
        ´body´ => $body,
    ];
}

// URL di esempio: un servizio che effettua redirect verso HTTPS
$result = fetchWithRedirects(´http://example.com´);

if (!$result[´success´]) {
    echo ´<p>Errore: ´ . htmlspecialchars($result[´error´]) . ´</p>´;
    exit;
}

echo ´<h3>Risultato richiesta</h3>´;
echo ´<p>URL richiesto: ´ . htmlspecialchars($result[´requested_url´]) . ´</p>´;
echo ´<p>URL finale: ´ . htmlspecialchars($result[´final_url´]) . ´</p>´;
echo ´<p>Codice HTTP finale: ´ . (int)$result[´http_code´] . ´</p>´;
echo ´<p>Numero redirect: ´ . (int)$result[´redirect_count´] . ´</p>´;

echo ´<h3>Header finali</h3>´;
echo ´<pre>´ . htmlspecialchars($result[´headers´]) . ´</pre>´;

echo ´<h3>Body della risposta</h3>´;
echo ´<pre>´ . htmlspecialchars(substr($result[´body´], 0, 500)) . ´</pre>´;
?>

Spiegazione

Il codice sopra crea una funzione fetchWithRedirects() che riceve un URL, esegue la richiesta e restituisce un array con i dati più utili. Vediamo i punti principali.

1. CURLOPT_FOLLOWLOCATION

Questa opzione dice a cURL di seguire automaticamente i redirect. Se il server risponde con un codice 301, 302, 307 o 308 e un header Location, cURL effettuerà una nuova richiesta verso l’URL indicato.

È la parte più importante del tutorial, perché evita di dover leggere manualmente il redirect e rilanciare la richiesta con un secondo passaggio.

2. CURLOPT_MAXREDIRS

Impostare un limite al numero di redirect è una buona pratica. Senza limite, un server mal configurato potrebbe causare un ciclo infinito, ad esempio:

  • URL A redirige verso URL B
  • URL B redirige verso URL A

Con CURLOPT_MAXREDIRS blocchi il comportamento dopo un numero massimo di passaggi, proteggendo la tua applicazione da loop indesiderati.

3. CURLOPT_HEADER e separazione header/body

Con CURLOPT_HEADER => true cURL restituisce sia gli header HTTP sia il corpo della risposta in un’unica stringa. Questo è utile quando vuoi analizzare i metadati della risposta, ma richiede di separare i due blocchi usando header_size ottenuto da curl_getinfo().

Nel nostro esempio, gli header finali e il body vengono estratti con substr(). Questo approccio è molto pratico quando vuoi ispezionare la risposta finale dopo i redirect.

4. curl_getinfo() e URL finale

La funzione curl_getinfo() fornisce informazioni preziose sulla richiesta. Tra queste, il campo url indica l’URL finale effettivamente raggiunto, cioè quello dopo eventuali redirect.

Questo è molto utile in casi come:

  • normalizzare URL memorizzati nel database;
  • verificare la destinazione reale di un link esterno;
  • controllare se un sito forza il passaggio da HTTP a HTTPS;
  • registrare il percorso finale di una risorsa.

5. Gestione degli errori

Se la richiesta fallisce, il codice usa curl_error() e curl_errno() per restituire un messaggio chiaro. È importante non limitarsi a controllare solo il codice HTTP: alcuni problemi, come errore di rete o timeout, si verificano prima di ricevere una risposta dal server.

Best practice

  • Imposta sempre un limite ai redirect con CURLOPT_MAXREDIRS per evitare loop infiniti.
  • Usa timeout ragionevoli per non bloccare il flusso dell’applicazione in caso di server lenti o non raggiungibili.
  • Controlla sempre l’URL finale quando il risultato della richiesta ha valore funzionale o di sicurezza.
  • Non fidarti ciecamente dei redirect esterni: in contesti sensibili, verifica che il dominio finale sia consentito.
  • Separa sempre errori di rete e errori HTTP: un 404 non è la stessa cosa di un timeout o di un DNS fallito.
  • Usa un User-Agent esplicito per rendere più chiaro il comportamento del tuo client verso i server remoti.
  • Se devi analizzare redirect multipli, valuta di salvare anche gli header intermedi, non solo quelli finali.

Riepilogo

La gestione dei redirect con cURL in PHP è una competenza molto utile perché ti permette di lavorare con URL dinamici, migrazioni di sito e servizi esterni senza perdere il controllo della richiesta. Con poche opzioni ben scelte puoi:

  • seguire automaticamente i redirect;
  • limitare i passaggi per sicurezza;
  • recuperare l’URL finale raggiunto;
  • analizzare header e body della risposta;
  • gestire correttamente gli errori di rete.

Se sviluppi script di integrazione, crawler, strumenti di monitoraggio o semplici utility per validare link, questo approccio ti farà risparmiare tempo e ti aiuterà a scrivere codice più robusto.

Approfondisci con risorse ufficiali

  • PHP Manual - cURL: documentazione ufficiale delle funzioni e delle opzioni cURL in PHP.
  • PHP Manual - curl_setopt(): elenco completo delle opzioni configurabili.
  • PHP Manual - curl_getinfo(): informazioni disponibili dopo l’esecuzione della richiesta.
  • cURL Official Documentation: approfondimenti sul comportamento delle opzioni lato libreria.

SHARE