Utilisation de CURL en PHP

20 June 2012 par Franck de Védrines

Dans cet article, nous parlerons de l'extension CURL en PHP. Nous verrons d'abord pourquoi CURL a été créé et à quoi il peut bien nous servir. Nous en étudierons ensuite les bases et verrons comment cela fonctionne pour récupérer des informations en simulant la validation d'un formulaire avec ou sans paramètre (GET et POST).

Ensuite, nous verrons quelles sont les principales options (CURLOPT_) que nous offre ce service, en commençant par l'utilisation de proxies ou de cookies. Pour finir sur l'utilisation de CURL, nous verrons comment ce dernier nous permet une gestion d'erreurs puissante.

Enfin, nous réaliserons un exemple concret : nous nous connecterons à notre blog WordPress dans le but de récupérer tous les articles postés.

Pré-requis

Nous allons réaliser ce tutoriel en utilisant Apache. Par conséquent, il va falloir activer l'extension CURL. L'extension en question se nomme « php_curl ».

Sur un système UNIX, il faut d'abord l'installer en tapant « apt-get install php5-curl » en ligne de commande. Ensuite, il faut l'activer.  Dans votre fichier php.ini (/etc/apache2/php5/php.ini, à modifier selon votre configuration), ajouter ou décommenter la ligne suivante :

« extension=php_curl.dll »

Redémarrez ou recharger ensuite apache.

A quoi ça sert

CURL, qui est l'abréviation de Client URL Request Library, est un outil qui permet de communiquer avec différents types de serveurs, de transférer des fichiers et des données à travers différents protocoles tels que HTTP, TELNET ou encore FTP.

CURL gère par ailleurs différentes options que nous verrons plus tard, comme l'utilisation de serveurs mandataires (Proxy), l'utilisation de cookies (utiles pour l'authentification), et bien d'autres.

Pour donner des exemples, avec CURL, vous pourrez :

  • Récupérer tout type d'information sur différents sites web
  • Vous connecter à votre compte (en soumettant le formulaire d'identification) sur votre site favori et récupérer les informations qui vous intéressent
  • Poster un article sur votre blog (WordPress, etc..)
  • Récupérer vos mails automatiquement
  • etc.

Initialement, CURL a été créé pour être utilisé en ligne de commande. Heureusement, la bibliothèque a été portée en PHP et est présente nativement dans le langage. Nous nous baserons sur celle-ci dans ce tutoriel.

Les bases

Dans cette partie, nous allons voir les bases du protocole CURL.

Tout d'abord, il faut savoir trois choses importantes avant de démarrer:

  • La fonction qui permet d'initialiser une session est « curl_init » qui peux prendre en paramètre l'URL de la requête (on peut également utiliser l'option CURLOPT_URL pour définir cette url)
  • La fonction qui permet de définir des options est « curl_setopt »
  • La fonction qui permet d’exécuter la requête est « curl_exec »

Nous allons donc afficher simplement le contenu d'une page (http://www.google.fr).

Cela passe par 4 étapes. Ces 4 étapes sont valables pour n'importe quelle requête :

  • Initialisation de la session CURL
  • Définitions des options
  • Exécution de la requête
  • Fermeture de la session

Voici donc le code qui traduit ces étapes :

/** Etape 1 : initialisation de la session **/
$ch = curl_init() ;
/** Etape 2 : définition des options **/
curl_setopt($ch, CURLOPT_URL, 'http://www.google.fr');
/** Etape 3 : exécution de la requête **/
curl_exec($ch) ;
/** Etape 4 : fermeture de la session **/
curl_close($ch) ;

Normalement, en écrivant ce code, vous devez voir le contenu de la page http://www.google.fr affiché sur votre écran.

Récupération d'informations (POST et GET)

Pourquoi CURL ?

En PHP, pour récupérer des informations sur un site web, vous pouvez tout à fait vous servir d'autres fonctions, telles que « file_get_contents », « file » ou bien « open ». Cependant, ces fonctions, bien qu'elles puissent être utiles pour certains besoins, ont plusieurs défauts importants :

  • La gestion des erreurs est mieux gérée avec CURL (ce dernier fournit de nombreuses informations sur les requêtes, nous verrons cela par la suite)
  • Ces fonctions ne sont pas vraiment adaptées à l'utilisation d'options comme les cookies, les proxies, la définition des en-têtes, etc.
  • CURL est une bibliothèque puissante permettant de faire pratiquement tout en terme de requêtes, alors autant ne pas se priver.

Comment utiliser les options ?

Pour déclarer une option, il suffit d'utiliser la fonction « curl_setopt », dont les paramètres sont les suivants :

  • 1er paramètre : la ressource curl initialisée plus tôt
  • 2ème paramètre : l'option que l'on veut renseigner
  • 3ème paramètre : la valeur que doit prendre cette option

Récupérer des informations

Nous verrons les principales options dans la partie « option » de ce tutoriel, mais les options permettant la récupération d'informations et la soumission de formulaires nécessitent une partie qui leur est propre car elles sont souvent utilisées, permettent de bien comprendre les bases et d'avoir une première vision de la puissance de CURL.

Dans l'exemple précédent, le contenu de la page est affiché sur notre navigateur. Nous aimerions maintenant le récupérer dans une variable plutôt que de l'afficher, cela afin de pouvoir réaliser différentes opérations sur ce contenu.

Il y a une option pour cela : « CURLOPT _RETURNTRANSFER ». Lorsque cette option est définie à true, le contenu est renvoyé par la fonction « curl_exec ». Lorsqu'elle est définie à false, « curl_exec » renvoit un booléen permettant de savoir si la requête a bien été exécutée.

Donc, pour récupérer le contenu de la page http://www.google .fr dans une variable, il suffit d'écrire :

/** Etape 1 : initialisation de la session **/
$ch= curl_init() ;
/** Etape 2 : définition des options **/
curl_setopt($ch, CURLOPT_URL, "http://www.google.fr");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
/** Etape 3 : exécution de la requête **/
$content_google = curl_exec($ch) ;
/** Etape 4 : fermeture de la session **/
curl_close($ch) ;
/** Si on veut afficher le contenu **/
echo $content_google ;

Soumission de formulaire

Soumettre un formulaire de manière automatique est une tâche relativement facile avec CURL. Pour faire cela, nous utiliserons 2 options :

  • CURLOPT_POST : permet de définir le protocole utilisé (true pour « POST », false pour « GET » (valeur par défaut))
  • CURLOPT_POSTFIELDS : permet de définir les données du formulaire (ou les champs à soumettre)

Lorsque l'on veut soumettre un formulaire, il faut initialiser la session CURL avec l'url correspondant au champ « action » de ce formulaire.

On va maintenant essayer de rechercher le terme « PS3 » dans la catégorie « Jeux Vidéo » du site http://www.amazon.fr :

$postfield = array(
   'field-keywords' => 'PS3',
   'url' => 'search-alias=videogames'
);
/** Etape 1 : initialisation de la session * */
$ch = curl_init();
/** Etape 2 : définition des options * */
// Champ action du formulaire de recherche
curl_setopt($ch, CURLOPT_URL, 'http://www.amazon.fr/s/');
// On fait une requête de type POST
curl_setopt($ch, CURLOPT_POST, true);
// On indique les champs à soumettre
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfield);
// On veut que le contenu soit stocké dans une variable et non affiché directement sur notre page
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
/** Etape 3 : exécution de la requête * */
$content_search_amazon = curl_exec($ch);
/** Etape 4 : fermeture de la session * */
curl_close($ch);
/** Si on veut afficher le contenu * */
echo $content_search_amazon;

Facile, non ? En quelques lignes de codes, on a réussi à créer un petit script qui permettra de nous faciliter la vie.

Attention cependant, certains formulaires sont plus compliqués à soumettre, par exemple les formulaires possédant un Captcha de confirmation ou bien un champ ayant une valeur auto générée lors de la soumission ; nous n'en parlerons pas dans ce tutoriel.

Les options

CURL permet de faire de nombreuses choses, et les options sont là pour ça. Il existe près de 100 options que l'on peut utiliser. Bien entendu, nous ne pourrons pas toutes les voir ; nous étudierons les principales, c'est-à-dire celle dont on se sert le plus souvent.

Vous pouvez trouver la liste des fonctions complète sur le site officiel de PHP pour la fonction curl_setopt.

Les proxies

Pour utiliser des proxies, c'est très simple. Il y a trois fonctions utiles pour cela :

  • CURLOPT_PROXY : le nom du proxy (IP:port) ; par exemple : « monproxy.com:8080 »
  • CURLOPT_PROXYUSERPWD (login:password) : si le proxy nécessite une authentification ; par exemple : « login :password »
  • CURLOPT_HTTPPROXYTUNNEL : si l'on souhaite passer par un proxy de type HTTP

Les cookies

L'utilisation de cookie avec CURL peut s'avérer très utile. Souvent, les sites sur lesquels nous naviguons requièrent une authentification avant de pouvoir accéder à différentes pages (Compte mail, blog, etc..). Il serait donc utile de mémoriser cette identification (sur un temps limité car les cookies ont une date limite) afin de ne pas avoir à se reconnecter à chaque fois pour consulter les pages qui nous intéressent.  Les cookies vont nous permettre de réaliser cela.

Voici un exemple de processus illustrant l'utilisation de cookies avec CURL :

  • On se connecte sur son site WordPress et on sauvegarde les cookies contenant les données de connexion
  • On ferme la session courante CURL
  • On veut écrire un article sans avoir à se reconnecter : on initialise une session CURL et on charge les cookies stockés précédemment pour s'identifier
  • On a maintenant accès aux pages nécessitant une identification

Trois options nous intéressent ici :

  • CURLOPT_COOKIE : le contenu du cookie (nom=valeur) ; par exemple
    « curl_setopt(CURLOPT_COOKIE, 'prenom=franck') »
  • CURLOPT_COOKIJAR : le nom du fichier dans lequel curl va stocker les cookies internes pouvant être réutilisés plus tard, même après fermeture de la session.
  • CURLOPT_COOKIFILE : le nom du fichier contenant les données des cookies à utiliser pour la session (qui peuvent être sauvegardés via la fonction CURLOPT_COOKIEJAR).

Options utiles

D'autres options sont également très utiles. Voici celles dont il est important de connaître l'existence :

  • CURLOPT_FRESH_CONNECT : pour forcer l'établissement d'une nouvelle connexion plutôt que celle en cache
  • CURLOPT_HEADER : permet d'inclure les informations d'en-tête dans la valeur de retour (Content-Type, Transfer-Encoding, etc..)
  • CURLOPT_HTTPHEADER : Permet de spécifier les valeurs d'en-têtes
  • CURLOPT_NOBODY : pour indiquer à curl de ne pas lire le contenu (même si la variable Content-Lenght est définie)
  • CUTLOPT_TIMEOUT : temps maximal d'exécution de la requête (en secondes), et donc de la fonction curl_exec
  • CURLOPT_FOLLOWLOCATION : pour suivre les redirections de type 'Location:'
  • CURLOPT_MAXREDIRS : Nombre maximal de redirections http à suivre (si l'option CURLOPT_FOLLOWLOCATION est à true)
  • CURLOPT_CONNECTTIMEOUT : durée maximale d'établissement de la connexion vers l'hôte (en seconds)
  • CURLOPT_PORT : le port à utiliser pour la requête
  • CURLOPT_AUTOREFERER : pour que CURL définisse automatiquement le referer (lors d'une redirection par exemple)
  • CURLOPT_REFERER : pour spécifier votre propre referer
  • CURLOPT_USERAGENT : pour spécifier un user-agent

Gestion des erreurs

Un autre point important est la gestion des erreurs avec CURL. En effet, bien souvent, les développeurs oublient à quel point une bonne gestion des erreurs est importante. Avec CURL, il peut arriver de se heurter à des erreurs qui peuvent paraître bizarres (par exemple une page blanche).

Grâce aux options de CURL, vous allez pouvoir avoir plus d'informations sur les différentes erreurs de vos requêtes.

Code d'erreur

Tout d'abord, il faut savoir que CURL met à disposition une fonction, « curl_errno », qui permet de récupérer le code d'erreur de votre requête. Par exemple, le code 1 signifie que l'url est mal formatée, le code 9 signifie que l'accès à la ressource n'est pas autorisé, etc..

Vous trouverez sur le site de CURL la liste complète des codes d'erreur.

Message d'erreur

Simple mais efficace, la fonction « curl_error » retourne une chaîne de caractères contenant le dernier message d'erreur.

Informations sur la requête

Il existe également une fonction qui permet de récupérer de nombreuses informations sur la requête : « curl_getinfo ».

Le premier argument de cette fonction est la ressource courante CURL.
Le second argument est facultatif. S'il est renseigné, la fonction retournera une chaîne de caractère contenant l'information relative à l'argument, sinon elle retournera un tableau associatif contenant les différentes informations.

La liste complète des informations se trouve sur le site de PHP pour la fonction curl_getinfo

Parmi ces informations, on trouve par exemple :

  • Le dernier code http reçu (CURLINFO_HTTP_CODE)
  • Le nombre d'octets envoyé (CURLINFO_SIZE_UPLOAD)
  • Le nombre d'octets reçus (CURLINFO_SIZE_DOWNLOAD)
  • Vitesse moyenne de téléchargement (CURLINFO_SPEED_DOWNLOAD)
  • etc.

Exemple concret

Maintenant que l'on a vu les bases de CURL et son utilisation générale, nous allons développer un script complet qui va nous permettre :

  • De nous connecter à notre compte WordPress (utilisation de cookies)
  • De récupérer la liste des articles publiés ainsi que les liens de ces articles

Pour information, il est préférable d'utiliser le protocole XML-RPC pour effectuer cette tâche, mais le but ici est de prendre un exemple qui illustre le mieux possible l'utilisation de CURL et ses possibilités.

Tout d'abord, on va définir différentes variables comme le login et le mot de passe WordPress :

$usernameWP     = 'username_wordpress';
$passwordWP     = 'mot_de_passe_wordpress';
$urlWP          = 'http://www.votreblog.com';
$urlAdmin       = $urlWP . '/wp-admin/';
$urlConnexion   = $urlWP . '/wp-login.php';
$urlGetArticle  = $urlAdmin . '/edit.php';
 
$cookie = 'C:\Temp\cookie.txt';

Ensuite, on crée les données nécessaires à l'identification sur WordPress :

$postfield = array(
   'log'                   => $usernameWP,
   'pwd'                   => $passwordWP,
   'rememberme'            => 1,
   'wp-submit'             => 'submit',
   'wordpress_test_cookie' => 1,
   'redirect_to'           => $urlAdmin,
);

On soumet ensuite le formulaire avec les différentes options (et au passage, on sauvegarde la session) :

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $urlConnexion);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6");
// Durée d'éxécution maximale de la requête : 60 secondes
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
// Durée d'éxécution maximale de la connexion au serveur distant : 60 secondes
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
// On accepte de suivre les redirections
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
// On accepte de suivre une seule redirection (celle du "redirect_to", définie dans les données envoyées)
curl_setopt($ch, CURLOPT_MAXREDIRS, 1);
// On ne veut pas afficher le résultat de la requête à l'écran
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// On stocke le cookie de connexion dans le fichier $cookie
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
// On défini le REFERER HTTP
curl_setopt($ch, CURLOPT_REFERER, $urlConnexion);
// On spécifie les données à envoyé (ici, on construit la requête avec la fonction http_build_query)
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postfield));
// On effectue une requête de type POST
curl_setopt($ch, CURLOPT_POST, true);
// On éxécute la requête (on ne récupère pas le résultat dans une variable car on ne travaillera pas sur le contenu : on veut juste s'identifier)
curl_exec($ch);
// On ferme la session
curl_close($ch);

Ensuite, on s'occupe de récupérer les différents articles :

/** RECUPERATION DES ARTICLES **/
$ch = curl_init();
// Autre façon de définir les options
$options = array(
   CURLOPT_URL             => $urlGetArticle,
   CURLOPT_TIMEOUT         => 60,
   CURLOPT_CONNECTTIMEOUT  => 60,
   CURLOPT_RETURNTRANSFER  => true,
   // On charge les données du cookie sauvegardées précédemment
   CURLOPT_COOKIEFILE      => $cookie,
   CURLOPT_REFERER         => $urlAdmin,
);
curl_setopt_array($ch, $options);
 
// Cette fois ci, on récupère le résultat de la requête dans une variable car on veut récupérer les articles postés
$result = curl_exec($ch);
curl_close($ch);

Enfin, on récupère et on affiche les articles avec leur liens :

// Une expression régulière pour récupérer les articles et leur lien
preg_match_all('#<span class=\'view\'><a href="(.*)" title="(.*)" rel="permalink">Afficher<\/a>#Ui', $result, $matches);
// On affiche les lien
if (empty($matches[1]))
   die('Aucun article');
 
$urls = $matches[1];
$titles = $matches[2];
foreach ($urls as $index => $url)
{
   // On nettoie le titre
   $title = str_replace(array('&nbsp;', 'Afficher', '&laquo;', '&raquo;'), '', $titles[$index]);
 
   echo '<a href="' . $url . '" title="' . $title . '">';
   echo $title;
   echo '</a>';
   echo ' (' . $url . ')';
   echo '<br/>';
}

Conclusion

Nous avons vu les bases de CURL ainsi que des choses un peu plus poussées comme la soumission de formulaires par le biais de proxy en utilisant des cookies de session. Cependant, la maîtrise de CURL et de ses options nécessite un long temps d'apprentissage, tant ce qu'il ce nous propose est riche.

Pour plus d'informations sur CURL, n'hésitez pas à consulter les différents sites cités en référence.

Références

Tags: , ,

Laisser un commentaire


8 × = sixty four