2010-03-02 7 views
9

Je tente de publier des données en utilisant fsockopen, puis en renvoyant le résultat. Voici mon code actuel:Post PHP données avec Fsockopen

<?php 
$data="stuff=hoorah\r\n"; 
$data=urlencode($data); 

$fp = fsockopen("www.website.com", 80, $errno, $errstr, 30); 
if (!$fp) { 
    echo "$errstr ($errno)<br />\n"; 
} else { 
    $out = "POST /script.php HTTP/1.0\r\n"; 
    $out .= "Host: www.webste.com\r\n"; 
    $out .= 'Content-Type: application/x-www-form-urlencoded\r\n'; 
    $out .= 'Content-Length: ' . strlen($data) . '\r\n\r\n'; 
    $out .= "Connection: Close\r\n\r\n"; 
    fwrite($fp, $out); 
    while (!feof($fp)) { 
     echo fgets($fp, 128); 
    } 
    fclose($fp); 
} 
?> 

Il est censé faire écho à la page, et il est faisant écho à la page, mais voici le script pour script.php

<?php 
echo "<br><br>";  
$raw_data = $GLOBALS['HTTP_RAW_POST_DATA']; 
parse_str($raw_data, $_POST); 

//test 1 
var_dump($raw_data); 
echo "<br><br>": 
//test 2 
print_r($_POST); 
?> 

Le résultat est:

HTTP/1.1 200 OK date: Mar 2 mars 2010 22:40:46 GMT serveur: Apache/2.2.3 (CentOS) X-Powered-By: PHP/5.2.6 Content-Length : 31 Connexion: fermer Content-Type: text/html; charset = chaîne UTF-8 (0) "" Array()

Que dois-je tort? Pourquoi la variable ne publie-t-elle pas ses données?

+1

Vous devriez utiliser curl. – rook

+0

Je ne peux pas utiliser curl car ce sera Open Source –

+1

"Curl est un logiciel libre et ouvert" Curl est sous licence MIT/X. – Xorlev

Répondre

1

À aucun moment $data n'est écrit dans le socket. Vous voulez ajouter quelque chose comme:

$out .= "Connection: Close\r\n\r\n"; 
fwrite($fp, $out); 
fwrite($fp, $data); 
+0

Je l'ai fait et toujours pas de cigare. –

1

Essayez cette place

$out .= 'Content-Length: ' . strlen($data) . '\r\n'; 
$out .= "Connection: Close\r\n\r\n"; 
$out .= $data; 
+0

Non, ne fonctionne pas, c'est parce que la connexion est fermée? –

+0

Nope, essayé Keep-alive, toujours rien. Seulement un tableau vide –

+0

Essayez d'installer un renifleur de paquets sur votre serveur et voyez quels en-têtes sont réellement envoyés au serveur. Sont-ils les mêmes que ce que vous envoyez en PHP? –

-2

utilise-t-cURL et option?

+2

non ce n'est pas, désolé. –

1

Essayez ceci:

<?php 
$data="stuff=hoorah\r\n"; 
$data=urlencode($data); 

$fp = fsockopen("www.website.com", 80, $errno, $errstr, 30); 
if (!$fp) { 
    echo "$errstr ($errno)<br />\n"; 
} else { 
    $out = "POST /script.php HTTP/1.0\r\n"; 
    $out .= "Host: www.webste.com\r\n"; 
    $out .= "Content-Type: application/x-www-form-urlencoded\r\n"; 
    $out .= 'Content-Length: ' . strlen($data) . "\r\n\r\n"; 
    $out .= "Connection: Close\r\n\r\n"; 
    fwrite($fp, $out); 
    fwrite($fp, $data); 
    while (!feof($fp)) { 
     echo fgets($fp, 128); 
    } 
    fclose($fp); 
} 
?> 

Certains caractère échappe, comme \n ne travaillent pas dans des guillemets simples.

16

Il y a beaucoup de petites erreurs dans votre code. Voici un extrait qui est testé et fonctionne.

<?php 

$fp = fsockopen('example.com', 80); 

$vars = array(
    'hello' => 'world' 
); 
$content = http_build_query($vars); 

fwrite($fp, "POST /reposter.php HTTP/1.1\r\n"); 
fwrite($fp, "Host: example.com\r\n"); 
fwrite($fp, "Content-Type: application/x-www-form-urlencoded\r\n"); 
fwrite($fp, "Content-Length: ".strlen($content)."\r\n"); 
fwrite($fp, "Connection: close\r\n"); 
fwrite($fp, "\r\n"); 

fwrite($fp, $content); 

header('Content-type: text/plain'); 
while (!feof($fp)) { 
    echo fgets($fp, 1024); 
} 

Et puis à example.com/reposter.php mettre ce

<?php print_r($_POST); 

Lorsqu'il est exécuté, vous devriez obtenir quelque chose de sortie comme

HTTP/1.1 200 OK 
Date: Wed, 05 Jan 2011 21:24:07 GMT 
Server: Apache 
X-Powered-By: PHP/5.2.9 
Vary: Host 
Content-Type: text/html 
Connection: close 

1f 
Array 
(
    [hello] => world 
) 
0 
+0

Pourquoi indique-t-il "1f" et "0" à la fin? Je reçois la même chose, mais pas tout à fait sûr. – carestad

+0

cela fonctionne mais vous devez changer dans fsockopen à fsockopen ('www.example.com', 80); et dans fwrite à fwrite ($ fp, "Host: www.example.com \ r \ n"); – Julian

0

Nice one Tamlyn, fonctionne très bien!

Pour ceux qui ont besoin aussi d'envoyer vars get avec l'url,

//change this: 

fwrite($fp, "POST /reposter.php HTTP/1.1\r\n"); 

//to: 

$query = 'a=1&b=2'; 
fwrite($fp, "POST /reposter.php?".$query." HTTP/1.1\r\n"); 
0

Essayez ceci dans reposter.php

$raw_data = $GLOBALS['HTTP_RAW_POST_DATA']; 
parse_str($raw_data, $_POST); 

print_r($_POST); 

Parce que, les données n'a pas été dans les $_POST[] variables, mais c'était dans la variable $GLOBALS['HTTP_RAW_POST_DATA'].

-1

Curl est trop lourd dans certains cas, d'utiliser post_to_host():

//GET: 
$str_rtn=post_to_host($str_url_target, array(), $arr_cookie, $str_url_referer, $ref_arr_head, 0); 

//POST: 
$arr_params=array('para1'=>'...', 'para2'=>'...'); 
$str_rtn=post_to_host($str_url_target, $arr_params, $arr_cookie, $str_url_referer, $ref_arr_head); 

//POST with file: 
$arr_params=array('para1'=>'...', 'FILE:para2'=>'/tmp/test.jpg', 'para3'=>'...'); 
$str_rtn=post_to_host($str_url_target, $arr_params, $arr_cookie, $str_url_referer, $ref_arr_head, 2); 

//raw POST: 
$tmp=array_search('uri', @array_flip(stream_get_meta_data($GLOBALS[mt_rand()]=tmpfile()))); 
$arr_params=array('para1'=>'...', 'para2'=>'...'); 
file_put_contents($tmp, json_encode($arr_params)); 
$arr_params=array($tmp); 
$str_rtn=post_to_host($str_url_target, $arr_params, $arr_cookie, $str_url_referer, $ref_arr_head, 3); 

//get cookie and merge cookies: 
$arr_new_cookie=get_cookies_from_heads($ref_arr_head)+$arr_old_cookie;//don't change the order 

//get redirect url: 
$str_url_redirect=get_from_heads($ref_arr_head, 'Location'); 

poste à l'hôte emplacement du projet php: http://code.google.com/p/post-to-host/

-2

Désolé pour rafraîchir, mais pour les gens qui ont encore des problèmes comme celui-ci , changez HTTP/1.0 en HTTP/1.1 et cela fonctionnera.

0

Vous pouvez utiliser cette technique pour appeler autant de pages que vous le souhaitez, toutes les pages pouvant être exécutées simultanément, sans attendre que chaque page soit asynchrone.

cornjobpage.php // mainpage

<?php 

post_async("http://localhost/projectname/testpage.php", "Keywordname=testValue"); 
//post_async("http://localhost/projectname/testpage.php", "Keywordname=testValue2"); 
//post_async("http://localhost/projectname/otherpage.php", "Keywordname=anyValue"); 
//call as many as pages you like all pages will run at once independently without waiting for each page response as asynchronous. 
      ?> 
      <?php 

      /* 
      * Executes a PHP page asynchronously so the current page does not have to wait for it to  finish running. 
      * 
      */ 
      function post_async($url,$params) 
      { 

       $post_string = $params; 

       $parts=parse_url($url); 

       $fp = fsockopen($parts['host'], 
        isset($parts['port'])?$parts['port']:80, 
        $errno, $errstr, 30); 

       $out = "POST ".$parts['path']."?$post_string"." HTTP/1.1\r\n";//you can use GET instead of POST if you like 
       $out.= "Host: ".$parts['host']."\r\n"; 
       $out.= "Content-Type: application/x-www-form-urlencoded\r\n"; 
       $out.= "Content-Length: ".strlen($post_string)."\r\n"; 
       $out.= "Connection: Close\r\n\r\n"; 
       fwrite($fp, $out); 
       fclose($fp); 
      } 
      ?> 

testpage.php

<? 
    echo $_REQUEST["Keywordname"];//case1 Output > testValue 
    ?> 

PS: si vous voulez envoyer des paramètres d'URL en boucle puis suivre cette réponse: https://stackoverflow.com/a/41225209/6295712