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().

Citer #1 SpeedFrance54 02-04-2012 09:34
Bonjour,
Merci, pour ce tutorial, je ne connaissais pas, cURL, j'aimerais savoir s'il serait possible, avec cette fonction, de se loguer via un formulaire créé personnellement, au lieu d'avoir les $user, $password, dans le code php, et qui envoie la requête post à cette page : "https://www.moneybookers.com/app/login.pl" qui va donc activer sûrement un cookie et récupérer les infos de cette page : "https://www.moneybookers.com/app/my_account.pl" qui est après le log-in du formulaire créé.

J'aimerais juste récupérer la balise (div "available_balance" ces un )

J'aimerais donc savoir si cela est possible, (formulaire de connexion déjà créé :), récupération des infos de la page après le log-in sans afficher la page retournée, et afficher seulement le div, et peut être un bouton déconnexion, qui efface le cookie).
PS: je souhaite créer tout simplement, une petite webapp, pour mon smartphone, et connaitre mon solde disponible moneybookers.
Citer #2 PLKT 02-04-2012 18:18
Je crois que j'ai compris ta question. ;-) (je me suis permis de corriger l'orthographe.)

Pour se loguer:
cURL peut simuler les cookies. Cela se configure via les options : CURLOPT_COOKIEJAR et CURLOPT_COOKIEFILE.
Tu peux t'inspirer de cet article : http://k-wi.com/blog/php/lib-curl-21

Pour extraire du contenu:
Tu peux coder un 'scrapper' avec la fonction preg_match().

Cependant, dans ton cas, je ne suis pas certain que ton approche soit en accord avec les conditions d'utilisation de moneybookers. Tu devrais te renseigner et voir si il existe une API.
Citer #3 SpeedFrance54 02-04-2012 18:35
Merci, je vais donc chercher, de nouveau avec (CURLOPT_COOKIEJAR), que j'ai testé sans succès...

Malheureusement il n'y as pas d'API pour moneybookers, comparer au site de Paypal... En tout cas sur Iphone et Bada.

Je souhaite juste connaître le solde disponible, et non pas payer une personne, ajouter des fonds ect, je ne pense donc pas que cela posera problème, niveau conditions d'utilisations...

J'arrive déjà à me connecter, via un formulaire, plus petit pour un mobile, mais des que j'utilise curl, pour afficher juste le solde, la connections et refuser, car il met à jour, le captcha, et change donc de session. Si j'ai bien compris avec d'autres Tutorial trouvé.

PS : Je n'ai jamais était bon en orthographe, désoler pour les fautes...
Citer #4 PLKT 02-04-2012 19:31
En y regardant de plus près, au delà des conditions d'utilisation, il y a, quand même, un gros problème de sécurité :
Ton application pourrait intercepter les identifiants de ceux qui l'utilisent.

Il faut utiliser l'API :
http://www.programmableweb.com/api/moneybookers
Citer #5 Zorba 10-04-2012 18:55
oups le formulaire a tronqué mon message au premier tag, je me permets de reprendre ci-dessous :

Bonjour et merci pour ce tutoriel.

dans le cadre d'un tracking post achat, le tracking se fait normalement en page de confirmation d'achat, via un pixel de tracking de la forme img src égale URL_TRACKEUR?param1=¶m2=... mais comme ce n'est pas obligatoire d'aller jusqu'à la page de confirmation :

Je recherche la manière d'appeler cette URL depuis le script automatique déclenché par l'achat, sur mon serveur.

Je pressens que cURL peut être la solution mais mes tests ni le googling ne m'ont donné la solution. J'avais d'abord essayé fopen sans succès.

Auriez-vous la gentillesse de m'aiguiller ?
Citer #6 PLKT 14-04-2012 03:44
Certains outils de tracking excluent les robots de leurs statistiques. Pour contourner cela (grossièrement), vous pouvez essayer d'utiliser cURL en spécifiant en option un référer (CURLOPT_REFERER) et un user-agent (CURLOPT_USERAGENT).

Mais considérez ceci :
Les statistiques intéressantes sont celles qui permettent de mesurer des choses du genre "Les visiteurs en provenance de telle campagne génèrent plus de conversions que les visiteur en provenance de tel site...". Dans cette optique, même avec un perte importante, les statistiques fournissent des indicateurs pertinents.

Votre démarche peut apporter de la précision, mais attention, vous devez vous assurer que le tracking fait bien remonter toutes les données nécessaires pour que le hit (la commande) soit associé à une visite, car c'est ce qui donne leur vraie valeur aux statistiques.