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 :
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 :
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 :
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
(
'url' => 'http://www.developpez.com/',
'content_type' => 'text/html',
'http_code' => 200,
'header_size' => 145,
'request_size' => 58,
'filetime' => -1,
'ssl_verify_result' => 0,
'redirect_count' => 0,
'total_time' => 0.125,
'namelookup_time' => 0,
'connect_time' => 0.052,
'pretransfer_time' => 0.052,
'size_upload' => 0,
'size_download' => 0,
'speed_download' => 0,
'speed_upload' => 0,
'download_content_length' => 0,
'upload_content_length' => 0,
'starttransfer_time' => 0.124,
'redirect_time' => 0
)
|
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);
}
if (!curl_exec($ch)) {
return FALSE;
}
$ret = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return in_array($ret, array(200, 301, 302));
}
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;
}
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.
 |
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¶m2=valeur2&...¶mN=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 :
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);
}
}
$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) :
$post = array(
'description' => "Photo n°1 de mon week-end en Bretagne.\r\nPique-nique dans la forêt de Broceliande.",
'photo' => '@' . realpath('P1010001.JPG')
);
$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 = '';
$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*/?>
$sid = '?' . $m[1] . '=' . $m[2];
}
$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:".
 |
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
{
protected $_post;
protected $_options;
protected $_ch;
@param
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();
}
$ojet->CURLOPT_X
@param
@returnNULL
public function __get($nom)
{
$resultat = NULL;
if (defined($nom)) {
$valeur = constant($nom);
if (isset($this->_options[$valeur])) {
$resultat = $this->_options[$valeur];
}
}
return $resultat;
}
$objet->CURLOPT_X
@param
@param
|