PHP cURL Redirect Tanpa Opsi FOLLOWLOCATION
Tidak seperti file_get_contents(), standarnya cURL di PHP tidak mengikuti redirect (pengalihan halaman). Harus mengaktifkan CURLOPT_FOLLOWLOCATION agar bisa mengikuti redirect. Namun tidak semua hosting menggunakan konfigurasi yang mengijinkan fitur ini. Seperti saat safe_mode atau open_basedir diaktifkan karena alasan keamanan. Untuk itu saya mencoba menulis fungsi berikut untuk mengatasi hal ini.
Berikut adalah fungsi untuk PHP >= 5.3.7 karena konstan CURLINFO_REDIRECT_URL tersedia sejak versi tersebut:
function curl_get_contents($url, $headers = array(), $maxredirs = 0) { static $ch, $redirscount = 0; $ch or $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $contents = curl_exec($ch); $redir = curl_getinfo($ch, CURLINFO_REDIRECT_URL); if ($redir && $redir != $url && ($maxredirs < 0 || $redirscount < $maxredirs)) { $redirscount++; $headers['Referer'] = 'Referer: ' . $url; return curl_get_contents($redir, $headers, $maxredirs); } else { curl_close($ch); $ch = $redirscount = 0; return $contents; } }
Berikut adalah fungsi kompatibel untuk PHP versi lama. Mungkin PHP >= 4.0.2. Namun hanya saya uji pada PHP 5.2.x:
function curl_get_contents_compat($url, $headers = array(), $maxredirs = 0) { static $ch, $redirscount = 0; $ch or $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate'); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $contents = curl_exec($ch); $first = true; $redir = $body = null; $tok = strtok($contents, "\n"); while ($tok !== false) { $tok = rtrim($tok); if ($first && !$tok) { $body = null; $first = false; } elseif ($first && strpos($tok, 'Location: ') === 0) { $redir = str_replace('Location: ', null, $tok); $body = null; break; } else { $body .= $tok . "\n"; } $tok = strtok("\n"); } if ($redir && $redir != $url && ($maxredirs < 0 || $redirscount < $maxredirs)) { $redirscount++; $headers['Referer'] = 'Referer: ' . $url; if (strpos($redir, '://') === false) { // relative url $path_pos = strpos($url, '/', 8); if ($redir[0] == '/') { $redir = substr($url, 0, $path_pos) . $redir; } else { $path = substr(strtok($url, '?'), $path_pos); $url = substr($url, 0, $path_pos) . '/'; if (strpos(basename($path), '.') === false) { $url .= ltrim($path, '/'); } else { $url .= ltrim(substr($path, 0, strrpos($path, '/')), '/'); } $redir = rtrim($url, '/') . '/' . $redir; } } return curl_get_contents_compat($redir, $headers, $maxredirs); } else { curl_close($ch); $ch = $redirscount = 0; return $body; } }
Berikut adalah fungsi wrapper yang akan otomatis menyesuaikan:
function get_contents($url, $headers = array(), $maxredirs = 0) { return defined('CURLINFO_REDIRECT_URL') ? curl_get_contents($url, $headers, $maxredirs) : curl_get_contents_compat($url, $headers, $maxredirs); }
Penggunaan:
Argumen pertama adalah wajib. Sisanya opsional.
$maxredirs standar nilainya -1, berarti redirect tak terbatas.
Contoh:
http://localhost/target.php
<?php header('Location: http://localhost/target1.php');
http://localhost/target1.php
<?php header('Location: http://localhost/target2.php');
http://localhost/target2.php
<?php phpinfo();
http://localhost/test.php
<?php // Paste tiga fungsi diatas ke sini echo get_contents('http://localhost/target.php');
Jika ingin membuat cURL benar-benar terdeteksi seperti browser tertentu, bisa menambahkan opsi $headers yang berupa array:
http://localhost/test.php
<?php // Paste tiga fungsi diatas ke sini $headers = array(); $headers[] = 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0'; $headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'; $headers[] = 'Accept-Language: en-US,en;q=0.5'; echo get_contents('http://localhost/target.php', $headers);
Selalu cek halaman ini karena selalu diperbaharui.
Update: Silahkan cek github saya: https://github.com/nggit/php-simple-client
|