• User Newbie

    Problema con Curl e CURLOPT_FOLLOWLOCATION

    Ciao a tutti e buona sera
    premetto che sono alle prime armi con PHP
    ho una classe (non fatta da me) che uso per recuperare dei dati da una pagina web
    [PHP]
    class CurlBrowser {
    function __construct() {
    $this->ckfile = tempnam ("/tmp", "SismicCookie");
    }
    function __destruct() {
    echo file_get_contents($this->ckfile);
    @unlink($this->ckfile);
    }
    function http_get($url, $outfile = null) {
    return $this->http_request($url, 'GET', null, $outfile);
    }
    function http_post($url, $data = array(), $outfile = null) {
    return $this->http_request($url, 'POST', $data, $outfile);
    }
    function http_request($url, $type, $data = null, $outfile = null) {
    $ch = curl_init($url);
    $outfileHandle = 0;
    if (!empty($outfile)) {
    $outfileHandle = fopen($outfile,'w');
    curl_setopt($ch, CURLOPT_FILE, $outfileHandle);
    }
    else
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    if (strtoupper($type) == 'POST') {
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
    }
    curl_setopt($ch, CURLOPT_COOKIEFILE, $this->ckfile);
    curl_setopt($ch, CURLOPT_COOKIEJAR, $this->ckfile);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
    curl_setopt($ch, CURLOPT_MAXREDIRS, 20);
    $out = curl_exec($ch);
    curl_close($ch);
    if ($outfileHandle!==0)
    fclose($outfileHandle);
    return $out;
    }
    }
    [/PHP]
    e la uso nello script richiamandola come da esempio sotto:
    [PHP]
    $browser=new CurlBrowser();
    $browser->http_post(
    'http : // www . xxx . it',
    array("Login"=>"Entra", "login_pwd"=>$password, "login_email"=>$email)
    );

    $browser->http_post(
    'http : // www . xxx . it',
    array(
    'date_from'=>$date_from,
    'date_to'=>$date_to,
    'town'=>'nessuno',
    'search'=>'Cerca'
    )
    );

    $csv_file = $browser->http_get('http : // www . xxx . it');

    [/PHP]

    e nella variabile $csv_file mi ritrovo un file csv, che poi utilizzo per recuperare dei valori e salvarli su MySql.

    tutto funzionava alla perfezione, finchè non ho cambiato provider
    il nuovo spazio ha open_basedir attivata (per sicurezza) e safe_mode disattivato.
    a causa del open_basedir attiva la seguente riga della classe va in errore:
    [PHP]
    //RIGA 129 è la seguente
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    [/PHP]
    e l'errore è:
    Warning: curl_setopt() [function.curl-setopt]: CURLOPT_FOLLOWLOCATION cannot be
    activated when safe_mode is enabled or an open_basedir is set in
    /home/xyz/public_html/xyz/include/function.php on line 129
    di questo errore se ne parla ampiamente su php.net (http : // us2.php.net / manual / en / function.curl-setopt.php#102121)
    ho chiesto al provider se è possibile (non ci speravo 😉 ) disattivare open_basedir , ma ovviamente mi hanno detto di no (hanno già disattivato il safe_mode che era on di default)
    mi hanno detto che una soluzione è presente qui:
    http : // simone.cabrino.it/blog/php-errore-curlopt_followlocation/
    in sostanza viene suggerita una funzione per ovviare al problema.
    questa:
    [PHP]
    function curl_redir_exec($ch) {
    static $curl_loops = -1;
    static $curl_max_loops = 10;
    if ($curl_loops++ >= $curl_max_loops) {
    $curl_loops = 0;
    return false;
    }
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $data = curl_exec($ch);
    list($header, $content) = explode(chr(10).chr(13).chr(10), $data);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    if ($http_code == 301 || $http_code == 302) {
    $matches = array();
    $matches = explode(chr(10),$header);
    foreach( $matches as $value) {
    $pos = strpos($value, "Location:");
    if ($pos === 0) {
    list($variabile,$url) = explode(" ",$value);
    }
    }
    $url = parse_url(trim($url));
    if (!$url) { //couldn't process the url to redirect to
    $data = array($curl_loops,curl_getinfo($ch),$data, curl_error($ch));
    return $data;
    }
    $last_url = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
    if (!isset($url['scheme']))
    $url['scheme'] = $last_url['scheme'];
    if (!isset($url['host']))
    $url['host'] = $last_url['host'];
    if (!isset($url['path']))
    $url['path'] = $last_url['path'];
    $new_url = $url['scheme'] . '://' . $url['host'] . $url['path'] . (isset($url['query'])?'?'.$url['query']:'');
    curl_setopt($ch, CURLOPT_URL, $new_url);
    return curl_redir_exec($ch);
    } else {
    $data = array($curl_loops,curl_getinfo($ch),$data, curl_error($ch));
    return $data;
    }
    }
    [/PHP]
    e la spiegazione dice:
    La funzione curl_exec_redir($ch) ritorna un?array a 4 dimensioni, contenente il numero di loop (redirect) effettuati [posizione 0], le informazioni sull?ultima interrogazione al server di destinazione [posizione 1], i dati (header e corpo della pagina) dell?ultima chiamata [posizione 2] e eventuali codici o stati d?errore [posizione 3].
    adesso, vorrei provare ad usarla, ma già non avevo capito come agicva Curl, figuriamoci se ho capito come/dove usare la funzione.
    Non è che mi dareste una piccola mano ?
    (lascio inoltre sia il problema che eventuale soluzione qui, caso mai qualcun' altro avesse lo stesso problema)
    Grazie
    Web.


  • User Newbie

    up
    speravo non fosse così difficile....
    ;(


  • User Newbie

    Risolto
    lascio qui la soluzione, nel caso serevisse ad altri
    ho integrato la funzione nello script
    ho modificato la classe, cambiando la riga
    $out = curl_exec($ch);
    in :
    $out = curl_redir_exec($ch);
    ho modificato lo script, nella riga in cui memorizza i risultati in una variabile.
    questo eprchè adesso non ottengo più la pagina, ma un array
    il contenuto della pagina (quello che mi interessa) è nell' indice 2
    quindi ho cambiato la riga
    $csv_file = $browser->http_get('http :// www . xxx . it');
    in
    $csv_iside_array = $browser->http_get('http :// iside .rm.ingv .it /iside/download?export=1&type=csv&data=EVENTS');
    e qindi aggiunto:
    $csv_iside = $csv_iside_array[2];
    Web