jueves, 1 de mayo de 2014

[Parte 5] CURL en PHP

Funciones interesantes

curl_multi_init


Una de las extensiones mas usadas en PHP es cURL, y es genial para devolver documentos remotos. Para situaciones donde necesitas devolver multiples documentos se usa curl_multi_init y curl_multi_exec trabajan mejor con multiples documentos.

La funcion curl_multi_exec es muy poderosa, pero en la documentacion de PHP la hacen ver mas dificil de lo que realmente es. Aqui una demostracion usando Google, Bing y Facebook todos devueltos:

 $urls = array('http://www.google.com/', 'http://www.facebook.com/', 'http://www.bing.com/');
$url_count = count($urls); // cuenta el numero de urls

$curl_array = array(); // creamos un array llamado curl_array
$ch = curl_multi_init(); // iniciamos un multirecurso curl
// para las urls hay una clave que contiene su url
foreach($urls as $count => $url) {
 $curl_array[$count] = curl_init($url); // establecemos la url en una sesion curl refiriendonos a cada 1 con su clave
 curl_setopt($curl_array[$count], CURLOPT_FOLLOWLOCATION, 1); // le damos una opcion de seguir el header location
 curl_setopt($curl_array[$count], CURLOPT_RETURNTRANSFER, 1); // devolvemos el contenido
 curl_multi_add_handle($ch, $curl_array[$count]); // añadimos a cada url con sus opciones en el multirecurso
}
// mientras se esten ejecutando las urls realiza lo siguiente
do {
 curl_multi_exec($ch, $exec);
} while($exec > 0);


En este ejemplo hay 3 urls establecidas para devolverse al mismo tiempo. 


curl_multi_getcontent

Para leer el contenido de las peticiones que hicimos anteriormente podriamos usar la funcion curl_multi_getcontent. Vamos a ver como podemos hacerlo... (el codigo siguiente se puede añadir al anterior):


 //para cada url devolvemos el contenido junto con la url
foreach($urls as $count => $url) {
 $returned = curl_multi_getcontent($curl_array[$count]);
 echo "$url - $returned";
}



Cerrar el manejador de cURL


Algunos programadores prefieren usar curl_close() despues de haberlo usado. Usted en lugar de utilizar curl_close() deberia utilizar curl_multi_close(), y curl_multi_remove_handle() despues de que el contenido se haya devuelto. Veamos un ejemplo:



//para cada url eliminamos el manejador, cerramos la peticion multi recurso y cada peticion de una sesion curl la cerramos 
foreach($urls as $count => $url) {
 curl_multi_remove_handle($ch, $curl_array[$count]);
}

curl_multi_close($ch); 

foreach($urls as $count => $url) {
 curl_close($curl_array[$count]);
}


Como anteriormente dijimos el codigo anterior puede añadirse a lo que habiamos puesto antes... de esta manera todo el codigo quedaria asi:


 <?php
$urls = array('http://www.google.com/', 'http://www.facebook.com/', 'http://www.bing.com/');
$url_count = count($urls);

$curl_array = array();
$ch = curl_multi_init();

foreach($urls as $count => $url) {
 $curl_array[$count] = curl_init($url);
 curl_setopt($curl_array[$count], CURLOPT_FOLLOWLOCATION, 1);
 curl_setopt($curl_array[$count], CURLOPT_RETURNTRANSFER, 1);
 curl_multi_add_handle($ch, $curl_array[$count]);
}

do {
 curl_multi_exec($ch, $exec);
} while($exec > 0);
foreach($urls as $count => $url) {
 $returned = curl_multi_getcontent($curl_array[$count]);
 echo "$url - $returned";
}
foreach($urls as $count => $url) {
 curl_multi_remove_handle($ch, $curl_array[$count]);
}

curl_multi_close($ch); 

foreach($urls as $count => $url) {
 curl_close($curl_array[$count]);
}
?>

Fuente: http://www.fusionswift.com/2011/08/php-curl_multi_exec-example/



curl_setopt_array()


Con esta funcion podemos configurar multiples opciones para una transferencia cURL. Veamos un ejemplo:



 <?php
 // creamos un nuevo recurso curl
 $ch = curl_init();
 // establecemos las opciones apropiadas para la url
 $options = array(
  CURLOPT_URL => 'http://www.google.com/',
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_USERAGENT => 'Googlebot/2.1 (+http://www.google.com/bot.html)',
  CURLOPT_RETURNTRANSFER => true
  );
 curl_setopt_array($ch, $options);
 $output = curl_exec($ch);
 curl_close($ch);
 echo $output;
?>



curl_getinfo()


Esta funcion obtiene informacion relativa a una transferencia especifica. Los valores que devuelve son los siguientes:


  • "url"
  • "content_type"
  • "http_code"
  • "header_size"
  • "request_size"
  • "filetime"
  • "ssl_verify_result"
  • "redirect_count"
  • "total_time"
  • "namelookup_time"
  • "connect_time"
  • "pretransfer_time"
  • "size_upload"
  • "size_download"
  • "speed_download"
  • "speed_upload"
  • "download_content_length"
  • "upload_content_length"
  • "starttransfer_time"
  • "redirect_time"
  • "certinfo"
  • "request_header" 





curl_version()

Obtiene la informacion de la version de cURL





cURL File

Como veíamos en la parte 4 de curl, subiamos un archivo con el uso de @, pero apartir de PHP 5.5.0 ese prefijo esta obsoleto, por lo que se recomienda utilizar esta funcion.

CURLFile::__Construct--curl_file_create - Crea un objeto CURLFile

Estilo orientado a objetos:


public CURLFile::__construct ( string $filename [, string $mimetype [, string $postname ]] )

Estilo orientado a procedimientos:


CURLFile curl_file_create ( string $filename [, string $mimetype [, string $postname ]] )

Crea un objeto CurlFile, utilizado para transferir (upload) un fichero con CURLOPT_POSTFIELDS.

filename - indica la ruta de acceso al fichero a ser transferido
mimetype - Tipo mime del fichero
postname - nombre del fichero

Ejemplo, estilo orientado a objetos:



 <?php
/* http://example.com/upload.php:
<?php var_dump($_FILES); ?>
*/

// Crea un gestor cURL
$ch = curl_init('http://example.com/upload.php');

// Crea un objeto CURLFile
$cfile = new CURLFile('cats.jpg','image/jpeg','test_name');

// Asigna los datos POST 
$data = array('test_file' => $cfile);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

// Ejecuta el gestor
curl_exec($ch);
?>


Estilo por procedimientos:



 <?php
/* http://example.com/upload.php:
<?php var_dump($_FILES); ?>
*/

// Crea un gestor cURL
$ch = curl_init('http://example.com/upload.php');

// Crea un objeto CURLFile
$cfile = curl_file_create('cats.jpg','image/jpeg','test_name');

// Asigna los datos POST
$data = array('test_file' => $cfile);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

// Ejecuta el gestor
curl_exec($ch);
?>


Usar cURL con Expresiones regulares

Como en ejemplos anteriores usabamos la funcion preg_match y preg_match_all para ver si se encontraba determinado texto o link para poder mostrar el resultado que necesitabamos, para mas informacion sobre expresiones regulares por favor consulte:
http://www.arthusu.com.mx/2013/07/phpexpresiones-regulares-pcre.html

Como en el ejemplo de subidas de archivos en la parte 4  de curl, veíamos un upload con el cual sacábamos los links usando expresiones regulares:



 <?php
   set_time_limit(0);
   $url = "http://www0.xup.in/exec/xupload.php?uid=&key=";
   $user_agent = "Mozilla/5.0 (Windows NT 6.1; rv:28.0) Gecko/20100101 Firefox/28.0";
   $referer = "http://www.xup.in/";
   $directory=dirname(__FILE__).'\files/';
   if(isset($_FILES['f1'])){
      move_uploaded_file($_FILES['f1']['tmp_name'],"files/".$_FILES['f1']['name']);
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
      curl_setopt($ch, CURLOPT_REFERER, $referer);
      curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_POSTFIELDS, array("F1"=>"@".$directory.$_FILES['f1']['name']));
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
      $result = curl_exec($ch);
      if(curl_errno($ch))
  {
      echo 'Curl error: ' . curl_error($ch);
  }
      curl_close($ch);
      unlink($directory.$_FILES['f1']['name']);
      //echo $result;
      preg_match_all('/<input type="text" name="t1" size="90" class="inp" value="(.*?)" onclick="highlight\(this\);" \/>/', $result, $matches);
      //echo '<p><img src="'.$matches[1][0].'" alt="img" /></p>';
      echo '<p><b>Link: <a href="'.$matches[1][0].'" target="_blank">Archive Link</a></p>';
      //print_r($matches);
   }else{
      echo '
         <form action="upload_curl.php" method="post" enctype="multipart/form-data">
            <label for="f1">Filename:</label>
            <input type="file" name="f1" id="f1"><br>
            <input type="submit" name="submit" value="Submit">
         </form>

      ';   
   }
?>
 

No hay comentarios:

Publicar un comentario