Accueil
Rechercher:
sur developpez.com sur les forums
Forums | Tutoriels | F.A.Q's | Participez | Hébergement | Contacts
Accueil Conception Java DotNET Visual Basic  C  C++ Delphi MS-Office SQL & SGBD Oracle  4D  Business Intelligence
Club Emploi Blogs   TV   Dév. Web PHP XML Python Autres 2D-3D-Jeux Sécurité Windows Linux PC Mac
FORUM PHP FAQ PHP COURS PHP SOURCES PHP LIVRES PHP SCRIPTS PHP OUTILS PHP COMPARATIFS PHP TV Zend Framework

PHP : l'extension cURL

Date de publication : 12/06/2007

Par julp (Autres articles)
 

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.


1. Installation
1.1. Windows
1.2. Unix/Linux
1.2.1. Statique
1.2.2. Dynamique
2. Vue d'ensemble
2.1. Les fonctions
2.2. Les options
3. Utilisation
3.1. Le protocole HTTP
3.1.1. Vérifier l'existence d'une URL
3.1.2. Récupérer le contenu d'une page
3.1.3. Envoyer des données par la méthode POST
3.1.4. Débuter une session puis la réutiliser
3.1.5. Source : simplifier l'utilisation de cURL pour le protocole HTTP
3.2. Le protocole FTP
3.2.1. Lister un répertoire distant
3.2.2. Envoyer un fichier
3.2.3. Télécharger un fichier
3.3. Le protocole LDAP
4. Alternatives : mise en parallèle avec d'autres méthodes
4.1. Vérifier l'existence d'une page
4.2. Récupérer le corps d'une page
4.3. Recevoir un fichier par FTP
4.4. Envoyer un fichier par FTP
5. Conclusion
5.1. Epilogue


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'extension en é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épertoires pointé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 cette nouvelle 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 votre distribution Linux ou de votre système Unix auquel cas il ne devrait vous rester qu'à activer cette extension en éditant le fichier php.ini (voir ci-dessous la partie intitulée "Dynamique"). Par exemple, dans le cas de Mandriva où vos médias sont convenablement renseignés, l'installation se fera par cette commande : urpmi phpVERSION-curl (remplacez VERSION 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-curl
make
make 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/extension
phpize
./configure
make
make install
Vous devez ensuite modifier le fichier php.ini afin de disposer des fonctions cURL en chargeant l'extension à l'aide de la ligne suivante :
extension=curl.so
Assurez-vous que les chemins indiqués par la directive extension_dir sont corrects puisque PHP sera alors incapable de charger les extensions demandées auquel cas vous obtiendriez des messages d'erreur et aucune des fonctions qu'elles sont censées fournir.


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 est présenté par le schéma ci-dessous :

Pile des appels nécessaires à l'emploi de cURL
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 de l'indiquer par la suite avec la fonction curl_setopt, option CURLOPT_URL. Cette fonction renverra une ressource exploitable 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 est rencontré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 informations nécessaires doivent être fournies au préalable avec la fonction curl_setopt. Elle retourne FALSE si une erreur survient 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ésultat de la requête (du texte).

  • rien curl_close(ressource 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 ressources alloué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 une chaîne vide. Notez que cette fonction attend la session cURL courante issue de la fonction curl_init, elle doit donc 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 option est fourni alors seule l'information correspondante sera retournée et s'il est omis vous les obtiendrez toutes sous la forme d'un tableau associatif.

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

    Nom Description
    CURLINFO_EFFECTIVE_URL Dernière URL effective utilisée.
    CURLINFO_HTTP_CODE Code HTTP de la dernière réponse reçue. La valeur sera nulle si aucune réponse n'a (encore) été reçue.
    CURLINFO_FILETIME Timestamp indiquant la date du fichier distant. La valeur -1 sera renvoyée si cette information n'est pas disponible et ce quelqu'en soit la raison.
    CURLINFO_TOTAL_TIME Durée totale exprimée en secondes du précédent transfert (ceci inclue toutes les étapes de la connexion comme la résolution d'adresse).
    CURLINFO_NAMELOOKUP_TIME Temps (en secondes) mis depuis le début (de la fonction curl_exec) jusqu'à la résolution de nom.
    CURLINFO_CONNECT_TIME Temps mis en secondes depuis le début à l'établissement de la connexion avec l'hôte distant ou le proxy.
    CURLINFO_PRETRANSFER_TIME Délai (en secondes) séparant le début au début du transfert. Cette étape inclue l'envoi des pré-commandes comme le permet l'option CURLOPT_QUOTE, par exemple.
    CURLINFO_STARTTRANSFER_TIME Temps, en secondes, écoulé entre le début et l'envoi du premier octet du transfert.
    CURLINFO_REDIRECT_TIME Durée totale du transfert incluant les différentes redirections. La valeur sera nulle si la requête n'a fait l'objet d'aucune redirection.
    CURLINFO_REDIRECT_COUNT Nombre de redirections suivies.
    CURLINFO_SIZE_UPLOAD Nombre d'octets envoyés.
    CURLINFO_SIZE_DOWNLOAD Nombre d'octets reçus pour le dernier transfert.
    CURLINFO_SPEED_DOWNLOAD Vitesse de téléchargement moyenne mesurée en octets/seconde.
    CURLINFO_SPEED_UPLOAD Vitesse d'envoi moyenne exprimée en octets/seconde.
    CURLINFO_HEADER_SIZE En octets, taille totale de tous les en-têtes reçus.
    CURLINFO_REQUEST_SIZE Taille 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_VERIFYRESULT Résultat de la vérification de la certification demandée via l'option CURLOPT_SSL_VERIFYPEER.
    CURLINFO_CONTENT_LENGTH_DOWNLOAD Valeur lue et correspondant au champ Content-Length dans la réponse.
    CURLINFO_CONTENT_LENGTH_UPLOAD Taille spécifiée pour l'envoi (c'est à dire à la valeur de l'option CURLOPT_INFILESIZE).
    CURLINFO_CONTENT_TYPE La valeur de l'en-tête Content-Type telle qu'elle a été lue. Vous pouvez obtenir la valeur NULL si le protocole ne gère pas cette en-tête ou si le serveur en a envoyé une qui s'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
        '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 principales options 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 Description
CURLOPT_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 protocole employé.
CURLOPT_TIMEOUT Temps maximal d'exécution, exprimé en secondes, de la fonction curl_exec.
CURLOPT_CONNECTTIMEOUT Durée maximale de la tentative d'établissement de la connexion vers l'hôte distant (en secondes). Une valeur nulle aura pour effet de 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 Description
CURLOPT_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 type HEAD 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'inclure les en-têtes dans le résultat renvoyé. La valeur par défaut est FALSE.
CURLOPT_RETURNTRANSFER Avec 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 par défaut FALSE a pour effet d'en afficher directement la sortie.
CURLOPT_FILE Un descripteur de fichier (préalablement obtenu et ouvert avec fopen en mode écriture) dans lequel sera alors écrit les données renvoyées par le serveur distant. La valeur par défaut est la sortie standard 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 lecture par la fonction fopen, duquel les données pour l'upload seront lues.
CURLOPT_INFILESIZE Taille du fichier qui sera envoyé au serveur distant.

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

Nom Description
CURLOPT_HTTP_VERSION Forcer la version du protocole HTTP utilisée. La valeur par défaut est CURL_HTTP_VERSION_NONE, laissant ainsi le soin à cURL de décider sinon forcez la à l'aide de CURL_HTTP_VERSION_1_0 ou CURL_HTTP_VERSION_1_1 qui correspondent respectivement aux versions 1.0 et 1.1.
CURLOPT_FOLLOWLOCATION TRUE pour suivre (toutes) les redirections de type "Location:". On peut toutefois limiter le nombre de celles-ci avec l'option CURLOPT_MAXREDIRS.
CURLOPT_MAXREDIRS Spécifie le nombre maximum de redirections qui seront suivies avant de faire échouer la requête. Une valeur nulle implique aucune redirection 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ête par défaut.
CURLOPT_POST Définir cette option à la valeur TRUE aura pour effet d'employer la méthode POST à la place de la méthode GET par défaut.
CURLOPT_POSTFIELDS Les données à envoyer par la méthode POST sous la forme d'une chaîne (doivent être encodées) ou d'un tableau associant le nom du champ à sa valeur. Cette deuxième forme ne nécessite pas l'encodage des données car elle sera réalisée en interne et permet d'envoyer des fichiers en faisant précéder leur nom d'une arobase.
CURLOPT_USERPWD Permet de fournir un identifiant et un mot de passe pour passer les systèmes d'authentification HTTP. Ils prennent alors la forme login:mot_de_passe.
CURLOPT_USERAGENT Définit l'en-tête User-Agent (le navigateur) pour la requête HTTP.
CURLOPT_REFERER Renseigne l'en-tête Referer, la page d'où on provient en temps normal.
CURLOPT_AUTOREFERER Avec la valeur TRUE cURL renseignera automatiquement l'en-tête Referer lors de redirections.
CURLOPT_HTTPHEADER Ensemble d'en-têtes à présenter lors de la requête sous la forme d'un tableau numériquement indexé.
CURLOPT_COOKIEFILE Indique le fichier duquel seront lues les données relatives aux cookies.
CURLOPT_COOKIEJAR Fichier où seront écrites les données des différents cookies reçus.

Et enfin la gestion du protocole FTP :

Nom Description
CURLOPT_QUOTE Un tableau numériquement indexé des commandes FTP à exécuter avant notre requête.
CURLOPT_POSTQUOTE Les commandes FTP à exécuter après notre requête sous la forme d'un tableau numériquement indexé.
CURLOPT_TRANSFERTEXT Une 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 au sein de cURL.
CURLOPT_FTP_SSL
Permet de spécifier, à l'aide d'une des constantes ci-dessous, le niveau de sécurité des données qui vont transiter :
  • CURLFTPSSL_NONE : connexion FTP normale, aucun recours à SSL
  • CURLFTPSSL_TRY : tente d'utiliser SSL ou à défaut le protocole normal
  • CURLFTPSSL_CONTROL : SSL sera requis sur la connexion de contrôle sinon cURL échouera
  • CURLFTPSSL_ALL : SSL sera requis à la fois pour la connexion de contrôle ainsi que sur le canal de données
CURLOPT_FTPSSLAUTH
Dé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

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 HTTP correspondant. 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) pour assurer que le script nous rende, quoiqu'il arrive, rapidement la main ainsi que CURLOPT_NOBODY car le contenu de la 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 . ' : ' . (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 de caractères à des fins toutes aussi diverses comme par exemple pour en extraire certaines informations, constituer un cache, etc. Cette pratique est monnaie courante avec le protocole HTTP mais puisque nous utilisons cURL est aussi valable pour d'autres, citons par exemple FTP.

L'option cURL la plus importante ici est CURLOPT_RETURNTRANSFER. En effet, si celle-ci est omise ou n'est pas fixée à une valeur vraie, le contenu du fichier distant sera directement renvoyé au navigateur de votre visiteur or nous souhaitons 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 = 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.

info Pour des raisons légales, vous êtes fortement invités à prendre préalablement contact avec 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 la soumission d'un formulaire, l'une des méthodes consiste à regrouper l'ensemble de ces données sous la forme d'une chaî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 pour garantir 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 du protocole HTTP doivent être encodés. En PHP 5, la fonction http_build_query permet de gérer directement tous ces aspects, 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 4
if (!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) {
                    $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ères mais 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 interne par 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);

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 alors nécessaire d'établir une première connexion pour créer une session côté serveur afin de mémoriser cette identification et de pouvoir lire par la suite l'ensemble des données du site. Pour cela nous devons faire parvenir son identifiant au serveur pour ne plus avoir à repasser par la case authentification (sur un temps limité) et consulter directement les 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émentaires pour faire transiter l'identifiant de session à savoir : l'utilisation d'un cookie de session ou la réécriture des liens internes 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 recourir aux cookies et nous parserons le corps de la page à la recherche d'un tel identifiant. La première étape consiste donc à s'authentifier pour initialiser une session "valide" et de tenter de capturer cet identifiant de session, suivant la configuration 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 le permet 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'));
$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 par des redirections à effectuer côté client (balise meta, window.location.href). Ce problème ne se pose pas lorsqu'elles sont effectuées côté serveur grâce à l'en-tête "Location:".

info Pour en savoir plus sur les sessions php (utilisation comme configuration), je vous invite à consulter l'article éponyme : fr 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;
    }

    /**
     * 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