2010-03-02 15 views
9

Sto tentando di pubblicare dati utilizzando fsockopen e quindi restituire il risultato. Qui è il mio codice corrente:Dati post PHP con 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); 
} 
?> 

Si suppone che l'eco della pagina, ed è facendo eco alla pagina, ma qui è la sceneggiatura di 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); 
?> 

Il risultato è:

HTTP/1.1 200 OK Data: martedì, 2 marzo 2010 22:40:46 GMT Server: Apache/2.2.3 (CentOS) X-Powered-By: PHP/5.2.6 Content-Length : 31 Connessione: close Content-Type: text/html; charset = UTF-8 string (0) "" Array()

Cosa ho sbagliato? Perché la variabile non pubblica i suoi dati?

+1

Dovresti usare arricciatura. – rook

+0

Non posso usare arricciatura perché questo sarà Open Source –

+1

"Curl è software libero e aperto" Curl è concesso in licenza con la licenza MIT/X. – Xorlev

risposta

1

In nessun momento $data viene scritto nella presa. Si desidera aggiungere qualcosa di simile:

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

L'ho fatto e ancora nessun sigaro. –

1

Prova a modificare la

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

No, non funziona, lo è perché la connessione è stata chiusa? –

+0

No, ho provato a mantenere vivo, ancora niente. Solo un array vuoto –

+0

Provare a installare uno sniffer di pacchetti sul server e vedere quali intestazioni vengono effettivamente inviate al server. Sono uguali a quelli che stai inviando in PHP? –

-2

Sta usando cURL e l'opzione?

+2

no non lo è, mi dispiace. –

1

Prova questo:

<?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); 
} 
?> 

Alcuni personaggio sfugge come \n non funzionano tra apici.

16

Ci sono molti piccoli errori nel codice. Ecco uno snippet che è testato e funziona.

<?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); 
} 

E poi alla example.com/reposter.php mettere questo

<?php print_r($_POST); 

Quando viene eseguito si dovrebbe ottenere qualcosa di simile uscita

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

Perché mostra "1f" e "0" alla fine lì? Prendo lo stesso, ma non del tutto sicuro. – carestad

+0

funziona ma devi cambiare in fsockopen a fsockopen ('www.example.com', 80); e in fwrite to fwrite ($ fp, "Host: www.example.com \ r \ n"); – Julian

0

Nice one Tamlyn, funziona benissimo!

Per coloro che hanno bisogno anche di inviare get vars insieme con 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

Prova questo in reposter.php

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

print_r($_POST); 

causa, i dati non era nelle variabili $_POST[] ma era nella variabile $GLOBALS['HTTP_RAW_POST_DATA'].

-1

Curl è troppo pesante in alcuni casi, per usare 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'); 

post per ospitare posizione progetto PHP: http://code.google.com/p/post-to-host/

-2

Ci scusiamo per l'aggiornamento, ma per le persone che hanno ancora problema come questo , cambia HTTP/1.0 in HTTP/1.1 e funzionerà.

0

è possibile utilizzare questa tecnica che aiuterà a richiamare tutte le pagine a cui piacciono tutte le pagine verranno eseguite contemporaneamente in modo indipendente senza attendere ogni risposta di pagina come asincrona.

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: se si desidera inviare parametri URL come anello poi seguire questa risposta: https://stackoverflow.com/a/41225209/6295712