[ Text ]

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:

  1. function curl_get_contents($url, $headers = array(), $maxredirs = 0) { 
  2.     static $ch, $redir, $redirscount = 0; 
  3.     $ch or $ch = curl_init(); 
  4.     curl_setopt($ch, CURLOPT_URL, $url); 
  5.     curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 
  6.     curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate'); 
  7.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
  8.     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
  9.     curl_setopt($ch, CURLOPT_TIMEOUT, 10); 
  10.     $contents = curl_exec($ch); 
  11.     $redir    = curl_getinfo($ch, CURLINFO_REDIRECT_URL); 
  12.     if ((!$maxredirs || $redirscount < $maxredirs) && $redir && $redir !== $url) { 
  13.         $redirscount++; 
  14.         $headers['Referer'] = 'Referer: '.$url; 
  15.         return curl_get_contents($redir, $headers, $maxredirs); 
  16.     } 
  17.     else { 
  18.         $redirscount = 0; 
  19.         curl_close($ch); 
  20.         return $contents; 
  21.     } 
  22. } 

Berikut adalah fungsi kompatibel untuk PHP versi lama. Mungkin PHP >= 4.0.2. Namun hanya saya uji pada PHP 5.2.x:

  1. function curl_get_contents_compat($url, $headers = array(), $maxredirs = 0) { 
  2.     static $ch, $redir, $redirscount = 0; 
  3.     $ch or $ch = curl_init(); 
  4.     curl_setopt($ch, CURLOPT_URL, $url); 
  5.     curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 
  6.     curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate'); 
  7.     curl_setopt($ch, CURLOPT_HEADER, true); 
  8.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
  9.     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
  10.     curl_setopt($ch, CURLOPT_TIMEOUT, 10); 
  11.     $contents = curl_exec($ch); 
  12.     $body     = null; 
  13.     $first    = true; 
  14.     $tok      = strtok($contents, "\n"); 
  15.     while ($tok !== false) { 
  16.         $tok = rtrim($tok); 
  17.         if ($first && !$tok) { 
  18.             $body  = null; 
  19.             $first = false; 
  20.         } 
  21.         elseif ($first && strpos($tok, 'Location: ') === 0) { 
  22.             $redir = str_replace('Location: ', null, $tok); 
  23.             $body  = null; 
  24.             break; 
  25.         } 
  26.         else { 
  27.             $body .= $tok."\n"; 
  28.         } 
  29.         $tok = strtok("\n"); 
  30.     } 
  31.     if ((!$maxredirs || $redirscount < $maxredirs) && $redir && $redir !== $url) { 
  32.         $redirscount++; 
  33.         $headers['Referer'] = 'Referer: '.$url; 
  34.         return curl_get_contents_compat($redir, $headers, $maxredirs); 
  35.     } 
  36.     else { 
  37.         $redirscount = 0; 
  38.         curl_close($ch); 
  39.         return $body; 
  40.     } 
  41. } 

Berikut adalah fungsi wrapper yang akan otomatis menyesuaikan:

  1. function get_contents($url, $headers = array(), $maxredirs = 0) { 
  2.     return defined('CURLINFO_REDIRECT_URL') ? curl_get_contents($url, $headers, $maxredirs) 
  3.                                             : curl_get_contents_compat($url, $headers, $maxredirs); 
  4. } 

Penggunaan:
Argumen pertama adalah wajib. Sisanya opsional. $maxredirs standar nilainya 0, berarti redirect tak terbatas.

Contoh:

http://localhost/target.php
  1. <?php 
  2.  
  3. header('Location: http://localhost/target1.php'); 

http://localhost/target1.php
  1. <?php 
  2.  
  3. header('Location: http://localhost/target2.php'); 

http://localhost/target2.php
  1. <?php 
  2.  
  3. phpinfo(); 

http://localhost/test.php
  1. <?php 
  2.  
  3. // Paste tiga fungsi diatas ke sini 
  4.  
  5. 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
  1. <?php 
  2.  
  3. // Paste tiga fungsi diatas ke sini 
  4.  
  5. $headers   = array(); 
  6. $headers[] = 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0'; 
  7. $headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'; 
  8. $headers[] = 'Accept-Language: en-US,en;q=0.5'; 
  9. $headers[] = 'Connection: keep-alive'; 
  10. echo get_contents('http://localhost/target.php', $headers); 

Selalu cek halaman ini karena selalu diperbaharui.