PHP 使用 Fsockopen 发布数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2367458/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 06:12:20  来源:igfitidea点击:

PHP Post data with Fsockopen

phpsocketsfsockopen

提问by Joseph Robidoux

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

我正在尝试使用 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);
}
?> 

It is supposed to echo the page, and it is echoing the page, but here is the script for script.php

它应该回显页面,它正在回显页面,但这里是 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 ( )

HTTP/1.1 200 OK 日期:2010 年 3 月 2 日星期二 22:40:46 GMT 服务器:Apache/2.2.3 (CentOS) X-Powered-By:PHP/5.2.6 Content-Length:31 连接:close Content-Type :文本/html;charset=UTF-8 string(0) "" 数组 ( )

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

我有什么问题?为什么变量不发布其数据?

回答by Tamlyn

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

然后在example.com/reposter.php把这个

<?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

回答by Rob

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

任何时候都$data没有写入套接字。您想添加如下内容:

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

回答by Ben Rowe

Try this instead

试试这个

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

回答by Nick Whaley

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 \ndo not work in single quotes.

某些字符转义,例如\n在单引号中不起作用。

回答by Hassan Saeed

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

cornjobpage.php //主页

    <?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

PS:如果您想将 url 参数作为循环发送,请按照以下答案进行操作:https: //stackoverflow.com/a/41225209/6295712

回答by MisterM

Nice one Tamlyn, works great!

不错的一个 Tamlyn,效果很好!

For those that also need to send get vars along with the url,

对于那些还需要随 url 一起发送 get vars 的人,

//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");

回答by chandoo

Try this in reposter.php

在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.

因为,数据不在$_POST[]变量中,而是在$GLOBALS['HTTP_RAW_POST_DATA']变量中。

回答by diyism

Curl is too heavy in some case, to use post_to_host():

在某些情况下,Curl 太重,无法使用 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/

发布到托管 php 项目位置:http: //code.google.com/p/post-to-host/

回答by Piotr

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

抱歉刷新,但对于仍然有这样问题的人,将 HTTP/1.0 更改为 HTTP/1.1 它将起作用。

回答by code_burgar

Is using cURLand option?

是否使用cURL和选项?