29
PHP : l'extension cURL par julp (Autres articles) Date de publication : 12/06/2007 Dernière mise à jour : La librairie cURL permet de communiquer facilement avec de nombreux types de serveurs applicatifs en parlant le même langage que celui-ci. Ce langage est définit par ce qu'on appelle un protocole dont les plus connus sont sans aucun doute HTTP et FTP. L'extension cURL permet d'interagir en PHP avec tous ces protocoles que nous employons de manière quotidienne sans avoir à gérer la connexion ou encore sans se soucier de la manière dont il faut écrire la requête ou en recevoir la réponse.

Plugin Php Curl

Embed Size (px)

Citation preview

Page 1: Plugin Php Curl

PHP : l'extension cURL

par julp (Autres articles)

Date de publication : 12/06/2007

Dernière mise à jour :

La librairie cURL permet de communiquer facilement avec de nombreux types de serveursapplicatifs en parlant le même langage que celui-ci. Ce langage est définit par ce qu'onappelle un protocole dont les plus connus sont sans aucun doute HTTP et FTP. L'extensioncURL permet d'interagir en PHP avec tous ces protocoles que nous employons de manièrequotidienne sans avoir à gérer la connexion ou encore sans se soucier de la manière dontil faut écrire la requête ou en recevoir la réponse.

Page 2: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 2 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

1 - Installation.............................................................................................................................................................. 31.1 - Windows.........................................................................................................................................................31.2 - Unix/Linux...................................................................................................................................................... 3

1.2.1 - Statique..................................................................................................................................................31.2.2 - Dynamique.............................................................................................................................................3

2 - Vue d'ensemble......................................................................................................................................................52.1 - Les fonctions..................................................................................................................................................52.2 - Les options.................................................................................................................................................... 8

3 - Utilisation.............................................................................................................................................................. 113.1 - Le protocole HTTP...................................................................................................................................... 11

3.1.1 - Vérifier l'existence d'une URL............................................................................................................. 113.1.2 - Récupérer le contenu d'une page.......................................................................................................113.1.3 - Envoyer des données par la méthode POST.....................................................................................123.1.4 - Débuter une session puis la réutiliser.................................................................................................143.1.5 - Source : simplifier l'utilisation de cURL pour le protocole HTTP.........................................................15

3.2 - Le protocole FTP.........................................................................................................................................183.2.1 - Lister un répertoire distant.................................................................................................................. 183.2.2 - Envoyer un fichier............................................................................................................................... 193.2.3 - Télécharger un fichier......................................................................................................................... 20

3.3 - Le protocole LDAP...................................................................................................................................... 214 - Alternatives : mise en parallèle avec d'autres méthodes.................................................................................... 23

4.1 - Vérifier l'existence d'une page.....................................................................................................................234.2 - Récupérer le corps d'une page...................................................................................................................244.3 - Recevoir un fichier par FTP........................................................................................................................ 264.4 - Envoyer un fichier par FTP......................................................................................................................... 27

5 - Conclusion............................................................................................................................................................295.1 - Epilogue....................................................................................................................................................... 29

Page 3: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 3 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

1 - Installation

1.1 - Windows

Récupérez la version binaire zippée de PHP pour Windows. Placez ensuite php_curl.dll avec les autres(généralement il s'agit du répertoire extensions pour PHP 4 et ext pour PHP 5). Indiquez à PHP de charger l'extensionen éditant le fichier php.ini pour y ajouter la ligne suivante :

extension=php_curl.dll

Vous aurez également besoin de copier les librairies libeay32.dll ainsi que ssleay32.dll dans un des répertoirespointés par votre variable d'environnement PATH. Modifiez la au besoin ou alors utilisez directement C:\WINDOWS\system32\.

Enfin, un redémarrage de votre serveur sera probablement nécessaire pour prendre en charge immédiatement cettenouvelle extension.

1.2 - Unix/Linux

L'installation de PHP ou de l'extension à partir de ses sources s'adresse à des utilisateurs initiés pour répondre àdes besoins particuliers. Privilégiez autant que possible les paquets mis à disposition par le distributeur de votredistribution Linux ou de votre système Unix auquel cas il ne devrait vous rester qu'à activer cette extension en éditantle fichier php.ini (voir ci-dessous la partie intitulée "Dynamique"). Par exemple, dans le cas de Mandriva où vos médiassont convenablement renseignés, l'installation se fera par cette commande : urpmi phpVERSION-curl (remplacezVERSION par 4 ou 5 suivant la version de PHP utilisée).

1.2.1 - Statique

Les sources de cette extension étant distribuées avec celles de PHP nous devons simplement ajouter l'option --with-curl lors du script configure :

./configure --prefix=/usr/local/php ... --with-curlmakemake install

1.2.2 - Dynamique

Cette méthode présente l'avantage de ne pas requérir une recompilation complète de PHP et d'être indépendante(jusqu'à un certain point) du coeur de PHP. Voici comment procéder à la compilation :

cd /répertoire/des/sources/de/l/extensionphpize./configuremakemake install

Vous devez ensuite modifier le fichier php.ini afin de disposer des fonctions cURL en chargeant l'extension à l'aidede la ligne suivante :

Page 4: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 4 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

extension=curl.so

Assurez-vous que les chemins indiqués par la directive extension_dir sont corrects puisque PHP sera alors incapablede charger les extensions demandées auquel cas vous obtiendriez des messages d'erreur et aucune des fonctionsqu'elles sont censées fournir.

Page 5: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 5 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

2 - Vue d'ensemble

2.1 - Les fonctions

Dans la plupart des cas, le recours à cURL en PHP se résume à quelques appels de fonctions dont l'ordre vous estprésenté par le schéma ci-dessous :

Voyons maintenant le rôle que joue chacune de ces fonctions ainsi que leurs prototypes :

• ressource curl_init([chaîne url]) :

Initialise une nouvelle session cURL. Son seul paramètre url peut être omis mais il ne faudra pas oublier del'indiquer par la suite avec la fonction curl_setopt, option CURLOPT_URL. Cette fonction renverra une ressourceexploitable par les autres fonctions curl ou FALSE en cas d'erreur.

• booléen curl_setopt(ressource curl, entier option, variable valeur) :

Définit le comportement de la session. Elle renvoie TRUE en cas de succès et FALSE si une erreur estrencontrée. Ces paramètres sont les suivants :

• curl : la session cURL (résultat de l'appel à curl_init)• option : le nom de l'option sous la forme d'une constante, celles-ci commencent par CURLOPT_* et les

principales seront présentées plus bas• valeur : la valeur à donner, son type (numérique, booléen, etc) est variable et est propre à l'option

utilisée

• variable curl_exec(ressource curl) :

Exécute la session cURL représentée par curl (résultat de la fonction curl_init). Toutes les informationsnécessaires doivent être fournies au préalable avec la fonction curl_setopt. Elle retourne FALSE si une erreursurvient et dans le cas contraire une valeur qui dépend de la valeur de l'option CURLOPT_RETURNTRANSFER.En effet, si cette option est fixée à FALSE (valeur par défaut), curl_exec renvoie alors TRUE sinon le résultatde la requête (du texte).

• rien curl_close(ressource curl) :

Page 6: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 6 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

Met fin à la session cURL désignée par le paramètre curl (résultat de la fonction curl_init) et libère les ressourcesallouées.

Fonctions supplémentaires utiles :

• chaîne curl_error(ressource curl) :

Permet d'obtenir le texte décrivant la dernière erreur produite. S'il n'y en a pas eu, vous récupérerez alors unechaîne vide. Notez que cette fonction attend la session cURL courante issue de la fonction curl_init, elle doitdonc par conséquent être appelée avant curl_close.

• variable curl_getinfo(ressource curl [, entier option]) :

Fournit diverses informations concernant la dernière session indiquée par le paramètre curl. Si l'argument optionest fourni alors seule l'information correspondante sera retournée et s'il est omis vous les obtiendrez toutessous la forme d'un tableau associatif.

Le paramètre option peut prendre l'une des valeurs suivantes sous les traits d'une constante :

Page 7: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 7 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

Nom DescriptionCURLINFO_EFFECTIVE_URLDernière URL effective utilisée.CURLINFO_HTTP_CODECode HTTP de la dernière réponse reçue. La valeur sera

nulle si aucune réponse n'a (encore) été reçue.CURLINFO_FILETIMETimestamp indiquant la date du fichier distant. La valeur -1

sera renvoyée si cette information n'est pas disponible et cequelqu'en soit la raison.

CURLINFO_TOTAL_TIMEDurée totale exprimée en secondes du précédent transfert(ceci inclue toutes les étapes de la connexion comme larésolution d'adresse).

CURLINFO_NAMELOOKUP_TIMETemps (en secondes) mis depuis le début (de la fonctioncurl_exec) jusqu'à la résolution de nom.

CURLINFO_CONNECT_TIMETemps mis en secondes depuis le début à l'établissement dela connexion avec l'hôte distant ou le proxy.

CURLINFO_PRETRANSFER_TIMEDélai (en secondes) séparant le début au début du transfert.Cette étape inclue l'envoi des pré-commandes comme lepermet l'option CURLOPT_QUOTE, par exemple.

CURLINFO_STARTTRANSFER_TIMETemps, en secondes, écoulé entre le début et l'envoi dupremier octet du transfert.

CURLINFO_REDIRECT_TIMEDurée totale du transfert incluant les différentes redirections.La valeur sera nulle si la requête n'a fait l'objet d'aucuneredirection.

CURLINFO_REDIRECT_COUNTNombre de redirections suivies.CURLINFO_SIZE_UPLOADNombre d'octets envoyés.CURLINFO_SIZE_DOWNLOADNombre d'octets reçus pour le dernier transfert.CURLINFO_SPEED_DOWNLOADVitesse de téléchargement moyenne mesurée en octets/

seconde.CURLINFO_SPEED_UPLOADVitesse d'envoi moyenne exprimée en octets/seconde.CURLINFO_HEADER_SIZEEn octets, taille totale de tous les en-têtes reçus.CURLINFO_REQUEST_SIZETaille totale des requêtes effectuées (inclue les pages de

redirection si CURLOPT_FOLLOWLOCATION est à TRUE).Cette information ne concerne que le protocole HTTP.

CURLINFO_SSL_VERIFYRESULTRésultat de la vérification de la certification demandée vial'option CURLOPT_SSL_VERIFYPEER.

CURLINFO_CONTENT_LENGTH_DOWNLOADValeur lue et correspondant au champ Content-Length dansla réponse.

CURLINFO_CONTENT_LENGTH_UPLOADTaille spécifiée pour l'envoi (c'est à dire à la valeur de l'optionCURLOPT_INFILESIZE).

CURLINFO_CONTENT_TYPELa valeur de l'en-tête Content-Type telle qu'elle a été lue.Vous pouvez obtenir la valeur NULL si le protocole negère pas cette en-tête ou si le serveur en a envoyé une quis'avère être invalide.

En revanche si vous n'utilisez pas ce deuxième paramètre, voilà la forme que prendra le tableau ainsi renvoyépar la fonction curl_getinfo :

Array( // Voir ci-dessus la description de la constante : 'url' => 'http://www.developpez.com/', // CURLINFO_EFFECTIVE_URL 'content_type' => 'text/html', // CURLINFO_CONTENT_TYPE 'http_code' => 200, // CURLINFO_HTTP_CODE 'header_size' => 145, // CURLINFO_HEADER_SIZE 'request_size' => 58, // CURLINFO_REQUEST_SIZE

Page 8: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 8 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

'filetime' => -1, // CURLINFO_FILETIME 'ssl_verify_result' => 0, // CURLINFO_SSL_VERIFYRESULT 'redirect_count' => 0, // CURLINFO_REDIRECT_COUNT 'total_time' => 0.125, // CURLINFO_TOTAL_TIME 'namelookup_time' => 0, // CURLINFO_NAMELOOKUP_TIME 'connect_time' => 0.052, // CURLINFO_CONNECT_TIME 'pretransfer_time' => 0.052, // CURLINFO_PRETRANSFER_TIME 'size_upload' => 0, // CURLINFO_SIZE_UPLOAD 'size_download' => 0, // CURLINFO_SPEED_DOWNLOAD 'speed_download' => 0, // CURLINFO_SPEED_DOWNLOAD 'speed_upload' => 0, // CURLINFO_SPEED_UPLOAD 'download_content_length' => 0, // CURLINFO_CONTENT_LENGTH_DOWNLOAD 'upload_content_length' => 0, // CURLINFO_CONTENT_LENGTH_UPLOAD 'starttransfer_time' => 0.124, // CURLINFO_STARTTRANSFER_TIME 'redirect_time' => 0 // CURLINFO_REDIRECT_TIME)

2.2 - Les options

La liste des options que nous allons voir est loin d'être exhaustive : nous n'aborderons en effet que les principalesoptions de l'extension suivant leur rôle et en prenant en compte le ou les protocoles avec lesquels elles peuventêtre employées.

Passons en revue tout d'abord les paramètres généraux de la connexion qui sera établie par cURL :

Nom DescriptionCURLOPT_URL URL à utiliser pour établir la connexion (alternative au paramètre url

de la fonction curl_init). La forme de celle-ci dépend du protocoleemployé.

CURLOPT_TIMEOUT Temps maximal d'exécution, exprimé en secondes, de la fonctioncurl_exec.

CURLOPT_CONNECTTIMEOUTDurée maximale de la tentative d'établissement de la connexionvers l'hôte distant (en secondes). Une valeur nulle aura pour effetde laisser cette tâche au système.

Voyons en maintenant d'autres toutes aussi générales qui, elles, sont liées au transfert des données :

Nom DescriptionCURLOPT_NOBODY Fixée à TRUE la partie "contenu" ne sera pas renvoyée. Par

exemple avec le protocole HTTP, la requête employée sera de typeHEAD au lieu de GET par défaut. Sa valeur par défaut est FALSE,rapatriant ainsi les données distantes.

CURLOPT_HEADER Suivant le protocole employé, la valeur TRUE permettra d'inclureles en-têtes dans le résultat renvoyé. La valeur par défaut estFALSE.

CURLOPT_RETURNTRANSFERAvec la valeur TRUE, le contenu de la page distante est retournésous la forme d'une chaîne par la fonction curl_exec. La valeur pardéfaut FALSE a pour effet d'en afficher directement la sortie.

CURLOPT_FILE Un descripteur de fichier (préalablement obtenu et ouvert avecfopen en mode écriture) dans lequel sera alors écrit les donnéesrenvoyées par le serveur distant. La valeur par défaut est la sortiestandard soit le navigateur dans une utilisation "web" de PHP.

CURLOPT_UPLOAD Permet d'indiquer, en attribuant la valeur TRUE à cette option, àcURL qu'un envoi de fichier va avoir lieu et qu'il doit s'y préparer.

CURLOPT_INFILE Un descripteur de fichier, auparavant obtenu et ouvert en lecturepar la fonction fopen, duquel les données pour l'upload seront lues.

CURLOPT_INFILESIZETaille du fichier qui sera envoyé au serveur distant.

Page 9: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 9 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

Abordons à présent les particularités du protocole HTTP :

Nom DescriptionCURLOPT_HTTP_VERSIONForcer la version du protocole HTTP utilisée. La valeur par défaut

est CURL_HTTP_VERSION_NONE, laissant ainsi le soin à cURLde décider sinon forcez la à l'aide de CURL_HTTP_VERSION_1_0ou CURL_HTTP_VERSION_1_1 qui correspondent respectivementaux versions 1.0 et 1.1.

CURLOPT_FOLLOWLOCATIONTRUE pour suivre (toutes) les redirections de type "Location:".On peut toutefois limiter le nombre de celles-ci avec l'optionCURLOPT_MAXREDIRS.

CURLOPT_MAXREDIRSSpécifie le nombre maximum de redirections qui seront suiviesavant de faire échouer la requête. Une valeur nulle implique aucuneredirection alors que -1 (valeur par défaut) signifie toutes.

CURLOPT_HTTPGET La méthode HTTP employée sera GET. Il s'agit du type de requêtepar défaut.

CURLOPT_POST Définir cette option à la valeur TRUE aura pour effet d'employer laméthode POST à la place de la méthode GET par défaut.

CURLOPT_POSTFIELDSLes données à envoyer par la méthode POST sous la forme d'unechaîne (doivent être encodées) ou d'un tableau associant le nomdu champ à sa valeur. Cette deuxième forme ne nécessite pasl'encodage des données car elle sera réalisée en interne et permetd'envoyer des fichiers en faisant précéder leur nom d'une arobase.

CURLOPT_USERPWDPermet de fournir un identifiant et un mot de passe pour passerles systèmes d'authentification HTTP. Ils prennent alors la formelogin:mot_de_passe.

CURLOPT_USERAGENTDéfinit l'en-tête User-Agent (le navigateur) pour la requête HTTP.CURLOPT_REFERERRenseigne l'en-tête Referer, la page d'où on provient en temps

normal.CURLOPT_AUTOREFERERAvec la valeur TRUE cURL renseignera automatiquement l'en-tête

Referer lors de redirections.CURLOPT_HTTPHEADEREnsemble d'en-têtes à présenter lors de la requête sous la forme

d'un tableau numériquement indexé.CURLOPT_COOKIEFILEIndique le fichier duquel seront lues les données relatives aux

cookies.CURLOPT_COOKIEJARFichier où seront écrites les données des différents cookies reçus.

Et enfin la gestion du protocole FTP :

Nom DescriptionCURLOPT_QUOTE Un tableau numériquement indexé des commandes FTP à exécuter

avant notre requête.CURLOPT_POSTQUOTELes commandes FTP à exécuter après notre requête sous la forme

d'un tableau numériquement indexé.CURLOPT_TRANSFERTEXTUne valeur vraie indique à cURL d'utiliser le mode de transfert

appelé ASCII au lieu du mode binaire par défaut. Toutefois,attention : le mode ascii est implémenté de manière incomplète ausein de cURL.

CURLOPT_FTP_SSL Permet de spécifier, à l'aide d'une des constantes ci-dessous, leniveau de sécurité des données qui vont transiter :

• CURLFTPSSL_NONE : connexion FTP normale, aucunrecours à SSL

Page 10: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 10 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

• CURLFTPSSL_TRY : tente d'utiliser SSL ou à défaut leprotocole normal

• CURLFTPSSL_CONTROL : SSL sera requis sur la connexionde contrôle sinon cURL échouera

• CURLFTPSSL_ALL : SSL sera requis à la fois pour laconnexion de contrôle ainsi que sur le canal de données

CURLOPT_FTPSSLAUTHDétermine l'ordre des versions du protocole SSL à employer :

• CURLFTPAUTH_DEFAULT : laisse à cURL le soin de décider• CURLFTPAUTH_SSL : tente d'utiliser SSL avant TLS• CURLFTPAUTH_TLS : tente d'utiliser TLS avant SSL

Page 11: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 11 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

3 - Utilisation

3.1 - Le protocole HTTP

3.1.1 - Vérifier l'existence d'une URL

Le but du jeu consiste à envoyer une requête de type HEAD vers la page indiquée est d'en obtenir le code HTTPcorrespondant. Bien sûr s'il n'y a aucun serveur HTTP à l'adresse et port indiqués, la fonction curl_exec échouera.

Les codes considérés comme synonymes de succès sont :

• 200 (OK) : la requête aboutie normalement• 301 (Moved Permanently) : la ressource visée a été définitivement déplacée, cette URL est obsolète• 302 (Temporary Redirect) : la page est temporairement accessible via une autre URL

Nous utiliserons donc les options de timeout (CURLOPT_TIMEOUT et CURLOPT_CONNECTTIMEOUT) pourassurer que le script nous rende, quoiqu'il arrive, rapidement la main ainsi que CURLOPT_NOBODY car le contenu dela page ne nous intéresse pas ici. Nous obtiendrons uniquement ce code d'erreur en combinant la fonction curl_getinfoà sa constante CURLINFO_HTTP_CODE que nous comparerons ensuite aux valeurs données ci-dessus :

function http_check_url($url, $timeout = 10){ $ch = curl_init($url); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch, CURLOPT_NOBODY, TRUE); if (strpos($url, 'https://') === 0) { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // On ne vérifie que l'existence de la page } if (!curl_exec($ch)) { return FALSE; } $ret = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);

return in_array($ret, array(200, 301, 302));}

// Exemple d'utilisation :define('OK', '<span style="color: green">OK</span>');define('KO', '<span style="color: red">KO</span>');$urls = array( 'http://www.non-existant.fr', 'http://www.developpez.com/', 'http://php.developpez.com/faq/');foreach ($urls as $u) { echo $u . ' : ' . (http_check_url($u) ? OK : KO) . '<br/>';}

3.1.2 - Récupérer le contenu d'une page

Nous sommes parfois amenés à vouloir récupérer le contenu d'une page distante sous la forme d'une chaîne decaractères à des fins toutes aussi diverses comme par exemple pour en extraire certaines informations, constituerun cache, etc. Cette pratique est monnaie courante avec le protocole HTTP mais puisque nous utilisons cURL estaussi valable pour d'autres, citons par exemple FTP.

Page 12: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 12 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

L'option cURL la plus importante ici est CURLOPT_RETURNTRANSFER. En effet, si celle-ci est omise ou n'est pasfixée à une valeur vraie, le contenu du fichier distant sera directement renvoyé au navigateur de votre visiteur or noussouhaitons le traiter. Nous réutiliserons des options que nous avons déjà vues auparavant, notamment celles liées àla durée maximale d'exécution de la requête par cURL. Voyons comment implémenter une telle fonction :

function http_fetch_url($url, $timeout = 10, $userpwd = ''){ $ch = curl_init($url); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); if ($userpwd) { curl_setopt($ch, CURLOPT_USERPWD, $userpwd); } $data = curl_exec($ch); curl_close($ch);

return $data;}

// Exemple d'utilisation :if (($content = http_fetch_url('http://www.monsite.fr/zone_privee/sqldump.php', 10, 'utilisateur:mot_de_passe')) === FALSE) { die("Une erreur est survenue");} else { echo htmlentities($content);}

Les paramètres d'identification (login et mot de passe) peuvent directement figurer dans l'URL comme ils peuventêtre spécifiés à part via l'option CURLOPT_USERPWD, introduite ci-dessus à titre informatif.

Pour des raisons légales, vous êtes fortement invités à prendre préalablement contactavec les responsables des sites sur lesquels vous voudriez reprendre des informations.

3.1.3 - Envoyer des données par la méthode POST

Pour utiliser la méthode POST, nous permettant ainsi d'envoyer des données conséquentes et de simuler lasoumission d'un formulaire, l'une des méthodes consiste à regrouper l'ensemble de ces données sous la forme d'unechaîne encodée qui sera ensuite fournie à la session cURL via l'option CURLOPT_POSTFIELDS. Parfaitement,les informations à transmettre doivent être encodées conformément à la définition du protocole HTTP pourgarantir la syntaxe de la requête, rappelons que les données doivent se présenter sous la forme suivante :param1=valeur1&param2=valeur2&...&paramN=valeurN et qu'un certain nombre de caractères spéciaux vis-à-vis duprotocole HTTP doivent être encodés. En PHP 5, la fonction http_build_query permet de gérer directement tous cesaspects, en revanche, pour PHP 4 il nous faudra la réécrire (voir ci-dessous).

Voyons un exemple sans réel intérêt, dont le rôle est de retransmettre les données POST reçues par un script àdestination d'une autre page :

// Pour assurer la compatibilité avec les versions PHP 4if (!function_exists('http_build_query')) { function http_build_query($formdata, $numeric_prefix = NULL, $arg_separator = '', $parent_key = '') { $ret = array(); if (is_array($formdata)) { if (empty($arg_separator)) { $arg_separator = ini_get('arg_separator.output'); } foreach ($formdata as $k => $v) { if (is_int($k) && $numeric_prefix != NULL) {

Page 13: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 13 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

$k = $numeric_prefix . $k; } if ($parent_key != '') { $k = sprintf('%s[%s]', $parent_key, $k); } if (is_array($v)) { array_push($ret, http_build_query($v, NULL, $arg_separator, $k)); } elseif (is_object($v)) { array_push($ret, http_build_query(get_object_vars($v), NULL, $arg_separator, $k)); } else { array_push($ret, urlencode($k) . '=' . urlencode($v)); } } } return implode($arg_separator, $ret); }}

// Faire suivre les données POST à une autre page$ch = curl_init('http://www.monsite.fr/formulaire.html');curl_setopt($ch, CURLOPT_POST, TRUE);curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($_POST));curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);$ret = curl_exec($ch);if (!$ret) { echo curl_error($ch);} else { echo $ret;}curl_close($ch);

L'autre méthode simplifiant quelque peu les choses est de donner à cette option non pas une chaîne de caractèresmais un tableau associant le nom du paramètre à sa valeur. L'intérêt est double :

• Vous n'avez pas à vous soucier de la forme des données : elles seront regroupées et encodées en internepar cURL

• Cela permet l'upload de fichiers : tout paramètre dont le nom commence par une arobase et correspondant àun fichier local sera joint

Voyons un exemple visant à simuler la validation d'un formulaire comportant un champ de type textarea (nommédescription) et un de type file (photo) :

// Données à envoyer$post = array( // La zone de texte "description" 'description' => "Photo n°1 de mon week-end en Bretagne.\r\nPique-nique dans la forêt de Broceliande.", // Le fichier à uploader sous "photo" 'photo' => '@' . realpath('P1010001.JPG'));

// On effectue la requête avec cURL$ch = curl_init('http://www.monsite.fr/envoi_photo.php');curl_setopt($ch, CURLOPT_NOBODY, TRUE);curl_setopt($ch, CURLOPT_POST, TRUE);curl_setopt($ch, CURLOPT_POSTFIELDS, $post);$ret = curl_exec($ch);if (!$ret) { echo curl_error($ch);} else { echo 'Envoi OK !';}curl_close($ch);

Page 14: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 14 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

3.1.4 - Débuter une session puis la réutiliser

Certaines pages requièrent parfois une authentification avant de donner accès à un contenu plus vaste. Il est alorsnécessaire d'établir une première connexion pour créer une session côté serveur afin de mémoriser cette identificationet de pouvoir lire par la suite l'ensemble des données du site. Pour cela nous devons faire parvenir son identifiantau serveur pour ne plus avoir à repasser par la case authentification (sur un temps limité) et consulter directementles pages qui nous intéressent par la suite.

Un serveur employant PHP (versions 4 et supérieures) propose deux méthodes indépendantes et complémentairespour faire transiter l'identifiant de session à savoir : l'utilisation d'un cookie de session ou la réécriture des liensinternes et formulaires de sorte à le transmettre à la prochaine requête.

Pour correspondre à un maximum de configuration nous utiliserons les options proposées par cURL pour recouriraux cookies et nous parserons le corps de la page à la recherche d'un tel identifiant. La première étape consistedonc à s'authentifier pour initialiser une session "valide" et de tenter de capturer cet identifiant de session, suivant laconfiguration du serveur distant, pour pouvoir ensuite le réexploiter lors de notre deuxième requête.

Lors de la deuxième, nous renverrons cet identifiant, si nous l'avons trouvé, en méthode GET (la méthode POST lepermet aussi), ce qui devrait nous donner directement accès au document que nous souhaitons consulter.

Voici une méthode de procéder propre à un serveur PHP :

define('LOGIN', 'julp');define('PASSWORD', 'mdp');define('AUTHENTIFICATION', 'http://localhost/curl/session/login.php');define('PAGE_PRIVEE', 'http://localhost/curl/session/admin.php');

$sid = '';

/** * Première connexion : authentification **/$ch = curl_init(AUTHENTIFICATION);curl_setopt($ch, CURLOPT_POST, TRUE);curl_setopt($ch, CURLOPT_POSTFIELDS, array( 'login' => LOGIN, 'mdp' => PASSWORD ));curl_setopt($ch, CURLOPT_COOKIEJAR, realpath('cookie.txt'));curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE);curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);$ret = curl_exec($ch);if ($ret === FALSE) { die(curl_error());}curl_close($ch);if (preg_match('/(PHPSESSID=[0-9a-z,-]{32,40})/i', $ret, $m)) { $sid = '?' . $m[1];} else if (preg_match('#<input\s+type="hidden"\s+name="([^\r\n\t <>\'"\\\]+)"\s+value="([0-9a-z,-]{32,40})"\s*/?>#i', $ret, $m)) { $sid = '?' . $m[1] . '=' . $m[2];}

/** * Deuxième partie : réutilisation de la session sur une page tierce **/$ch = curl_init(PAGE_PRIVEE . $sid);curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);curl_setopt($ch, CURLOPT_COOKIEFILE, realpath('cookie.txt'));

Page 15: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 15 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

$ret = curl_exec($ch);if ($ret === FALSE) { die(curl_error());}curl_close($ch);echo $ret;

Pour rappel : cURL n'interprète pas les langages (HTML ou Javascript notamment) ainsi il peut être mis à mal pardes redirections à effectuer côté client (balise meta, window.location.href). Ce problème ne se pose pas lorsqu'ellessont effectuées côté serveur grâce à l'en-tête "Location:".

Pour en savoir plus sur les sessions php (utilisation comme configuration), je vous invite

à consulter l'article éponyme : Les sessions en PHP.

3.1.5 - Source : simplifier l'utilisation de cURL pour le protocole HTTP

Voici une classe PHP 5 qui vous permet d'interroger facilement et rapidement des serveurs HTTP :

class HTTPQuery{ /** * Tableau : les données POST qui seront envoyées (nom du champ => valeur) **/ protected $_post;

/** * Tableau des options cURL définies par l'utilisateur (option => valeur) **/ protected $_options;

/** * La ressource cURL **/ protected $_ch;

/** * Constructeur * @param url URL à laquelle la requête sera envoyée * @throws Exception si l'extension cURL n'est pas active **/ public function __construct($url) { if (!extension_loaded('curl')) { throw new Exception("L'extension curl n'est pas disponible"); } $this->_ch = curl_init($url); $this->_options = array(); }

/** * Obtenir la valeur des options cURL avec la syntaxe $ojet->CURLOPT_X définie par l'utilisateur * @param nom le nom de l'option cURL * @return NULL si l'option n'a pas été définie sinon sa valeur **/ public function __get($nom) { $resultat = NULL; if (defined($nom)) { $valeur = constant($nom); if (isset($this->_options[$valeur])) { $resultat = $this->_options[$valeur]; } } return $resultat;

Page 16: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 16 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

}

/** * Fixer les valeurs des options cURL avec la syntaxe $objet->CURLOPT_X = Y * @param nom le nom de l'option cURL (constantes CURLOPT_*) * @param valeur la nouvelle valeur de l'option (écrase la précédente) * @throws Exception si l'option "nom" n'est pas valide (inexistante ou ne commençant pas par CURLOPT_) ou est * protégée de façon à ce que vous passiez par les méthodes déléguées à la fonctionnalité ciblée **/ public function __set($nom, $valeur) { if (defined($nom) && preg_match('/^CURLOPT_(?!POSTFIELDS)/', $nom)) { $this->_options[constant($nom)] = $valeur; } else { throw new Exception("Option '$nom' invalide ou protégée"); } }

/** * Prendre connaissance de la définition d'une option cURL par l'utilisateur * @param nom le nom de l'option cURL * @return un booléen indiquant si cette option a été définie **/ public function __isset($nom) { return (defined($nom) && isset($this->_options[constant($nom)])); }

/** * Détruire la définition d'une option cURL * @param nom le nom de l'option cURL à détruire **/ public function __unset($nom) { if (defined($nom) && isset($this->_options[constant($nom)])) { unset($this->_options[constant($nom)]); } }

/** * Description de l'objet * @return une chaîne de caractères décrivant l'objet **/ public function __toString() { return sprintf("%s (%s)", __CLASS__, curl_getinfo($this->_ch, CURLINFO_EFFECTIVE_URL)); }

/** * Fixer la durée maximale d'exécution de la requête * @param timeout cette durée exprimée en secondes **/ public function setTimeout($timeout) { $timeout = intval($timeout); if ($timeout > 0) { $this->CURLOPT_TIMEOUT = $timeout; $this->CURLOPT_CONNECTTIMEOUT = $timeout; } }

/** * Ajouter des données textuelles aux données POST à envoyer * @param nom_champ le nom du champ (permet d'exploiter les données côté serveur - $_POST) * @param valeur les données correspondantes à envoyer * @return un booléen indiquant que les données ont été prises en compte **/ public function addPostData($nom_champ, $valeur) { if (!isset($this->_post[$nom_champ]) && !is_array($valeur)) { $this->_post[$nom_champ] = $valeur; return TRUE;

Page 17: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 17 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

} else { return FALSE; } }

/** * Ajouter un fichier aux données POST à envoyer (upload de fichiers) * @param nom_champ le nom du champ (permet d'exploiter le fichier à sa réception - $_FILES) * @param fichier le fichier à envoyer * @throws Exception si le fichier indiqué est inexistant ou n'est pas un fichier régulier **/ public function addPostFile($nom_champ, $fichier) { if (is_file($fichier)) { $this->_post[$nom_champ] = '@' . realpath($fichier); } else { throw new Exception("Le fichier '$fichier' n'existe pas ou n'est pas un fichier régulier"); } }

/** * Exécuter la requête * @param fichier_sortie, renseigné le contenu de la page distante est écrit dans le fichier indiqué * @return le contenu de la page distante ou alors TRUE si le paramètre fichier_sortie a été utilisé * @throws Exception en cas d'erreur liée à cURL ou à l'écriture du fichier **/ public function doRequest($fichier_sortie = FALSE) { if ($this->_options) { if (function_exists('curl_setopt_array')) { curl_setopt_array($this->_ch, $this->_options); } else { foreach ($this->_options as $option => $valeur) { curl_setopt($this->_ch, $option, $valeur); } } } if ($fichier_sortie) { @ $fp = fopen($fichier_sortie, 'w'); if (!$fp) { throw new Exception("Impossible d'ouvrir en écriture le fichier '$fichier_sortie'"); } curl_setopt($this->_ch, CURLOPT_FILE, $fp); } else { curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, TRUE); } if ($this->_post) { curl_setopt($this->_ch, CURLOPT_POST, TRUE); curl_setopt($this->_ch, CURLOPT_POSTFIELDS, $this->_post); } $ret = curl_exec($this->_ch); if ($fichier_sortie) { fclose($fp); } if ($ret === FALSE) { throw new Exception("Une erreur est survenue : '" . curl_error($this->_ch) . "'"); } return $ret; }

/** * Destructeur **/ public function __destruct() { unset($this->_options); unset($this->_post); curl_close($this->_ch); }}

Page 18: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 18 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

Un exemple complet visant à afficher la sortie résultant de la soumission d'un formulaire distant d'upload de photoscomprenant d'autres champs plus classiques, le tout avec une authentification HTTP et utilisant le protocole HTTPSpour la sécurité :

require_once('/var/www/offline/librairies/HTTPQuery.php');

try { $http = new HTTPQuery('https://julp:mdp@mon_serveur/admin/ajouter_photo.php'); /* Quelques fichiers à uploader */ $http->addPostFile('images[0]', '../images1.jpg'); // Récupérée sur le serveur distant via $_FILES['images']['name'][0] $http->addPostFile('images[1]', '../images2.jpg'); // Récupérée sur le serveur distant via $_FILES['images']['name'][1] /* Les données correspondant aux différents champs du formulaire */ $http->addPostData('visibilite[0]', 'visiteurs'); // $_POST['visibilite'][0] : simulation d'une checkbox $http->addPostData('visibilite[1]', 'enregistrés'); // $_POST['visibilite'][1] : simulation d'une checkbox $http->addPostData('description', "Les photos de ce week-end.\r\nC'est fou ce qu'il faisait beau."); // $_POST['description'] : simulation d'une textarea $http->addPostData('submit', 'x'); // $_POST['submit'] : le bouton submit /* Vérification du certificat présenté par le serveur */ $http->CURLOPT_CAINFO = 'ca-root.crt'; // Obtenu sur http://www.freebsd.org/cgi/cvsweb.cgi/ports/security/ca-roots/files/ $http->CURLOPT_SSL_VERIFYPEER = TRUE; /* On effectue enfin la requête */ echo $http->doRequest();} catch (Exception $e) { die($e->getMessage());}

3.2 - Le protocole FTP

3.2.1 - Lister un répertoire distant

Il est possible d'obtenir la liste des fichiers présents dans un répertoire distant en utilisant le protocole FTP et l'optionCURLOPT_FTPLISTONLY. Le résultat est une liste des noms des fichiers (et aucune autre information comme leurpoids) séparés par des nouvelles lignes. Par conséquent voici une méthode pour exploiter et réutiliser ce résultat :

function curl_ftp_list($url, $timeout = 10){ $ch = curl_init($url); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_FTPLISTONLY, TRUE); $ret = curl_exec($ch); curl_close($ch); if ($ret === FALSE) { return FALSE; } else { return preg_split('/[\r\n]+/', $ret, -1, PREG_SPLIT_NO_EMPTY); }}

// Exemple d'utilisation :$fichiers = curl_ftp_list('ftp://login:mot_de_passe@serveur/');natsort($fichiers);if ($fichiers === FALSE) { die("La connexion n'a pu être établie");} else { echo '<ul>';

Page 19: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 19 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

foreach ($fichiers as $f) { if ($f != '.' and $f != '..') { echo '<li>' . $f . '</li>'; } } echo '</ul>';}

On peut cependant aller plus loin en envoyant la commande FTP LIST (via l'option CURLOPT_CUSTOMREQUEST)qui nous permettra de récupérer en plus des noms des fichiers, leurs permissions, propriétaire, taille, etc. Toutefois,ces informations étant renvoyées sous forme de texte monolithique il va nous falloir utiliser une expression régulièreafin de séparer ces différentes informations :

function curl_ftp_list_bis($url, $timeout = 10){ $ch = curl_init($url); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "LIST"); $ret = curl_exec($ch); echo curl_error($ch); curl_close($ch); if ($ret === FALSE) { return FALSE; } else { $fichiers = array(); $nbFichiers = 0; if (preg_match_all('/([-dl])([rwxst-]{9})[ ]+([0-9]+)[ ]+([^ ]+)[ ]+(.+)[ ]+([0-9]+)[ ]+([a-zA-Z]+[ ]+[0-9]+)[ ]+([0-9:]+)[ ]+(.*)/', $ret, $m, PREG_SET_ORDER)) { foreach ($m as $f) { $fichiers[$nbFichiers] = array(); $fichiers[$nbFichiers]['dir'] = $f[1] == 'd'; // Répertoire ? $fichiers[$nbFichiers]['filename'] = $f[9]; // Nom $fichiers[$nbFichiers]['size'] = $f[6]; // Taille $fichiers[$nbFichiers]['owner'] = $f[4]; // Propriétaire $fichiers[$nbFichiers]['group'] = $f[5]; // Groupe $fichiers[$nbFichiers]['permissions'] = $f[2]; // Permissions $fichiers[$nbFichiers]['mtime'] = "$f[7] $f[8]"; // Date de dernière modification $nbFichiers++; } } return $fichiers; }}

3.2.2 - Envoyer un fichier

Le fichier à envoyer doit tout d'abord être ouvert en écriture avec la fonction fopen (mode r). Ce descripteur de fichierainsi obtenu sera transmis à cURL par l'option CURLOPT_INFILE. Nous devons également indiquer la partie dufichier concernée via CURLOPT_INFILESIZE mais notre but étant de faire parvenir ce fichier dans son intégraliténous lui fournirons donc la taille réelle de celui-ci grâce à la fonction filesize. Enfin, nous signalons à cURL qu'il s'agitd'un upload et qu'il doit s'y préparer en positionnant l'option CURLOPT_UPLOAD à vrai :

function curl_ftp_put($url, $nom_local, $mode_ascii = FALSE, $chmod = FALSE){ $ret = FALSE;

if (is_file($nom_local)) { $fp = fopen($nom_local, 'r'); $ch = curl_init($url); curl_setopt($ch, CURLOPT_INFILE, $fp);

Page 20: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 20 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

curl_setopt($ch, CURLOPT_INFILESIZE, filesize($nom_local)); curl_setopt($ch, CURLOPT_UPLOAD, TRUE); if ($mode_ascii) { curl_setopt($ch, CURLOPT_TRANSFERTEXT, TRUE); } if ($chmod) { $path = parse_url($url, PHP_URL_PATH); curl_setopt($ch, CURLOPT_POSTQUOTE, array("SITE CHMOD $chmod $path")); } $ret = curl_exec($ch); curl_close($ch); fclose($fp); }

return $ret;}

// Exemple d'utilisation :if (!curl_ftp_put('ftp://login:mot_de_passe@serveur/mon_fichier.txt', 'mon_fichier.txt', TRUE, '0400')) { die("Le fichier n'a pu être uploadé sur le serveur");}

L'URL désigne bien le fichier à créer ou écraser et non le répertoire parent.Veillez, de préférence, à fermer le fichier ouvert (fonction fclose) à la fin de l'envoi.

J'ai introduit dans l'exemple ci-dessus deux options que vous serez peut être amenés à réutiliser. Tout d'abord,CURLOPT_TRANSFERTEXT qui indique que le mode de transfert à utiliser n'est pas le mode binaire (par défaut)mais le mode ascii. Le protocole FTP propose en effet deux modes qui dépendent de la nature des données à envoyeret qui lorsque le mode adéquat n'est pas employé donne souvent lieu à des corruptions de fichiers. La deuxième,CURLOPT_POSTQUOTE, permet d'exécuter après la requête une liste (sous forme de tableau) de commandes quiici peut être employée pour fixer les permissions du fichier à l'issue de sa réception.

3.2.3 - Télécharger un fichier

Sur le même principe que l'envoi, il faut en premier lieu ouvrir le fichier local qui va accueillir les données reçues enécriture. Chose que nous ferons avec la fonction fopen (mode w) et nous procurerons ensuite le descripteur de fichierainsi obtenu à cURL par l'intermédiaire de l'option CURLOPT_FILE :

function ftp_curl_get($url, $sortie, $timeout = 10){ if ($fp = fopen($sortie, 'w')) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_FILE, $fp); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); $ret = curl_exec($ch); curl_close($ch); fclose($fp); return $ret; } return FALSE;}

// Exemple d'utilisation :if (!ftp_curl_get('ftp://utilisateur:mot_de_passe@serveur/fichier_distant', 'nom_local')) { die("Le fichier indiqué n'a pu être récupéré");}

Page 21: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 21 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

3.3 - Le protocole LDAP

cURL est également capable d'interroger un annuaire LDAP, le seul changement à apporter se situe alors auniveau de l'URL dont la forme vous est rappelée ci-dessous. Cependant, il faut savoir que cURL utilise la librairiecliente OpenLDAP pour interagir avec les annuaires (fonctionnalité pouvant être désactivée) et qu'elle est limitée(l'authentification n'est pas assurée par exemple).

ldap[s]://[hôte]:[port]/[dn_base]?[attributs]?[scope]?[filtre]?[extensions]

• hôte : nom du serveur LDAP• port : le port TCP de connexion. Les valeurs par défaut sont 389 pour une connexion non chiffrée ou TLS et

636 pour une connexion cryptée à l'aide de SSL• dn_base : nom distingué de l'objet servant de point de référence pour la recherche• attributs : liste des attributs souhaités séparés par une virgule. Ils seront tous retournés si cette partie est

omise. La valeur spéciale * renvoie en plus les attributs internes.• scope : une des valeurs suivantes :

• base (par défaut) : seul l'objet désigné par dn_base sera concerné par la recherche• one : les objets dont le père direct est l'objet indiqué par dn_base seront retenus• sub : la recherche touchera tous les objets ayant un lien de parenté avec dn_base

• filtre : le filtre de recherche (par défaut : (objectclass=*))• extensions : liste de fonctionnalités diverses

En guise d'exemple une réimplémentation de la fonction ldap_get_entries entièrement basée sur les extensions cURLet PCRE :

function curl_ldap_get_entries($url, $timeout = 10){ // Exécution de la recherche $ch = curl_init($url); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); $ldif = curl_exec($ch); curl_close($ch);

// Traitement du résultat if ($ldif) { $objets = preg_split('/^DN:\s*/im', $ldif, -1, PREG_SPLIT_NO_EMPTY); $res = array('count' => 0); foreach ($objets as $o) { $lignes = preg_split('/[\r\n]+/', $o, -1, PREG_SPLIT_NO_EMPTY); $nbAttr = 0; foreach ($lignes as $l) { $l = trim($l); if (preg_match('/^([^:]+):\s*(.*)$/', $l, $m)) { if (!in_array($m[1], $res[$res['count']])) { $res[$res['count']][] = $m[1]; $nbAttr++; } $res[$res['count']][$m[1]][] = $m[2]; if (!isset($res[$res['count']][$m[1]]['count'])) { $res[$res['count']][$m[1]]['count'] = 1; } else { $res[$res['count']][$m[1]]['count']++; } } else { // DN $res[$res['count']]['dn'] = $l; } } $res[$res['count']]['count'] = $nbAttr;

Page 22: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 22 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

$res['count']++; } return $res; } return FALSE;}

// Un exemple :$objets = curl_ldap_get_entries('ldap://ldap.mondomaine.fr/dc=developpez,dc=com??sub');if ($objets) { print_r($objets);}

Page 23: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 23 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

4 - Alternatives : mise en parallèle avec d'autres méthodes

Ces fonctions ont été développées pour un environnement PHP5 car certaines fonctionnalités ont évoluées (ledeuxième paramètre de la fonction parse_url a été introduit à ce moment) ou bien de nouvelles fonctions sontapparues (stream_get_wrappers et http_build_query).

4.1 - Vérifier l'existence d'une page

Comme nous l'avons précédemment vu, une requête HEAD permet de connaître le statut d'une page HTTP. Il existeplusieurs méthodes pour envoyer une telle requête pour ensuite contrôler le code d'erreur retourné comme réponseparmi les en-têtes :

• avec cURL• en exploitant la gestion native de flux HTTP par PHP si elle est possible (c'est à dire que la directive

allow_url_fopen doit être à On)• à l'aide de la fonction fsockopen

function tester_url_http($url, $timeout = 10){ if (extension_loaded('curl')) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch, CURLOPT_NOBODY, TRUE); if (strpos($url, 'https://') === 0) { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // On ne vérifie que l'existence de la page } if (!curl_exec($ch)) { return FALSE; } $ret = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return in_array($ret, array(200, 301, 302)); } elseif (ini_get('allow_url_fopen') && in_array(parse_url($url, PHP_URL_SCHEME), stream_get_wrappers())) { $infos = parse_url($url); $options = array( 'http' => array( 'method' => 'HEAD', 'header' => '', 'timeout' => $timeout // Effectif pour les versions 5.2.1 et supérieures ) ); if (isset($infos['user'])) { $options['http']['header'] .= 'Authorization: Basic ' . base64_encode($infos['user'] . ':' . $infos['pass']) . "\r\n"; } $contexte = stream_context_create($options); @ $fp = fopen($url, 'r', FALSE, $contexte); if (!$fp) { return FALSE; } $meta = stream_get_meta_data($fp); fclose($fp); if (preg_match('#^HTTP/1\.[01] ([0-9]{3})#', $meta['wrapper_data'][0], $m)) { return in_array($m[1], array(200, 301, 302)); } else { return FALSE; } } elseif (function_exists('fsockopen')) { $infos = parse_url($url);

Page 24: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 24 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

if (empty($infos['path'])) { $infos['path'] = '/'; } if (!isset($infos['port'])) { if ($infos['scheme'] == 'http') { $infos['port'] = 80; } elseif ($infos['scheme'] == 'https') { $infos['port'] = 443; } } @ $fp = fsockopen($infos['host'] == 'https' ? 'ssl://' . $infos['host'] : $infos['host'], $infos['port'], $errno, $errstr, $timeout); if (!$fp) { return FALSE; } stream_set_timeout($fp, $timeout); $requete = 'HEAD ' . $infos['path'] . '?' . (isset($infos['query']) ? $infos['query'] : '') . " HTTP/1.1\r\n"; $requete .= 'Host: ' . $infos['host'] . ':' . $infos['port'] . "\r\n"; if (isset($infos['user'])) { $requete .= 'Authorization: Basic ' . base64_encode($infos['user'] . ':' . $infos['pass']) . "\r\n"; } fwrite($fp, $requete . "\r\n"); $entete = fgets($fp, 32); fclose($fp); if (preg_match('#^HTTP/1\.[01] ([0-9]{3})#', $entete, $m)) { return in_array($m[1], array(200, 301, 302)); } else { return FALSE; } } else { die("Aucune méthode permettant de vérifier l'état d'un document en ligne n'est disponible"); }}

4.2 - Récupérer le corps d'une page

L'obtention du corps d'une page distante peut se faire de plusieurs manières :

• Avec l'extension cURL• Avec la gestion de flux HTTP par PHP pour les fonctions capables de lire des fichiers• Avec la fonction fsockopen, relativement lente, avec laquelle nous devons forger et exploiter les requêtes de

nous-mêmes

Vous trouverez ci-dessous une fonction générique pour obtenir le code source d'une page distante, gérant la méthodePOST ainsi que l'authentification HTTP basique :

function recuperer_page_http($url, $timeout = 10, $nom_local = '', $post = NULL) { if (extension_loaded('curl')) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); if ($nom_local) { $fp = fopen($nom_local, 'w') or die("Le fichier '$nom_local' n'a pu être ouvert en écriture"); curl_setopt($ch, CURLOPT_FILE, $fp); } else { curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); } if ($post) { curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); }

Page 25: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 25 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

$ret = curl_exec($ch); if ($nom_local) { fclose($fp); } curl_close($ch); if ($ret === FALSE) { die("Une erreur a été rencontrée : " . curl_error()); } return $ret; } elseif (ini_get('allow_url_fopen') && in_array(parse_url($url, PHP_URL_SCHEME), stream_get_wrappers())) { $infos = parse_url($url); $contexte = NULL; if (isset($infos['user']) || $post) { $options = array( 'http' => array( 'method' => $post ? 'POST' : 'GET', 'header' => '', 'timeout' => $timeout // Effectif pour les versions 5.2.1 et supérieures ) ); if (isset($infos['user'])) { $options['http']['header'] .= 'Authorization: Basic ' . base64_encode($infos['user'] . ':' . $infos['pass']) . "\r\n"; } if ($post) { $data = http_build_query($post); $options['http']['header'] .= "Content-type: application/x-www-form-urlencoded\r\n"; $options['http']['header'] .= 'Content-Length: ' . strlen($data) . "\r\n"; $options['http']['content'] = $data; } $contexte = stream_context_create($options); } if (!$nom_local) { return file_get_contents($url, FALSE, $contexte); } else { $in = fopen($url, 'r', FALSE, $contexte); stream_set_timeout($in, $timeout); $out = fopen($nom_local, 'w') or die("Le fichier '$nom_local' n'a pu être ouvert en écriture"); while (!feof($in)) { fwrite($out, fread($in, 1024)); } fclose($in); fclose($out); } } elseif (function_exists('fsockopen')) { $infos = parse_url($url); if ($nom_local) { $out = fopen($nom_local, 'w') or die("Le fichier '$nom_local' n'a pu être ouvert en écriture"); } if (empty($infos['path'])) { $infos['path'] = '/'; } if (!isset($infos['port'])) { if ($infos['scheme'] == 'http') { $infos['port'] = 80; } elseif ($infos['scheme'] == 'https') { $infos['port'] = 443; } } @ $fp = fsockopen($infos['host'] == 'https' ? 'ssl://' . $infos['host'] : $infos['host'], $infos['port'], $errno, $errstr, $timeout); if (!$fp) { return FALSE; } stream_set_timeout($fp, $timeout); $requete = ($post ? 'POST ' : 'GET ') . $infos['path'] . '?' . (isset($infos['query']) ? $infos['query'] : '') . " HTTP/1.1\r\n";

Page 26: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 26 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

$requete .= 'Host: ' . $infos['host'] . ':' . (isset($infos['port']) ? $infos['port'] : '80') . "\r\n"; if (isset($infos['user'])) { $requete .= 'Authorization: Basic ' . base64_encode($infos['user'] . ':' . $infos['pass']) . "\r\n"; } if ($post) { $data = http_build_query($post); $requete .= "Content-type: application/x-www-form-urlencoded\r\n"; $requete .= 'Content-Length: ' . strlen($data) . "\r\n"; } fwrite($fp, $requete . "\r\n" . $data); $buffer = ''; do { // Saut de l'entête HTTP $buffer .= fgets($fp, 1024); } while (!feof($fp) && strpos($buffer, "\r\n\r\n") === FALSE); $buffer = ''; while (!feof($fp)) { $buffer .= fread($fp, 1024); } $buffer = ltrim($buffer); $pos = strpos($buffer, "\r\n"); $len = hexdec(substr($buffer, 0, $pos)); $buffer = substr($buffer, $pos + strlen("\r\n"), $len); if ($nom_local) { fwrite($out, $buffer); fclose($out); $buffer = TRUE; } fclose($fp); return $buffer; } else { die("Aucune méthode permettant de récupérer la source d'une page n'est disponible"); }}

4.3 - Recevoir un fichier par FTP

PHP offre différents moyens pour télécharger un fichier via le protocole FTP. A savoir :

• l'extension FTP, le premier moyen qui nous viendrait à l'esprit• l'extension cURL, comme nous l'avons déjà vu précédemment• la gestion interne par PHP de flux FTP, ce qui nous permet d'utiliser les traditionnelles fonctions de lecture et

écriture sur des fichiers

Voilà donc une fonction capable de s'adapter à l'environnement afin de tenter de télécharger un fichier à partir d'uneURL FTP :

function recuperer_fichier_ftp($url, $nom_local, $mode_ascii = FALSE, $timeout = 10) { if (extension_loaded('ftp')) { $infos = parse_url($url); if ($infos['scheme'] == 'ftps') { if (function_exists('ftp_ssl_connect')) { $conn = ftp_ssl_connect($infos['host'], isset($infos['port']) ? $infos['port'] : 0, $timeout) or die("La connexion n'a pu être établie"); } else { die("La fonction ftp_ssl_connect n'est pas disponible !"); } } else { $conn = ftp_connect($infos['host'], isset($infos['port']) ? $infos['port'] : 0, $timeout) or die("La connexion n'a pu être établie"); } ftp_login($conn, $infos['user'], $infos['pass']) or die("La phase d'authentifcation a échoué");

Page 27: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 27 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

ftp_get($conn, $nom_local, $infos['path'], $mode_ascii ? FTP_ASCII : FTP_BINARY) or die("Le téléchargement a échoué"); ftp_close($conn); } elseif (extension_loaded('curl')) { $fp = fopen($nom_local, 'w') or die("Le fichier '$nom_local' n'a pu être ouvert en écriture"); $ch = curl_init($url); curl_setopt($ch, CURLOPT_FILE, $fp); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); if ($mode_ascii) { curl_setopt($ch, CURLOPT_TRANSFERTEXT, TRUE); } if (strpos($url, 'ftps://') === 0) { // Options supplémentaires liées à SSL à utiliser } curl_exec($ch) or die("Une erreur a été rencontrée : " . curl_error()); curl_close($ch); fclose($fp); } elseif (ini_get('allow_url_fopen') && in_array(parse_url($url, PHP_URL_SCHEME), stream_get_wrappers())) { $in = fopen($url, $mode_ascii ? 'r' : 'rb'); $out = fopen($nom_local, $mode_ascii ? 'w' : 'wb'); while (!feof($in)) { fwrite($out, fread($in, 1024)); } fclose($in); fclose($out); } else { die("Aucune méthode permettant de récupérer un fichier par FTP n'est disponible"); }}

4.4 - Envoyer un fichier par FTP

Similaire en tout point au téléchargement d'un fichier par le biais du protocole FTP, un envoi n'entraîne deschangements que sur le sens des échanges (les flux ouverts en lecture sont maintenant ouverts en écriture et vice-versa) :

function envoyer_fichier_ftp($url, $nom_local, $mode_ascii = FALSE, $timeout = 10) { if (is_file($nom_local)) { if (extension_loaded('ftp')) { $infos = parse_url($url); if ($infos['scheme'] == 'ftps') { if (function_exists('ftp_ssl_connect')) { $conn = ftp_ssl_connect($infos['host'], isset($infos['port']) ? $infos['port'] : 0, $timeout) or die("La connexion n'a pu être établie"); } else { die("La fonction ftp_ssl_connect n'est pas disponible !"); } } else { $conn = ftp_connect($infos['host'], isset($infos['port']) ? $infos['port'] : 0, $timeout) or die("La connexion n'a pu être établie"); } ftp_login($conn, $infos['user'], $infos['pass']) or die("La phase d'authentifcation a échoué"); ftp_put($conn, $infos['path'], $nom_local, $mode_ascii ? FTP_ASCII : FTP_BINARY) or die("L'envoi a échoué"); ftp_close($conn); } elseif (extension_loaded('curl')) { $fp = fopen($nom_local, 'r'); $ch = curl_init($url); curl_setopt($ch, CURLOPT_INFILE, $fp); curl_setopt($ch, CURLOPT_INFILESIZE, filesize($nom_local)); curl_setopt($ch, CURLOPT_UPLOAD, TRUE); if ($mode_ascii) { curl_setopt($ch, CURLOPT_TRANSFERTEXT, TRUE);

Page 28: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 28 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

} if (strpos($url, 'ftps://') === 0) { // Options supplémentaires liées à SSL à utiliser } curl_exec($ch) or die("Une erreur a été rencontrée : " . curl_error()); curl_close($ch); fclose($fp); } elseif (ini_get('allow_url_fopen') && in_array(parse_url($url, PHP_URL_SCHEME), stream_get_wrappers())) { $in = fopen($nom_local, $mode_ascii ? 'r' : 'rb'); $out = fopen($url, $mode_ascii ? 'w' : 'wb'); while (!feof($in)) { fwrite($out, fread($in, 1024)); } fclose($in); fclose($out); } else { die("Aucune méthode permettant d'envoyer un fichier par FTP n'est disponible"); } } else { die("Le fichier '$nom_local' n'existe pas ou n'est pas un fichier régulier"); }}

Page 29: Plugin Php Curl

PHP : l'extension cURL par julp (Autres articles)

- 29 -Copyright © 2007 - julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents,images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommageset intérêts.

http://julp.developpez.com/php/curl/

5 - Conclusion

5.1 - Epilogue

J'espère vous avoir convaincu d'utiliser à votre tour l'extension cURL à la fois pour sa simplicité et sa souplesse dansla prise en charge des différents protocoles qu'elle est capable de gérer.

Cependant ceux qui n'ont pas la chance de profiter de son support (information que vous pouvez obtenir via la sortiede phpinfo) devront se tourner vers des alternatives comme fsockopen ou plus simplement vers les traditionnellesfonctions de lecture de fichiers comme file_get_contents et fopen, fread/fwrite, fclose mais requiert que la directiveallow_url_fopen soit à On (elles prennent habituellement en charge les protocoles HTTP et FTP).

Liens Developpez :• Le protocole HTTP

Liens externes :• Documentation officielle de l'extension cURL