PHP: Errore CURLOPT_FOLLOWLOCATION
Programmazione Thursday 1 November 2007 alle 20:59Usando le funzioni e le variabili predefinite di cURL ho trovato questo errore:
Warning: curl_setopt() [function.curl-setopt]: CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set in /var/www/vhosts/DOMAIN_NAME/httpdocs/PAGE.php on line ###
Leggendo le specifiche di PHP e di cURL, ho scoperto che la funzione per seguire i redirect “follow redirect”, attivabile grazie all’opzione CURL_FOLLOWLOCATION, è stata disabilitata già nel lontano 17/08/2006 per problemi dovuti alla sicurezza. Come si spiega in PHP.net, cURL non è parte di PHP, anche se è stato integrato in esso: come permettere a milioni di gestori di server in PHP di soffrire di una falla così grossa?
Soluzione 1: disattivare open_basedir e safe_mode
Un modo per rimuovere l’errore e poter utilizzare correttamente tutte le funzioni di cURL, è avere le variabili safe_mode e open_basedir disabilitate o nulle. Questa soluzione, seppure se funzionale, apre la falla di cui ho parlato nel paragafo d’apertura, quindi è consigliabile solo nel caso in cui facciate girare Server Apache e PHP in locale per propri test. E’ consigliato a tutti i mantainer di mantenere sempre la variabile di sistema open_basedir impostata in una cartella temporanea e nella root del dominio degli utenti.
Per disabilitare la variabile, occorre quindi inserire nelle direttive nel file di configurazione di Apache (/etc/apache/httpd.conf) le seguenti righe :
php_admin_flag safe_mode off
php_admin_value open_basedir none
open_basedir none: imposta (setta) la variabile open_basedir ad un valore “null” che permette di lavorare senza restrizioni
safe_mode off: disabilita il “safe_mode” di PHP, imponendo molti meno vincoli sulla programmazione. La maggior parte degli hosting ha già questa variabile impostata su off.
Soluzione 2: funzione curl_exec() alternativa
Sempre leggendo le specifiche di cURL in PHP.net ho trovato una soluzione “possibile”, se non fosse che provare ad utilizzarla mi solleva un altro tipo di errore. Ho pensato allora di riscrivere la funzione, aggiungendo nel contempo alcune funzionalità.
Scrivo qui il codice della funzione curl_redir_exec($ch) utilizzata da alcune applicazioni create a scopo di studio.
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;
}
}
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].
Spero che questa funzione possa essere a tutti il più utile possibile! Se avete suggerimenti o consigli su come migliorarla, fatemi sapere…
18 November 2010 alle 1:13
ciao scusa la seconda soluzione dove devo inserire quei codici? grazie