Notes
Rejoindre la conversation

Pratique PHP - Requêtes HTTP GET et POST avec cURL

AddThis Social Bookmark Button

Bien connu des utilisateur UNIX, cURL permet d'effectuer des requêtes sur différents types de serveurs avec différents types de protocoles. cURL peut être utilisé en langage PHP via la bibliothèque libcurl. Les application possibles sont diverses: web services, proxy, crawler, web scraper etc... Dans cet article, nous verrons comment, en PHP, grâce à cURL, effectuer des requêtes HTTP de type GET et POST, soit télécharger le contenu d'une page web (et envoyer des variables au serveur). Nous coderons une classe qui aura pour objectif de simplifier l'utilisation de cURL pour ce type de requêtes. Nous verrons les options de configuration les plus utiles. Pensez aussi à consulter le manuel de cURL.

Dans cet article, ne seront abordés, ni les aspects concernant la nature du contenu téléchargé, ni les éventuels traitements, ni l'affichage du contenu téléchargé. Indirectement, cela sera le sujet de prochains articles. Il s'agit d'apporter une base (une classe php) pour l'invocation de cURL dans de prochains articles sans toutefois négliger le côté pratique : cURL Get Started 4 Script Kitteh'.

Requête HTTP de type GET en PHP avec cURL

Voici un code minimaliste permettant de télécharger le contenu d'une page web avec cURL via une requête HTTP GET :

 
<?php
 
////////// PARAMS
 
// Complétez $url avec l'url cible (l'url de la page que vous voulez télécharger)
$url=""; 
 
// Tableau contenant les options de téléchargement
$options=array(
      CURLOPT_URL            => $url, // Url cible (l'url la page que vous voulez télécharger)
      CURLOPT_RETURNTRANSFER => true, // Retourner le contenu téléchargé dans une chaine (au lieu de l'afficher directement)
      CURLOPT_HEADER         => false // Ne pas inclure l'entête de réponse du serveur dans la chaine retournée
);
 
////////// MAIN
 
// Création d'un nouvelle ressource cURL
$CURL=curl_init();
 
      // Configuration des options de téléchargement
      curl_setopt_array($CURL,$options);
 
      // Exécution de la requête
      $content=curl_exec($CURL);      // Le contenu téléchargé est enregistré dans la variable $content. Libre à vous de l'afficher.
 
// Fermeture de la session cURL
curl_close($CURL);
 
?>
 
Notez bien que :

Vous devez préciser l'url de la page que vous voulez télécharger dans la variable $url.

Si vous lancez le script "tel quel", il ne se passera rien de visible. L'obectif de ce script est de récupérer le contenu d'une page web dans une variable ($content). Libre à vous, ensuite, de l'afficher.

A propos du code :

Par défaut, cURL effectue une requête HTTP de type GET. Aussi, pour pouvoir utiliser cURL, seule l'option CURLOPT_URL qui contient l'url cible est réellement obligatoire. Les autres options sont configurées par défaut. Cependant, il convient en pratique de modifier le comportement par défaut de cURL. Ici les options CURLOPT_RETURNTRANSFER et CURLOPT_HEADER ont été configurées. Elle permettent de retourner le contenu téléchargé dans une variable (au lieu de l'afficher directement) et de ne pas retourner l'entête de réponse du serveur dans celle-ci.

Gestion des erreurs

Dans le code précédent, nous n'avons pas pris en compte les éventuelles erreurs possibles. Voyons comment améliorer le code précédent :

 
<?php
 
////////// PARAMS
 
// Complétez $url avec l'url cible (l'url de la page que vous voulez télécharger)
$url=""; 
 
// Tableau contenant les options de téléchargement
$options=array(
      CURLOPT_URL            => $url,  // Url cible (l'url la page que vous voulez télécharger)
      CURLOPT_RETURNTRANSFER => true,  // Retourner le contenu téléchargé dans une chaine (au lieu de l'afficher directement)
      CURLOPT_HEADER         => false, // Ne pas inclure l'entête de réponse du serveur dans la chaine retournée
      CURLOPT_FAILONERROR    => true   // Gestion des codes d'erreur HTTP supérieurs ou égaux à 400
);
 
////////// MAIN
 
// Création d'un nouvelle ressource cURL
$CURL=curl_init();
// Erreur suffisante pour justifier un die()
if(empty($CURL)){die("ERREUR curl_init : Il semble que cURL ne soit pas disponible.")}
 
      // Configuration des options de téléchargement
      curl_setopt_array($CURL,$options);
 
      // Exécution de la requête
      $content=curl_exec($CURL);       // Le contenu téléchargé est enregistré dans la variable $content. Libre à vous de l'afficher.
 
      // Si il s'est produit une erreur lors du téléchargement
      if(curl_errno($CURL)){
            // Le message d'erreur correspondant est affiché
            echo "ERREUR curl_exec : ".curl_error($CURL);
      }
 
// Fermeture de la session cURL
curl_close($CURL);
 
?>
 
A propos du code :

Vérifier que curl_init() a bien créé une ressource cURL est la moindre des choses. Un échec à ce niveau signifiera, dans la plupart des cas, que cURL n'est pas disponible sur votre serveur.

Par défaut cURL ne considère pas les codes d'erreur HTTP supérieurs ou égaux à 400 comme des erreurs. En effet, pour ce type d'erreur, le serveur retourne bien une page (par exemple une page d'erreur 404). L'option CURLOPT_FAILONERROR permet de changer ce comportement de manière à ce que cURL prenne en compte ces erreurs.

cURL fournit deux fonctions permettant de faire remonter les erreurs de téléchargement. Si il s'est produit une erreur, curl_errno() retournera le numéro d'erreur et curl_error() le message correspondant. Ici nous avons donc utilisé ces fonctions de manière à afficher les éventuels messages d'erreur.

Requête HTTP de type POST en PHP avec cURL

Par défaut cURL effectue une requête HTTP de type GET (les éventuelles variables envoyées au serveur sont donc passées par url). Voyons maintenant comment modifier le code précédent pour effectuer une requête de type POST, par exemple, pour simuler l'envoi d'un formulaire :

 
<?php
 
////////// PARAMS
 
// Complétez $url avec l'url cible (l'url de la page que vous voulez télécharger)
$url=""; 
 
// Complétez le tableau associatif $postFields avec les variables qui seront envoyées par POST au serveur
$postFields=array();
 
// Tableau contenant les options de téléchargement
$options=array(
      CURLOPT_URL            => $url,       // Url cible (l'url de la page que vous voulez télécharger)
      CURLOPT_RETURNTRANSFER => true,       // Retourner le contenu téléchargé dans une chaine (au lieu de l'afficher directement)
      CURLOPT_HEADER         => false,      // Ne pas inclure l'entête de réponse du serveur dans la chaine retournée
      CURLOPT_FAILONERROR    => true,       // Gestion des codes d'erreur HTTP supérieurs ou égaux à 400
      CURLOPT_POST           => true,       // Effectuer une requête de type POST
      CURLOPT_POSTFIELDS     => $postFields // Le tableau associatif contenant les variables envoyées par POST au serveur
);
 
////////// MAIN
 
// Création d'un nouvelle ressource cURL
$CURL=curl_init();
// Erreur suffisante pour justifier un die()
if(empty($CURL)){die("ERREUR curl_init : Il semble que cURL ne soit pas disponible.")}
 
      // Configuration des options de téléchargement
      curl_setopt_array($CURL,$options);
 
      // Exécution de la requête
      $content=curl_exec($CURL);            // Le contenu téléchargé est enregistré dans la variable $content. Libre à vous de l'afficher.
 
      // Si il s'est produit une erreur lors du téléchargement
      if(curl_errno($CURL)){
            // Le message d'erreur correspondant est affiché
            echo "ERREUR curl_exec : ".curl_error($CURL);
      }
 
// Fermeture de la session cURL
curl_close($CURL);
 
?>
 
Notez bien que :

Vous devez compléter le tableau associatif $postFields avec les variables qui seront envoyées par POST au serveur. Par exemple, si vous vouliez envoyer au serveur (comme si il s'agissait des champs d'un formulaire) des variables "user" et "pass" avec leurs valeurs, il vous faudrait créer un tableau de ce type :

 
$postFields=array(
      "user" => "identifiant",
      "pass" => "mot de passe"
);
 
A propos du code :

Deux options ont été ajoutées par rapport au code de la requête HTTP de type GET. CURLOPT_POST permet d'indiquer à cURL d'effectuer une requête de type POST. CURLOPT_POSTFIELDS contient les variables POST sous forme d'un tableau associatif ($postFields).

Remarque :

Pour configurer cURL pour une requête HTTP de type GET, on utilise l'option CURLOPT_HTTPGET avec la valeur true. Cette configuration est rarement utilisée puisque par défaut cURL effectue une requête de type GET.

Utilisation de cURL via la classe PHP Kurl

Afin de pouvoir utiliser cURL pour des requêtes HTTP de type GET et POST de manière plus conviviale, je vous propose d'utiliser la classe Kurl.

Utilisation de la classe PHP Kurl pour une requête de type GET

Voici comment utiliser la classe Kurl pour une requête de type GET (le code de la classe Kurl sera donné plus loin):

 
<?php
 
////////// PARAMS
 
// Complétez $url avec l'url cible (l'url de la page que vous voulez télécharger)
$url=""; 
 
// Tableau contenant les options de téléchargement
$options=array(
      CURLOPT_RETURNTRANSFER => true,  // Retourner le contenu téléchargé dans une chaine (au lieu de l'afficher directement)
      CURLOPT_HEADER         => false, // Ne pas inclure l'entête de réponse du serveur dans la chaine retournée
      CURLOPT_FAILONERROR    => true   // Gestion des codes d'erreur HTTP supérieurs ou égaux à 400
);
 
////////// MAIN
 
// Création (via la classe Kurl) d'un nouvelle ressource cURL et configuration des options de téléchargement
$oKurl=new Kurl($options);    
 
      // Exécution d'une requête GET. Le contenu téléchargé est enregistré dans la variable $OUT passée en paramètre. Libre à vous de l'afficher.
      $OUT="";
      $ERR=$oKurl->Load($OUT,$url); 
 
// Fermeture de la session cURL
$oKurl=null;
 
?>
 
Notez bien que :

Par rapport aux codes précédents, le tableau contenant les options de téléchargement ne contient plus l'option CURLOPT_URL. L'url cible (l'url de la page que vous voulez télécharger) est précisé en paramètre ($url) de la méthode Load().

La méthode Load() enregistre le contenu téléchargé dans la variable $OUT qui lui est passé en paramètre. Si il se produit une erreur lors du téléchargement la méthode Load() retourne le message d'erreur correspondant. (Sinon la valeur 'null' est retournée). Cela laisse une certaine liberté dans la façon de gérer les erreurs.

Utilisation de la classe PHP Kurl pour une requête de type POST

Voici comment utiliser la classe Kurl pour une requête de type POST (le code de la classe Kurl sera donné plus loin):

 
<?php
 
////////// PARAMS
 
// Complétez $url avec l'url cible (l'url de la page que vous voulez télécharger)
$url=""; 
 
// Complétez le tableau associatif $postFields avec les variables qui seront envoyées par POST au serveur
$postFields=array();
 
// Tableau contenant les options de téléchargement
$options=array(
      CURLOPT_RETURNTRANSFER => true,  // Retourner le contenu téléchargé dans une chaine (au lieu de l'afficher directement)
      CURLOPT_HEADER         => false, // Ne pas inclure l'entête de réponse du serveur dans la chaine retournée
      CURLOPT_FAILONERROR    => true   // Gestion des codes d'erreur HTTP supérieurs ou égaux à 400
);
 
////////// MAIN
 
// Création (via la classe Kurl) d'un nouvelle ressource cURL et configuration des options de téléchargement
$oKurl=new Kurl($options);    
 
      // Exécution d'une requête POST. Le contenu téléchargé est enregistré dans la variable $OUT passée en paramètre. Libre à vous de l'afficher.
      $OUT="";
      $ERR=$oKurl->Load($OUT,$url,$postFields); 
 
// Fermeture de la session cURL
$oKurl=null;
 
?>
 
Notez bien que :

Par rapport aux codes précédents, le tableau contenant les options ($options) de téléchargement ne contient plus les options liées à l'utilisation de la méthode POST, soient les options CURLOPT_POST et CURLOPT_POSTFIELDS. En effet, la méthode Load() déduit la méthode (GET ou POST) à utiliser selon que vous ayez passé ou non le tableau $postFields en paramètre.

La classe PHP Kurl

Voici le code de la classe Kurl :

 
<?php
 
class Kurl{
 
      //////// CONSTRUCT / DESTRUCT
 
      function __construct($options){
            $this->curlRef=@curl_init();                                                // Création d'un nouvelle ressource cURL
            if(!empty($this->curlRef)){curl_setopt_array($this->curlRef,$options);}     // Configuration des options de téléchargement
            else{die("ERREUR curl_init : Il semble que cURL ne soit pas disponible.");} // Erreur suffisante pour justifier un die()
      }
 
      function __destruct(){curl_close($this->curlRef);}                                // Fermeture de la session cURL
 
      //////// METHODS
 
      public function Load(&$OUT,$url,$postFields=null){
      $ERR=null;
                  // Si le paramètre $postField est laissé vide on effectue une requête de type GET
                  if(empty($postFields)){
                        curl_setopt($this->curlRef,CURLOPT_HTTPGET,true);               // Configuration de l'option CURLOPT_HTTPGET
                  }
                  // Sinon on effectue une requête de type POST ($postField contient alors les variables envoyées par POST au serveur)
                  else{
                        curl_setopt($this->curlRef,CURLOPT_POST,true);                  // Configuration de l'option CURLOPT_POST
                        curl_setopt($this->curlRef,CURLOPT_POSTFIELDS,$postFields);     // Configuration de l'option CURLOPT_POSTFIELDS
                  }
            curl_setopt($this->curlRef,CURLOPT_URL,$url);                               // Configuration de l'option CURLOPT_URL
            $OUT=@curl_exec($this->curlRef);                                            // Exécution de la requête
            // Si il s'est produit une erreur lors du téléchargement, le message d'erreur correspondant est retourné
            if(curl_errno($this->curlRef)){$ERR="ERREUR curl_exec : ".curl_error($this->curlRef);}
      return $ERR;
      }
}
 
?>
 
A propos du code :

La fonction curl_setopt_array() prend en paramètre un tableau associatif contenant les différentes options cURL associées à leurs valeurs. curl_setopt_array() permet de configurer plusieurs options en une seule fois. Ici, la fonction curl_setopt() est également utilisée. curl_setopt() permet de configurer individuellement une option. Elle prend en paramètre l'option à configurer et la valeur de l'option. De cette manière, on peut reconfigurer une option sans être obligé de reconfigurer toutes les autres.

Les options de transfert cURL

La bonne utilisation de cURL passe par la configuration des options de téléchargement (appelées aussi options de transfert). Le manuel PHP de cURL propose une liste des options de cURL en PHP. Voici une configuration (qui peut être utilisée directement avec la classe Kurl) qui détaille quelques unes des options cURL qui pourraient vous être utiles :

 
// Tableau contenant les options de téléchargement
$options=array(
      CURLOPT_RETURNTRANSFER => true,  // Retourner le contenu téléchargé dans une chaine (au lieu de l'afficher directement)
      CURLOPT_HEADER         => false, // Ne pas inclure l'entête de réponse du serveur dans la chaine retournée
      CURLOPT_FAILONERROR    => true,  // Gestion des codes d'erreur HTTP supérieurs ou égaux à 400
 
      CURLOPT_CONNECTTIMEOUT => 2,     // Nombre de secondes à attendre avant d'abandonner une tentative de connexion
      CURLOPT_TIMEOUT        => 2,     // Nombre de secondes à attendre une réponse avant d'abandonner une connexion établie
      CURLOPT_FOLLOWLOCATION => true,  // Suivre les redirections
      CURLOPT_MAXREDIRS      => 5,     // Nombre maximum de redirections acceptées (pour ne pas se faire balader)
      CURLOPT_AUTOREFERER    => true,  // Compléter le 'referer' automatiquement  après une redirection
      CURLOPT_ENCODING       => "",    // Paramètre l'entête HTTP "Accept-Encoding:" avec tous les encodages supportés
      CURLOPT_VERBOSE        => false  // Ne pas 'faire chier pour rien' 
);
 

Dans certain cas, il peut être utile de configurer directement les entêtes HTTP envoyées au serveur. Cela peut être fait grâce à l'option CURLOPT_HTTPHEADER. CURLOPT_HTTPHEADER prend en paramètre un tableau où chaque cellule correspond à une ligne de l'entête. L'option CURLOPT_HTTPHEADER pourrait être ajoutée au tableau des options ($option) de cette manière:

 
// Ajout de l'option CURLOPT_HTTPHEADER au tableau contenant les options de téléchargement
$options[CURLOPT_HTTPHEADER]=array(
"Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3",
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7",
);
 

Conclusion

Nous avons vu comment, en PHP, effectuer des requêtes HTTP de type GET et POST grâce à cURL. Cela permet, entre autres, de récupérer du contenu web. Aussi, afin de traiter le sujet de manière générale, nous n'avons pas abordé les aspects concernant la nature du contenu, les éventuels traitement sur celui-ci, ni son affichage. Comme il a été précisé en introduction, cela sera le sujet de prochains articles où l'invocation de cURL se fera par le biais de la classe Kurl de manière à ne pas interférer avec le 'scope' de ces articles.

Un obstacle que vous risquez probablement de rencontrer au niveau du contenu téléchargé par cURL sera celui de l'encodage de caractères, soit des caractères spéciaux (accents etc...) qui ne s'affichent pas correctement, ou pire, qui ne correspondent pas avec vos expressions rationelles. Il vous faudra alors convertir cet encodage. Je vous propose de voir comment faire : A VENIR

Pour ce qui est de l'affichage de contenu HTML, considérez cette fonction PHP htmlspecialchars().