Introduction à CURL PHP à quoi ça sert et comment ça marche

cURL (client URL request library) est une librairie créée par Daniel Stenberg la première version date d'avril 1997.
Elle permet de communiquer avec de nombreux types de serveurs et en utilisant les protocoles standards (HTTP,HTTPS,FTP,Telnet,LDAP,etc.). Il est possible d'utiliser des proxys lors de la communication.

Cette librairie est vitale pour s'interfacer avec des API's (Application Programming Interface) qu'elles soient REST, SOAP ou autre.

Explications rapides sur HTTP et HTTPS :

Cette librairie gère les protocoles HTTP et HTTPS et bien que les deux protocoles de communication visent le même objectif, la couche de sécurité n'est clairement pas la même.
Le protocole HTTP transfert des données de manières non sécurisé, alors que le HTTPS permet de transmettre des données dans un canal de communication crypté entre les deux points, en SSL (Secure Socket Layer). Il est donc préférable dans le cadre d'applicatif de sécurité d'utiliser le HTTPS au détriment du HTTP.

php curl get

Les méthodes  (HEAD,GET,POST,PUT) supportées par l'extension CURL en PHP et explications de base sur les différentes méthodes :


cURL supporte les méthodes de requêtes en HEAD,GET et POST ainsi qu'en PUT.

HEAD : sers à récupérer l'en-tête d'une page internet sans le corps de la page. Ce genre de requête offre l'avantage d'être très légère lors de son exécution aussi bien en ressource qu'en bande passante, elle est parfaite pour contrôler si un site internet répond.

GET : la méthode GET demande au serveur distant la page (ou le fichier) dans les standards ce type de méthode sert uniquement à récupérer des données.

POST : la méthode POST sert à envoyer au serveur distant les données (ressources) indiquées.

Prérequis et installation de cURL en PHP
Pour utiliser cUrl avec son serveur Apache il est nécessaire de contrôler que la dll est bien présente dans l'installation de PHP.

Installation sous Windows :

Dans le dossier de votre instance XAMPP ou WAMPP : .\php\ext
Rechercher le fichier : php_curl.dll
Puis dans le php.ini contrôler que l'extension est n'est pas commentée extension=curl.

Installation sous Linux :

Pour l'installation : apt-get install php-curl
Pour la mise à jour : apt-get update php-curl
Puis dans le php.ini : extension=curl.so

Il est également possible de contrôler directement depuis un script PHP si l'extension cURL est chargée.

Pour réaliser cette tâche en PHP on utilise la fonction extension_loaded en lui passant en paramètre curl. Cette fonction retourne un boolean en cas d'échec ou de réussite. Nous pouvons aussi connaître le numéro de version grâce à la fonction curl_version qui retourne le numéro de version de l'extension active sur le serveur.

php curl post

Initialisation et explications sur l'objet curl en PHP :

L'initialisation de l'objet curl se fait en utilisant la fonction curl_init() cette fonction retourne un objet.

$ch = curl_init();

Une fois l'objet initialiser on lui assigne des options en fonctions de nos besoins grâce à la fonction curl_setopt().

curl_setopt accèpte 3 paramètres :

  1. l'objet curl créer avec la méthode curl_init().
  2. une des constantes prefixés CURLOPT_.
  3. un paramètre complémentaire propre à l'option spécifé.
Listes des différentes options supportées par Curl:
  • CURLOPT_URL : l'url cible que la requête devra appeler (une chaine de caractères typée URL).
    • curl_setopt($ch, CURLOPT_URL, "https://www.analyse-innovation-solution-fr/404");
  • CURLOPT_POST : si la requête doit utiliser le protocole POST pour sa résolution (boolean).
    • curl_setopt($ch, CURLOPT_POST, true);
  • CURLOPT_POSTFIELDS : le tableau de paramètres à assigner à une requête POST (tableau associatif).
    • $datas = array("user"=>"johndoe","user_id"=>1);
      curl_setopt($ch, CURLOPT_POSTFIELDS, $datas);
  • CURLOPT_CUSTOMREQUEST : pour forcer le format de la commande HTTP (chaine de caractères, PUT,GET,POST,CONNECT,HEAD,etc.).
    • curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); 
  • CURLOPT_HTTPHEADER : un tableau non associatif permettant de modifier des paramètres du header envoyé par la requête (tableau).
    • curl_setopt($ch, CURLOPT_HTTPHEADER, array(
      	"Cache-Control: no-cache",
      	"content-type:application/json;charset=utf-8"
      ));
  • CURLOPT_HEADER :  si nous souhaitons ou non récupérer les informations de l'entête (boolean).
    •  curl_setopt($ch, CURLOPT_HEADER, false);
  • CURLOPT_RETURNTRANSFER : si nous voulons ou non récupérer le contenu de la requête appelée (boolean).
    • curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  • CURLOPT_CONNECTTIMEOUT  : le délais maximum exprimé en secondes avant l'abandon de la connexion au serveur lors de l'établissement de la connexion (entier).
    • curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20); 
  • CURLOPT_TIMEOUT : le délais maximum exprimé en secondes avant l'abandon de la résolution de la requête curl lors de son éxécution (entier).
    • curl_setopt($ch, CURLOPT_TIMEOUT, 30);
  • CURLOPT_FOLLOWLOCATION : si la résolution de la requête doit ou non suivre les redirections (boolean).
    • curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
  • CURLOPT_MAXREDIRS : le nombre de redirection que doit autoriser la résolution de la requête avant de déclancher son abandon (entier).
    • curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
  • CURLOPT_USERAGENT : le nom de l'agent utilisateur/l'application cliente utilisée (chaine de caractères).
    • curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');
  • CURLOPT_SSL_VERIFYPEER : si la requête doit vérifier ou non la validité du certificat SSL (boolean).
    • curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
  • CURLOPT_NOBODY : si la requête doit utiliser le protocole HEAD et ne pas télécharger les ressources retournées par son action.
    • curl_setopt($ch, CURLOPT_NOBODY, true);
  • CURLOPT_PROXYTYPE : le type de prox à utiliser.
    • curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
  • CURLOPT_PROXY : assigner l'adresse IP d'un serveur proxy où doit transiter la requête CURL (chaine de caractères, au format ip:port).
    • curl_setopt($ch, CURLOPT_PROXY, "127.0.0.1:9050");

Cette liste ne se veut pas exhaustive mais couvre la grande majorité des cas rencontrés.

Exécution et récupération de la ressource appelée :

Pour récupérer la ressource appelée et téléchargée par la requête CURL on utilise la méthode curl_exec().

$response = curl_exec($ch);
Contrôler la présence d'erreur fatale dans l'éxécution de la requête :

Pour contrôler la présence d'une erreur fatale dans l'éxécution d'une requête CURL on utilise la méthode curl_errno() elle accepte un paramètre l'objet curl. Pour connaître le message d'erreur on utilise la fonction curl_error() qui accèpte elle aussi un seul paramètre l'objet curl.

if (curl_errno($ch)) {
	echo curl_error($ch);
}
Listes des informations les plus utiles retournées :

Pour récupérer les informations d'une requête CURL on utilise la méthode curl_getinfo() qui prend deux paramètres, l'objet curl,et l'un des paramètres suivant :

$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  • CURLINFO_HTTP_CODE : le code de retour HTTP (200,301,307,404,etc).
  • CURLINFO_REDIRECT_TIME : La durée exprimée en seconde de l'ensemble des étapes de redirection avant l'accès à la ressource finale soit commencée.
  • CURLINFO_TOTAL_TIME_T: le temps total  d'éxécution de la transaction en microseconde.
Exemples concrets d'utilisation de CURL en PHP avec les différentes méthodes et les principaux protocoles (HEAD,POST,GET) :
Exemple d'utilisation de CURL en PHP avec le protocole HTTP sans vérification du certificat SSL et la méthode HEAD :

Dans le cadre d'un appel en HEAD pour vérifier si un site internet répond et que la page est bien disponible même après plusieurs redirections.

 Ici nous ciblons https://analyse-innovation-solution.fr/page/comment-envoyer-un-mail-en-php qui est l'ancienne page pour l'article https://analyse-innovation-solution.fr/publication/fr/php/comment-envoyer-un-mail-en-php le système effectue une redirection HTTP 301, mais la page finale retourne bien un code HTTP 202.

	$ch = curl_init();
	try {
		curl_setopt($ch, CURLOPT_URL, "https://analyse-innovation-solution.fr/page/comment-envoyer-un-mail-en-php");
		curl_setopt($ch, CURLOPT_HEADER, false);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);   
		curl_setopt($ch, CURLOPT_TIMEOUT, 5);         
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
		curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
		curl_setopt($ch, CURLOPT_NOBODY, true);
		
		$response = curl_exec($ch);
		
	    if (curl_errno($ch)) {
			echo curl_error($ch);
			die();
		}
		
		$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		if($http_code == intval(200)){
			echo "Ressource valide";
		}
		else{
			echo "Ressource introuvable : " . $http_code;
		}
	} catch (\Throwable $th) {
		throw $th;
	} finally {
		curl_close($ch);
	}
Exemple d'utilisation de CURL en PHP sans paramètres en GET et HTTPS :

Pour récupérer le contenu d'une page avec le protocole HTTPS en GET il suffit de modifier les paramètres : CURLOPT_RETURNTRANSFER et CURLOPT_SSL_VERIFYPEER. La variable $response contient le contenu de retour de la ressource (ici du HTML).

	$ch = curl_init();
	try {
		curl_setopt($ch, CURLOPT_URL, "https://analyse-innovation-solution.fr/page/comment-envoyer-un-mail-en-php");
		curl_setopt($ch, CURLOPT_HEADER, false);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);   
		curl_setopt($ch, CURLOPT_TIMEOUT, 5);         
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
		curl_setopt($ch, CURLOPT_MAXREDIRS, 1);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
		
		$response = curl_exec($ch);
		
	    if (curl_errno($ch)) {
			echo curl_error($ch);
			die();
		}
		
		$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		if($http_code == intval(200)){
			echo $response;
		}
		else{
			echo "Ressource introuvable : " . $http_code;
		}
	} catch (\Throwable $th) {
		throw $th;
	} finally {
		curl_close($ch);
	}
	
Exemple d'utilisation de CURL en PHP avec paramètres en POST et HTTPS :

 Pour envoyer une requête HTTPS vers l'url de sont choix en utilisant la méthode POST et en lui assignant le paramètre "nameparam"  avec la valeur "valeurparam" rien de plus simple :

	
	$ch = curl_init();
	try {
		curl_setopt($ch, CURLOPT_URL, "https://votreurl.fr");
		curl_setopt($ch, CURLOPT_POST, true);
		curl_setopt($ch, CURLOPT_POSTFIELDS, array("nameparam"=>"valeurparam"));
		curl_setopt($ch, CURLOPT_HEADER, false);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);   
		curl_setopt($ch, CURLOPT_TIMEOUT, 5);         
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
		curl_setopt($ch, CURLOPT_MAXREDIRS, 1);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
		
		$response = curl_exec($ch);
		
	    if (curl_errno($ch)) {
			echo curl_error($ch);
			die();
		}
		
		$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		if($http_code == intval(200)){
			echo $response;
		}
		else{
			echo "Ressource introuvable : " . $http_code;
		}
	} catch (\Throwable $th) {
		throw $th;
	} finally {
		curl_close($ch);
	}
	
Exemple d'utilisation de CURL en PHP via la méthode GET et HTTPS via un serveur PROXY :

Pour faire transiter une requête HTTPS au travers d'un serveur proxy, il suffit de rajouter 3 paramètres, CURLOPT_PROXY,CURLOPT_PROXYTYPE,CURLOPT_VERBOSE.

$ch = curl_init();
	try {
		
		$proxy = "127.0.0.1:9150";
		$timeout = '3000';
		
		curl_setopt($curl, CURLOPT_PROXY, $proxy);
		curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
		curl_setopt($ch, CURLOPT_VERBOSE, 0);
		
		curl_setopt($ch, CURLOPT_URL, 'http://www.monip.org');
		curl_setopt($ch, CURLOPT_HEADER, false);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);   
		curl_setopt($ch, CURLOPT_TIMEOUT, 5);         
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
		curl_setopt($ch, CURLOPT_MAXREDIRS, 1);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
		
		$response = curl_exec($ch);
		
	    if (curl_errno($ch)) {
			echo curl_error($ch);
			die();
		}
		
		$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		if($http_code == intval(200)){
			echo $response;
		}
		else{
			echo "Ressource introuvable : " . $http_code;
		}
	} catch (\Throwable $th) {
		throw $th;
	} finally {
		curl_close($ch);
	}
	

En conclusion :

CURL en PHP est donc un outil adapté pour faire des crawler's, des outils de monitoring, interroger des API, et bien plus ! Bon code.