Auteur: Ludovic PATEY

Publié le 7 février 2008

Modifié le: 3 janvier 2010

Page d'accueil

Envoyer une requête POST par PHP

Vous êtes ici : Accueil / Articles / Formations en PHP

Zip - 18.2 ko
WebConversation 1.0
Zip - 1.3 ko
PostRequest 2.1

Tout développeur sait comment récupérer un formulaire POST envoyé par un internaute. Il suffit en effet de lire le tableau $_POST contenant les valeurs des champs du formulaire.

Cependant, il est également possible d’envoyer facilement des requêtes POST à d’autres serveurs, permettant notamment de récupérer des informations nécessitant une authentification. C’est ce que nous allons voir dans cet article.

Envoyer un formulaire avec file_get_contents()

La fonction file_get_contents() ouvre un fichier, le lit entièrement et retourne son contenu sous forme d’une chaine de caractères. Cependant, il accepte également des URL http en paramètre, ce qui permet d’envoyer des requêtes à des serveurs distants. Par défaut, la requête est de type GET :

<?php
// Envoi d'une requête de type GET à google
$page = file_get_contents( 'http://www.google.fr' );
?>

Il est cependant possible de modifier tous les paramètres de la requête et notamment son type. Nous allons pour cela créer un contexte de socket. En effet, file_get_contents() a recours aux sockets pour communiquer avec le serveur.

La création de contexte de socket s’effectue avec la fonction suivante : stream_context_create(). Elle prend en paramètres un tableau multidimensionnel spécifiant les différentes propriétés de l’environnement. La première dimension correspond au type de protocole. Exemple :

<?php
$options = array(

// Définition du contexte pour une requête FTP
'http' => array( ... ),

// Définition du contexte pour une requête HTTP
'ftp' => array( ... )

);

$contexte = stream_context_create( $options );
?>

La liste des protocoles supportés se trouve sur le site de PHP.net

Nous ne nous intéresserons qu’au protocole http.

Voici quelques options qu’il propose :

- method : permet de définir la méthode. Dans notre cas, nous la définirons à POST

- user_agent : il est conseillé de définir un agent officiellement reconnu au cas où le serveur effectue un filtre dessus.

Voici celui de Mozilla Firefox sous Windows XP :

Mozilla/5.0 (Windows ; U ; Windows NT 5.1 ; fr ; rv:1.8.1) Gecko/20061010 Firefox/2.0

- content : correspond au contenu dans le cas où la requête est de type POST. Sa valeur est une chaîne de caractères contenant les données brut. Il existe cependant la fonction http_build_query() qui accepte en paramètre un tableau de couples clé/valeur et retourne le contenu brut de la requête correspondante.

Exemple :

<?php
$donnees = array(
'login' => 'pateysoft',
'password' => 'xxxx' );

$contenu = http_build_query( $donnees );
?>

- headers : contient une chaine de caractère correspondant aux headers. Il n’existe malheureusement pas de fonction native PHP permettant de créer cette chaîne à partir d’un tableau, mais il est cependant très facile de la créer :

<?php
function http_build_headers( $headers ) {

       $headers_brut = '';

       foreach( $headers as $nom => $valeur ) {
               $headers_brut .= $nom . ': ' . $valeur . "\r\n";
       }

       return $headers_brut;
}
?>

Voici un exempe de headers à l’état brut :

Pragma : public Pragma : no-cache Expires : 0 Content-Type : text/html

Attention, parmi les headers, il va être nécessaire de préciser le Content-Length pour que le serveur sache lorsqu’il doit cesser d’attendre des données et commencer son traitement. Pour obtenir sa valeur, il suffit simplement de calculer la longueur de la chaîne spécifiée dans content avec la fonction strlen.

Exemple :

<?php
$donnees = array(
'login' => 'pateysoft',
'password' => 'xxxx' );

$contenu = http_build_query( $donnees );

$headers['Content-Length'] = strlen( $contenu );
?>

Parmi les autres headers indispensables, il y a le Content-Type qui doit être défini à application/x-www-form-urlencoded ou multipart/form-data, le second permettant d’envoyer des fichiers par le formulaire. Nous n’aborderons pas l’envoi des fichiers dans cet article.

Voyons donc maintenant une requête http résumant ce qui a été vu dans cette partie :

<?php
// Définition des champs du formulaire POST
$donnees = array(
'login' => 'pateysoft',
'password' => '******' );


// Définition de la fonction d'encodage des headers
function http_build_headers( $headers ) {

       $headers_brut = '';

       foreach( $headers as $nom => $valeur ) {
               $headers_brut .= $nom . ': ' . $valeur . "\r\n";
       }

       return $headers_brut;
}

// Création du contenu brut de la requête
$contenu = http_build_query( $donnees );

// Définition des headers
$headers = http_build_headers( array(
'Content-Type' => 'application/x-www-form-urlencoded',
'Content-Length' => strlen( $contenu) ) );

// Définition du contexte
$options = array( 'http' => array( 'user_agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1) Gecko/20061010 Firefox/2.0',
'method' => 'POST',
'content' => $contenu,
'header' => $headers ) );

// Création du contexte
$contexte = stream_context_create( $options );

// Envoi du formulaire POST
$retour = file_get_contents( 'http://www.monsite.com', false, $contexte );
?>

Envoyer un formulaire avec fopen()

Le code précédent s’avère utile lorsque les informations à recueillir se situent directement sur la page de traitement du formulaire. Cependant, dans beaucoup de cas, il est nécessaire de naviger dans le site après l’authentification par accéder à la page qui nous intéresse. L’authentification se fait souvent par le biais de sessions dont l’identifiant est stocké dans les cookies. Nous devons donc récupérer les cookies et les renvoyer à chaque appel pour que le serveur distant sache que nous sommes authentifiés. L’envoi des cookies s’effectue en les rajoutant dans le contexte de sockets. En revanche, il n’est pas possible de les récupérer avec un file_get_contents. Nous allons donc devoir descendre dans les couches et manipuler des flux pour pouvoir récupérer leur environnement. En effet, PHP met à notre disposition la fonction stream_get_meta_data() qui prend en paramètre un flux de données.

fopen() peut prendre en premier argument une URL, en second argument, le mode d’ouverture ( lecture, écriture, lecture/ecriture... ). Dans notre situation, nous ouvrirons le flux en lecture seule.

Cette fopen() fonctionne également avec les contextes et ce qui a été vu dans la partie précédente va donc être réutilisé ici.

Pour définir des cookies, nous allons ajouter un élément au sous-tableau http du contexte : cookie, prenant comme valeur une chaine brute. La syntaxe est de la forme nom1=valeur1 ;nom2=valeur2 ;...

Il existe une fonction PHP , http_build_cookie() permettant de générer la chaine à partir d’un tableau. Cependant, il est nécessaire d’installer PECL_HTTP pour l’utiliser. Voici une implémentation de cette fonction :

<?php
function http_build_cookie( $cookies ) {

       $retour = '';
       foreach( $cookies as $name => $value ) {
               $retour .= ' ' . $name . '=' . $value . ';';
       }

       return trim($retour);
}
?>

Et voici son ajout dans le contexte de flux :

<?php
$headers['cookie'] = http_build_cookie( $cookies );

$options = array( 'http' => http_build_headers($headers) );

$contexte = stream_context_create( $options );
?>

Voyons maintenant comment récupérer les cookies renvoyés par le serveur distant :

<?php
// $contexte correspond au contexte de flux
$fh = fopen( 'http://www.monsite.com', 'r', false, $contexte );

// Récupération des meta informations du flux
$meta = stream_get_meta_data( $fh );

// Récupération des headers sous forme de tableau
$headers= $meta['wrapper_data'];

// Récupération de la réponse du serveur
$retour= '';

while( !feof( $fh ) ) {
       $retour  .= fread( $fh, 1024 );
}

fclose( $fh );
?>

$headers contient donc un tableau de headers. Parmi eux se trouvent des headers Set-Cookie qui contient les cookies envoyés par le serveur. Chaque header de type Set-Cookie définit un et un seul cookie. Les informations sur le cookie sont variables : on peut ne spécifier que le couple clé/valeur, mais également le domaine, la date d’expiration... Nous n’avons pas besoin de faire une gestion très fine des cookies pour récupérer le cookie d’authentification.

Voici comment récupérer les cookies à partir du tableau de headers :

<?php
$cookies = array();

// Pour chaque header
foreach( $this->meta['wrapper_data'] as $data ) {

       // S'il s'agit d'un Set-Cookie
       if( preg_match( '/Set-Cookie: ([^=]+)=([^;]+)/', $data, $cookie ) ) {

               // Ajouter le cookie au tableau
               $cookies[ $cookie[1] ] = $cookie[2];
       }

}
?>

Le code précédent a recours aux expressions régulières. Celles-ci ne sont pas le sujet du cours. Sachez seulement que cette expression régulière a permi de tester le type de header et d’en extraire par la même occasion le nom et la valeur du cookie, les stockant dans la variable $cookie.

Nous avons donc tous les éléments pour interagir avec le serveur distant pendant la durée d’une session.

Gérer les sessions

Afin de gérer les sessions, il est utile de comprendre leur fonctionnement interne. Voici un article arbordant le sujet :

Les cookies et les sessions en PHP

Il existe beaucoup de tutoriels pour manipuler les cookies et les sessions en PHP. Cependant, les contraintes d’utilisation ont trop tendance à être imposées sans justification. Voici un tutoriel avec l’explication de leur gestion par PHP.

Pour ceux qui préfèrent aller à l’essentiel, sachez que les sessions sont stockées dans des fichiers dont le nom constitue l’id de session. Les id de session sont envoyés par défaut dans les headers sous forme de coockies par le serveur. Le client renvoie les coockies au serveur à chaque appel, ce qui permet au serveur de récupérer l’id de session, et donc de récupérer les données dans le fichier de session.

Il est donc nécessaire de faire manuellement ce que votre navigateur fait automatiquement : conserver les cookies et les renvoyer. Par défaut, le nom de cookie est PHPSESSID, mais il peut être changé.

Voici le code à utiliser :

<?php
require_once 'postrequest.class.php';

$request = new PostRequest( 'http://www.serveur.com/auth.php' );
$request->setData( 'login', 'my login' );
$request->setData( 'password', 'my password' );
$request->send();

$cookies = $request->getCookies();

// Affichage de l'id de session du serveur
echo $cookies['PHPSESSID'];

$request = new PostRequest( 'http://www.serveur.com/test.php' );
$request->setCookies( $cookies );

$page = $request->send();
?>

Gérer les fichiers

Envoyer des fichiers complique un peu la tâche. La syntaxe est un peu plus complexe.

Nous allons devoir utiliser une syntaxe multipart basée sur des séparateurs appelés boundary. Le boundary est une chaîne de caractères arbitraire que nous définirons dans l’exemple par U8sn1osj.

Il faut tout d’abord changer le Content-type global pour signifier que nous passons en multipart :

Content-type : multipart/form-data, boundary=U8sn1osj

La RFC décrivant le format à utiliser lors de l’upload de fichiers est disponible à l’url suivante :

http://www.faqs.org/rfcs/rfc1867.html

Nous n’entrerons pas plus loin dans les détails. La classe présentée ci-après gère les fichiers à l’aide de la méthode setFile :

<?php
$post->setFile( 'mon_fichier', 'file://my_file.txt', 'text/plain' );
?>

Complément

Voici une petite classe permettant d’envoyer des requêtes POST simplement :

Zip - 18.2 ko
WebConversation 1.0

Exemple

Un petit exemple vaut mieux qu’un long discours. Créez un fichier test.php et mettez-y le code suivant :

<?php
if( $_POST ) {
       print_r( $_POST );
       exit();
}

require_once 'Core/Request/Abstract.php';

require_once 'Core/Request/Post.php';
require_once 'Core/Request/Get.php';

require_once 'Core/Request/Conversation.php';


$conversation = new Core_Request_Conversation();
$pr =$conversation->newPost( 'http://127.0.0.1/test.php' );

$pr->setData( 'nom', 'Gates' );
$pr->setData( 'prenom', 'Bill' );

echo $pr->send();

print_r( $conversation->getCookies() );
?>

Le code précédent envoie un formulaire post à sa propre page.

Commentaires

David a dit le 23 mai 2008

C’est pas mal ça peut etre parfois utile. Mais pour ta classe tu l’as pas documenté ? Bon alors je met un exemple ça peut toujours etre utile à d’autre :) :



require(’postrequest.class.php’) ;

PostRequest pr = new PostRequest(’http://www.google.fr/’) ;



pr->setData(’SOCIETE’, $_POST[’SOCIETE’]) ;
pr->setData(’NOM_PRENOM’, $_POST[’NOM_PRENOM’]) ;
pr->setData(’CODE_POSTAL_VILLE’, $_POST[’CODE_POSTAL_VILLE’]) ;
pr->setData(’PAYS’, $_POST[’PAYS’]) ;
pr->setData(’E_MAIL’, $_POST[’E_MAIL’]) ;
pr->setData(’SITE_WEB’, $_POST[’SITE_WEB’]) ;
pr->setData(’TELEPHONE’, $_POST[’TELEPHONE’]) ;
pr->setData(’MESSAGE’, $_POST[’MESSAGE’]) ;



pr->setHeader(’Content-Type’, ’application/x-www-form-urlencoded’) ;



pr->send() ;



Ca c’est pour la base. Ta classe gere donc les cookies et permet aussi de construire un cookies ca celui qui s’y interesse trovuera.

David a dit le 23 mai 2008

arg désolé petite correction (pas de nom de classe au debut) et les variables php prennent un $. Peut etre pourras tu corriger mon post.
Puis les ligne ne vont pas à la ligne :s

Bishop a dit le 29 mai 2008

Merci énormément pour l’envoi de données POST en PHP, ça fait un moment que je cherche et cette méthode marche du tonnerre. Bonne continuation

Mike a dit le 4 juin 2008

(à priori, il y a un soucis avec le site... Je recommence !)



Salut,



J’ai un soucis en utilisant ta classe... J’ai créé deux pages :
1- test.php :



/*
* (c)
require(’../src/class/postrequest.class.php’) ;
$pr = new PostRequest(’http://localhost/pages/index.php’) ;

$pr->setData(’test’,’test’) ;
$pr->setData(’essai’,’essai’) ;
$pr->setHeader( ’Content-Type’, ’application/x-www-form-urlencoded’ ) ;
echo ’


’ ;
echo str_replace(’<’,’<’,$pr->send()) ;
echo ’
’ ;
*/

2- index.php :



Ceci est un test !!
/*
echo $_GET[’a’] ;
echo
’ESSAI : ’.$_POST[’essai’].
’ - TEST : ’.$_POST[’test’] ;
*/



En ouvrant la page : http://localhost/evalution/pages/essai.php, j’obtient :



Ceci est un test !!
ESSAI : - TEST : test



Alors que je m’attendais à avoir :



Ceci est un test !!
ESSAI : essai - TEST : test



Je ne trouve pas mon erreur.

Ludovic PATEY a dit le 4 juin 2008

Bonjour,
Ton code est théoriquement bon. Parmi les explications possibles, il y a toujours l’erreur de frappe.
Peux-tu effectuer un print_r( $_POST ) dans ton fichier index.php et me donner la valeur de retour ?
Sinon, donnes-moi une url où tu mettes tes sources disponibles.

Mike a dit le 5 juin 2008

Déja, merci pour ta réponse rapide :) et surtout ton code qui va m’aider si le problème est résolu !



En mettant le print_r j’obtient ceci :



Array
(
[test] => test
[amp ;essai] => essai
)
ESSAI : - TEST : test



Ceci signifie qu’il y a une info en trop... Pourquoi ?



En réflichissant un peu... En HTML & = & donc, il y a une fonction qui met un & à la place du & tout court. Cette fonction est



$contenu = http_build_query( $donnees ) ;



J’ai donc remplacé cette ligne par :



$content = ’’ ;
foreach( $this->data as $name => $value )
$content .= $name . ’=’ . $value . "&" ;



et ca marche !

Cyril a dit le 8 juillet 2008

Bonjour



j’ai essayé le code de Mike chez moi masi il me dit :



Warning : fopen(http://localhost/Serveur/test.php) [function.fopen] : failed to open stream : Une tentative de connexion a échoué car le parti connecté n’a pas répondu convenablement au-delà d’une certaine durée ou une connexion établie a échoué car l’hôte de connexion n’a pas répondu. in Z :\Projets\PlayerHub\site\Module_PlayerHUB\postrequest.class.php on line 65



je ne trouve pas pourquoi



j’utilise easyphp sur un windows vista
j’ai verifier php.ini et allow_url_fopen est bien on

Ludovic PATEY a dit le 12 juillet 2008

Bonjour Cyril,



J’avais effectivement été confronté à ce problème qui ne relève pas des formulaires POST, mais d’un fopen d’une adresse localhost. Ce problème n’a pas lieu avec un serveur distant. Je suppose qu’avec les url, le serveur PHP va interroger des serveurs dns distants sans passer par ton fichier hosts. Il n’arrive donc pas à résoudre le nom correctement.



Si tu veux néanmoins le tester en local, utilises l’url suivante :



http://127.0.0.1/Serveur/test.php

Cyril2 a dit le 17 juillet 2008

Bonjour,



J’utilise la classe postrequest avec succès mais un problème se pose pour moi. J’ai deux serveurs. Le serveur1 envoie un "send" au serveur 2 avec les données post d’identification, le serveur 2 répond favorablement en créant une nouvelle session. Le problème est que la session ne doit pas être créé pour le client mais pour le serveur1... Est-il possible de préciser dans l’envoi post pour résoudre ce problème ? dans le header ?



Merci

Ludovic PATEY a dit le 17 juillet 2008

Bonjour,
Afin de clarifier ma réponse, j’ai modifié l’article. Je t’invite donc à lire la partie "Gérer les sessions"

GuiGui a dit le 15 août 2008

Salut,
Tout d’abord, merci pour ta classe, c’était ce que je recherchais.
Mais dans ton article, tu ne traites pas de l’envoi de fichiers en POST.
Est-ce compliqué à mettre en œuvre ?

Ludovic PATEY a dit le 16 août 2008

Envoyer des fichiers en POST est effectivement un peu plus compliqué à mettre en œuvre. C’est cependant tout à fait faisable. Il faut pour cela

- Remplacer le Content-type donné précédemment par
Content-type : multipart/form-data, boundary=tonboundary

- Modifier la partie d’encodage des données pour séparer le contenu par les boundaries. Voici un exemple de ce que cela peut donner :
http://www.php.net/manual/fr/function.fsockopen.php#30796
Si j’ai le temps, je modifierai ma classe en conséquence pour ajouter une méthode addFile. Un autre post de ma part annoncera sa mise à jour.

Ludovic PATEY a dit le 16 août 2008

La classe est mise à jour et gère désormais les fichiers avec la méthode
$post->setFile( nom, chemin, type mime ) ;

Grabriel a dit le 11 septembre 2008

Bonjour,



J’ai une url https que faut-il modifier pour que ca fonctionne ?



J’ai ce message d’erreur :
Warning : fopen(https://www.gnagnagna.com/secure/script.aspx) [function.fopen] : failed to open stream : Invalid argument in D :\postrequest.class.php on line 85



Merci

Ludovic PATEY a dit le 11 septembre 2008

Bonjour,
Afin que php supporte le protocole SSL, il convient d’installer openssl.
http://fr3.php.net/openssl

Grabriel a dit le 12 septembre 2008

Yep !!



Ca marche nickel merci beaucoup !!!

GagneTaWii.com a dit le 20 septembre 2008

Bonjour,



Je n’arrives pas à utiliser correctement la classe.
J’obtiens l’erreur :
Parse error : syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or ’’ in xxx/xxx/xxx/xxx/postrequest.class.php on line 17



Or je ne m’y connais pas trop en classes je ne peux pas la corriger.
Voici le passage ou sa bugge :
class PostRequest



private $url ;
private $cookies = array() ;
private $meta = array() ;
private $data = array() ;
private $files = array() ;
private $headers = array() ;
private $boundary ;



Si quelqu’un avait l’ancienne version ou pourrait m’aider a corriger celle-ci sa serait génial.



Merci d’avance pour votre aide.

Ludovic PATEY a dit le 20 septembre 2008

Bonjour, cette classe est codée en PHP 5, et le mot-clé private n’existe pas en PHP4, d’où votre message d’erreur. Sachant que PHP 6 va bientôt sortir et que la version 4 cessera d’être maintenue, il serait temps de passer à la version 5.



Si cependant vous cherchez à rester compatible PHP 4, il suffit de remplacer les "private" des propriétés par des "var", et en ce qui concerne les fonctions, supprimez les modificateurs "private, protected, public". Il faut également renommer le constructeur __construct en "PostRequest". En effet, en PHP 4, le constructeur porte le nom de la classe.



Ainsi,
private $url ;
private $cookies = array() ;
private $meta = array() ;
private $data = array() ;
private $files = array() ;
private $headers = array() ;
private $boundary ;



devient



var $url ;
var $cookies = array() ;
var $meta = array() ;
var $data = array() ;
var $files = array() ;
var $headers = array() ;
var $boundary ;



public function __construct( $url ) devient function PostRequest( $url )

Christophe a dit le 13 mai 2009

Bonjour,



J’ai utilisé votre exemple pour me connecter à une page PHP et à afficher la page sécurisée. Mais lorsque je fais cela, il ne m’affiche que la page d’authentification, comme si la connexion n’avait pas marché.



Voici le code :



$request = new PostRequest( ’http://monsite.fr/signin.php’ ) ;
$request->setData( ’clientid’, ’1234’ ) ;
$request->setData( ’username’, ’1234’ ) ;
$request->setData( ’password’, ’1234’ ) ;
$request->send() ;



$cookies = $request->getCookies() ;



// Affichage de l’id de session du serveur
echo $cookies[’PHPSESSID’] ;



$request = new PostRequest( ’http://81.91.219.67:8787/monitoring/index.php ?p=ecommsmanagement’ ) ;
$request->setCookies( $cookies ) ;



$page = $request->send() ;



echo $page ;



De plus, l’id de session est toujours différente, comme s’il m’en attribuait un à chaque fois. Cela me semble louche mais je ne voie pas comment régler mon problème.



Merci d’avance.

Ludovic PATEY a dit le 20 mai 2009

Bonjour,
Désolé du délai, pour des raisons inconnues, je n’étais plus avertis de l’arrivée de nouveaux posts.



Il est tout à fait normal que l’ID de session change à chaque fois :
Lorsque vous appelez pour la première fois la requête, vous ne lui transmettez pas de cookies, donc votre serveur distant ne peut pas savoir qu’il s’agit de la même personne et crée une nouvelle session.
La solution serait d’utiliser la syntaxe suivante pour le script local :

<?php

session_start();



$request = new PostRequest( ?http://monsite.fr/signin.php? ) ;

$request->setCookies( @$_SESSION['cookies'] );

$request->setData( ?clientid?, ?1234? ) ;

$request->setData( ?username?, ?1234? ) ;

$request->setData( ?password?, ?1234? ) ;

$request->send() ;

$_SESSION['cookies'] = $request->getCookies();

?>


En ce qui concerne votre second problème, essayez de mettre dans votre page signin.php



print_r( $_POST ) ;



et d’afficher le retour de send. Vous verrez si le formulaire est bien transmis.

EP Factory a dit le 23 juin 2009

Bonjour,
J’ai tenté d’utiliser cette classe, mais en vain. je bloque sur l’accès au cookie. Je met en place une solution paypal pour un site, et je souhaite envoyer un formulaire en post afin de récupérer certains paramètres de la transaction effectuée quelques secondes auparavant.



Voici un petit résumé :



1- l’utilisateur va sur paypal, se connecte et paye
2- l’utilisateur est redirigé vers le site où il voit une confirmation de réception de commande
3- lors de cette redirection, je souhaite récupérer les informations de commande, depuis une fonctionnalité paypal : https://www.paypal-france.fr/webscr/fr_FR/html/Espace-Integration-PayPal/ic_pdt.html



Mon problème est le suivant : en envoyant le formulaire (via ta classe) vers la page paypal, il me relance la page d’authentification. je n’arrive pas à récupérer le cookie paypal.



Voici mon code :
private function sendPaypalForm($website, $params = array())

$pr = new PostRequest($website) ;
foreach($params as $key => $value) $pr->setData($key, $value) ;
$pr->setCookies(@$_SESSION[’cookies’]) ;
$toto = $pr->send() ;
$_SESSION[’cookies’] = $pr->getCookies() ;



Merci d’avance



Cordialement



Vincent
vincent@epfactory.com

Ludovic PATEY a dit le 23 juin 2009

Bonjour,
Votre code semble bon à première vue.

- Avez-vous bien fait un session_start() ?

- Pouvez-vous faire print_r( $pr->getCookies() ) ; avant $_SESSION[’cookies’] = $pr->getCookies() ; ?
Cordialement,
Ludovic

Snake_27 a dit le 24 juin 2009

Bonsoir,



J’ai essayé de comprendre un maximum la structure et une fois ceci fait, j’ai essayé bêtement le code d’exemple donné par David.
Sur Google.fr, cela me donne une série d’erreurs :



Warning : fopen(http://www.google.fr/) [function.fopen] : failed to open stream : HTTP request failed ! HTTP/1.0 405 Method Not Allowed in /var/www/posts/postrequest.class.php on line 85



Warning : stream_get_meta_data() : supplied argument is not a valid stream resource in /var/www/posts/postrequest.class.php on line 87



Warning : Invalid argument supplied for foreach() in /var/www/posts/postrequest.class.php on line 91



Warning : feof() : supplied argument is not a valid stream resource in /var/www/posts/postrequest.class.php on line 102



Warning : fread() : supplied argument is not a valid stream resource in /var/www/posts/postrequest.class.php on line 103



Les deux dernières citées reviennent en boucle. Si j’essaye sur un serveur distant m’appartenant sur lequel j’ai mis un fichier contenant print_r($_POST), le array est vide (je fais un echo du file_get_contents de ce fichier dans le fichier où j’exécute la structure).



J’obtiens comme un bug d’encodage (bien que ça ne soit pas ça) au début du script d’ailleurs. " ï »¿ "



Merci d’avance de votre aide. :)
Bonne fin de soirée.

Ludovic PATEY a dit le 24 juin 2009

Bonjour,
C’est normal : google refuse les requêtes POST. Je viens de mettre à jour l’exemple. En ce qui concerne le bug d’encodage, c’est parce que votre page web est en iso tandis que la classe PostRequest.class.php est en UTF8 avec BOM.
Une nouvelle version de la classe est disponible, corrigeant le problème d’encodage.

Snake_27 a dit le 24 juin 2009

Bonjour,



J’avais pourtant modifié l’encodage dans une meta mais ça ne marchait pas. =/



Bref, cela marche maintenant, mais uniquement le print_r($_POST) ; de la page retourne les données. Ce que j’aimerai faire, c’est afficher un file_get_contents qui retourne les données POST.



En dehors de cela, est-ce que vous ne connaitriez pas par hasard des fonctions utiles pour "naviguer" dans un file_get_contents ? (un code source au format texte en fait). Car moi j’y vais à grand coup d’explose, de preg_replace et de str_replace si besoin. (Ceci étant dans le but d’afficher des informations contenues sur des pages distantes)



Merci d’avance.

Ludovic PATEY a dit le 24 juin 2009

"Ce que j’aimerai faire, c’est afficher un file_get_contents qui retourne les données POST." Cette phrase n’a aucun sens, donc je ne peux vous être d’aucun secours si vous ne l’explicitez pas.
En ce qui concerne votre second problème, je crois comprendre que vous voulez extraire les informations d’une page html. Théoriquement, si le code source est xml valide, alors il doit être possible d’accéder au contenu par DOMDocument. Cependant, comme c’est rarement le cas, il vaut mieux utiliser preg_match ( et non preg_replace ).

Snake_27 a dit le 25 juin 2009

Est-il possible de faire une "sélection" avec preg_match et non une recherche ? (j’ai cherché dans la doc des fonctions adéquats mais sans vraiment de succès).



En ce qui concerne le file_get_contents "retournant les données post", ce n’est pas bien compliqué en soit. Le fichier distant que j’analyse avec file_get_contents contient un print_r($_POST) ; j’aimerai envoyer des données POST à ce serveur distant pour que celui-ci me réponde autre chose que "Array ( )" (données POST inéxistantes).
Je voudrais afficher le contenu d’une page qui dépend des données POST qu’on lui envoie.

Ludovic PATEY a dit le 25 juin 2009

Alors concernant l’affichage du contenu d’une page qui dépend des données POST qu’il envoie, il suffit que tu remplaces le print_r( $_POST ) par du html et des echo de tes variables POST.
Les fonctions preg_match et preg_match_all effectuent une recherche et stockent le résultat de la recherche dans un tableau multidimensionnel. Tu peux donc ensuite récupérer ce que tu as trouvé pour effectuer des traitements dessus. Si ce n’est pas ce que tu veux, il faut que tu précises le sens du mot "sélection". Je l’entendais dans le sens "extraction de données"

Snake_27 a dit le 25 juin 2009

Ah cela marche maintenant. Merci beaucoup de m’avoir aidé ! =)

EP Factory a dit le 25 juin 2009

Bonjour,



Suite à votre message du 23 juin, je vous confirme que la session a bien été démarrée. Pour ce site en cours, j’utilise le framework symfony 1.2.
voici le résultat du print_r($pr->getCookies()), effectué après le $pr->send() et avant le $_SESSION[’cookies’] = $pr->getCookies() :



Array ( [c9MWDuvPtT9GIMyPc3jwol1VSlO] => %7clPIAS1_p_97RVNVdcY1jjPSOgkRR8AK9G4shLLb1PzXIZDS2VbJoA8tI066kxvMMjImUgG%7cbbJ3nmVrjUqmBD7NS4pNA4nTdzHB5DX4wnq3QMdSpVqIMnEFGCgmD0dNGZTua5BA9b5UJ0%7c [-1ILhdyICORs4hS4xTUr41S8iP0] => WxvunzGxD141M-khpW_Q099UMYlk-rI0prJAnHmPr8ioqRG0sfuok24-brwfUzgzl0-WEHidqsWnuJ4r [cookie_check] => yes [navcmd] => p%2fwel%2fsandbox-outside [navlns] => 0 [Apache] => 10.191.196.11.203671245932298377 )



Merci pour vos réponses
Cordialement



Vincent
vincent@epfactory.com
http://www.epfactory.com

Ludovic PATEY a dit le 25 juin 2009

A prioris, ce n’est pas un problème de cookies : l’intérêt des cookies est uniquement de pouvoir conserver les infos de session entre 2 appels, or vous n’en faites qu’un : l’envoi du formulaire post contenant les informations d’authentification, et $toto est sensé récupérer le contenu de la page ( si j’ai bien compris ). Par conséquent, le problème relève plutôt de setData. Si cela vous réaffiche le formulaire, il doit y avoir probablement en plus un message d’erreur. Il faudrait donc regarder le message accompagnant le formulaire contenu dans $toto.

Acropole a dit le 25 juin 2009

Bonjour,



J’ai un problème avec la classe PostRequest. J’ai créé deux fichiers :
index.php :
require_once( ’postrequest.class.php’ ) ;
$pr = new PostRequest (’http://nomdusite.free.fr/test.php’) ;
$pr->setData( ’page’, ’13’ ) ;
$pr->setHeader( ’Content-Type’, ’application/x-www-form-urlencoded’ ) ;
echo $pr->send() ;



et test.php :
print_r( $_POST ) ;



Et voici ce qui est affiché quand j’exécute index.php :
Warning : preg_match() expects parameter 2 to be string, array given in /postrequest.class.php on line 92
Warning : preg_match() expects parameter 2 to be string, resource given in /postrequest.class.php on line 92
Array ( )



En commentant la boucle foreach contenant preg_match(), la variable $_POST est toujours vide. Je ne comprends pas pourquoi cela ne marche pas. Pouvez-vous m’aider ?



PS : désolé pour le message précédent, j’avais laissé les balises php.

Ludovic PATEY a dit le 25 juin 2009

Bonjour,
votre message d’erreur vient d’un bug de php dû à votre version :
http://aspn.activestate.com/ASPN/Mail/Message/php-dev/3685132
Je vais uploader dans la soirée une nouvelle classe qui contourne le bug.

pronet88 a dit le 29 juin 2009

J’ai de solides bases en PHP mais rien de plus, ce qui fait que ce code n’est pas tout à fait à ma porté. Cela dit j’arrive a peu près a comprendre, mais je n’arrive pas a faire fonctionner l’envoi de formulaire avec la récupération de cookie et la conservation ce celui ci. Si quelqu’un l’a déjà fait, pourrait-il m’envoyer son code en exemple.(par mail a pronet88@aol.com)
Merci d’avance.

claude a dit le 17 novembre 2009

La classe webconversation est très bien, mais de mon coté, cela ne récupère aucun COOKIES !



Je n’ai pas trouvé sinon postrequest.class.php, ou peux on la télécharger ?
merci

Ludovic PATEY a dit le 18 novembre 2009

Je viens de rajouter la classe postrequest.class.php en haut de l’article.
Sinon, pour webconversation, allez dans le fichier Abstract.php et ajoutez
print_r($headers) ; à la ligne 73, c’est à dire juste avant le foreach( $headers as $data).
Postez ce que cela retourne, et je pourrai vous aider à débugger votre programme.

benj a dit le 19 décembre 2009

Bonjour
La bibliothèque CURL http://fr.php.net/manual/fr/intro.curl.php ne fait elle pas la même chose ?

Ludovic PATEY a dit le 19 décembre 2009

La fonction file_get_contents utilise par derrière la librairie curl qui est de plus bas niveau.

benj a dit le 21 décembre 2009

merci pour l’info

Amnell a dit le 2 janvier 2010

<< "s" en trop.
Je n’ai pas eu le temps de tout lire mais l’article semble intéressant.">Légère faute d’orthographe au début : "Elle prends" << "s" en trop.
Je n’ai pas eu le temps de tout lire mais l’article semble intéressant.

Ben a dit le 26 janvier 2010

J’aimerais pouvoir lire le contenu de la page html ouverte par fopen pour executer une epression reguliere dessus



Merci

Ben a dit le 26 janvier 2010

J’ai trouvé il suffisait de recuperer le resultat de send()

Patrice a dit le 8 février 2010

Une fois que je suis connecté ( car il y avait un username et password) comment faire pour faire une recherche dans un formulaire toujours en utilisant les classes de WebConversation



Merci

Ludovic PATEY a dit le 8 février 2010

Bonjour,
Cela dépend de ce que vous appelez "faire une recherche dans un formulaire" :

- s’il s’agit d’extraire des données du code html, je vous conseille d’utiliser des expression régulières

- s’il s’agit d’entrer des données dans un formulaire pour faire une recherche, il faut regarder le code html pour identifier les champs à remplir, et utiliser exactement le même principe que ce que vous avez fait pour vous authentifier, c’est à dire faire un setData( cle, valeur ) pour chaque champ.

Auteur :

Message :


Warning: Wrong parameter count for join() in /home/ludovic/public_html/pateysoft/plugins/spipBB/genie/statvisites.php on line 37

Warning: Wrong parameter count for join() in /home/ludovic/public_html/pateysoft/plugins/spipBB/genie/statvisites.php on line 49

Fatal error: Call to undefined function spip_unlink() in /home/ludovic/public_html/pateysoft/plugins/spipBB/genie/statvisites.php on line 73