PHP Post data with Fsockopen

2020-01-28 08:32发布

问题:

I am attempting to post data using fsockopen, and then returning the result. Here is my current code:

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

It is supposed to echo the page, and it is echoing the page, but here is the script for 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 );  
?>

The outcome is:

HTTP/1.1 200 OK Date: Tue, 02 Mar 2010 22:40:46 GMT Server: Apache/2.2.3 (CentOS) X-Powered-By: PHP/5.2.6 Content-Length: 31 Connection: close Content-Type: text/html; charset=UTF-8 string(0) "" Array ( )

What do I have wrong? Why isn't the variable posting its data?

回答1:

There are many small errors in your code. Here's a snippet which is tested and works.

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

And then at example.com/reposter.php put this

<?php print_r($_POST);

When run you should get output something like

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


回答2:

At no point is $data being written to the socket. You want to add something like:

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


回答3:

Try this instead

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


回答4:

Try this:

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

Some character escapes such as \n do not work in single quotes.



回答5:

Nice one Tamlyn, works great!

For those that also need to send get vars along with the 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");


回答6:

Try this in reposter.php

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

print_r( $_POST );

Because, the data wasn't in the $_POST[] variables but it was in the $GLOBALS['HTTP_RAW_POST_DATA'] variable.



回答7:

you can use this technique it will help to call as many as pages you like all pages will run at once independently without waiting for each page response as asynchronous.

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:if you want to send url parameters as loop then follow this answer :https://stackoverflow.com/a/41225209/6295712



回答8:

Curl is too heavy in some case, to use 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 to host php project location: http://code.google.com/p/post-to-host/



回答9:

Is using cURL and option?



回答10:

Sorry for refresh, but for people who still have problem like this, change HTTP/1.0 to HTTP/1.1 and it will work.