Chinaunix

标题: [分享]POST的原始数据获得方法 [打印本页]

作者: 别爱我我没钱    时间: 2007-12-22 17:49
标题: [分享]POST的原始数据获得方法
XX软件,去联接hxxp://www.test.com:80
当通信联接好后这个XX软件就发送一段序列比如:abc123
然后php运算后,反回一段111aaa字符给这个软件,最后软件运行相应的功能。

如果这个XX软件发送123456,php运算后就返回abcdef


这样的php应该怎么写呢?


我试着用$_GET,这个变量,可是捕捉不到 这个XX软件发送的序列!

还请GGJJ不吝赐教!

[ 本帖最后由 别爱我我没钱 于 2007-12-23 18:23 编辑 ]
作者: 别爱我我没钱    时间: 2007-12-23 09:41
或者在google上搜什么样的关键字呢?
我搜了半天php第一次会话,可还是没有找到相关的内容!!
作者: achieverain    时间: 2007-12-23 09:53
软件端执行命令类似于  "get www.xxx.com:80/test.php?action=edit&aid=123"

php程序做出响应的代码为

<?php

if ($_GET['action'] == 'edit')
{
      echo "edit!!!!";
}
if($_GET['aid'] > 0)
{
      echo 'aid ok!';
}
?>
作者: achieverain    时间: 2007-12-23 10:06
我最近也在做程序端和php交互的工作. 你注意一下,如果客户端发送的http请求不规范,php可能会忽略发送的信息. 这个时候用 $_SERVER 看不到客户端发送的信息
作者: 别爱我我没钱    时间: 2007-12-23 16:46
也就是说,基本上$GLOBALS['HTTP_RAW_POST_DATA'] 和 $_POST是一样的。但是如果post过来的数据不是PHP能够识别的,你可以用 $GLOBALS['HTTP_RAW_POST_DATA']来接收,比如 text/xml 或者 soap 等等。

--------------------------------------------------------------------------------
补充说明一下。PHP默认识别的数据类型是application/x-www.form-urlencoded标准的数据类型。
作者: achieverain    时间: 2007-12-23 17:20
Errrrrrrrr

我这里客户端post信息不规范用 $GLOBALS 或者 $_SERVER 都看不见........ 最后抓了本地表单的包仿写了一个才解决
作者: 别爱我我没钱    时间: 2007-12-23 18:22
谢谢你的参于,我的问题已经自己解决方法如下:
file_get_contents("php://input");
用这个可以直接得到POST过来的最原始数据

$key=file_get_contents("php://input");
把这个原始数据传给key

这样就可以使用$key来处理这个原始数据了!!!
作者: 别爱我我没钱    时间: 2007-12-23 18:42
原帖由 achieverain 于 2007-12-23 17:20 发表
Errrrrrrrr

我这里客户端post信息不规范用 $GLOBALS 或者 $_SERVER 都看不见........ 最后抓了本地表单的包仿写了一个才解决

如何仿写的呢,说来听听!!
把过程写一下,这样不更好!!
作者: achieverain    时间: 2007-12-23 22:27
以下是从同事那里抢的c++ 代码
   SetRequestLine(_T("POST"), _T("http://192.168.1.101/post.php"), _T("HTTP/1.1"));
    SetRequestHeader(_T("Accept"), _T("*/*"));
    SetRequestHeader(_T("Accept-Encoding"), _T("gzip, deflate"));
    SetRequestHeader(_T("Accept-Language"), _T("zh-cn"));
    SetRequestHeader(_T("Content-Type"), _T("application/x-www-form-urlencoded"));
    SetRequestHeader(_T("Cache-Control"), _T("no-cache"));
    SetRequestHeader(_T("Content-Length"), CA2T(os.str().c_str()));
    SetRequestHeader(_T("Connection"), _T("close"));
    SetRequestHeader(_T("User-Agent"), _T("Mozilla/4.0 (compatible;\
                                          MSIE 7.0; Windows NT 5.1;\
                                          POTU(RR:27082316:0:5104704);\
                                          .NET CLR 1.1.4322; .NET CLR 2.0.50727;\
                                          .NET CLR 3.0.04506.30)"));


没有想到用 php://input  一直用的$_POST

[[i] 本帖最后由 achieverain 于 2007-12-23 22:28 编辑 [/i]]
作者: 别爱我我没钱    时间: 2007-12-24 08:49
没有想到用 php://input  一直用的$_POST




$_POST也会有一些过滤,但具体怎么过滤,我就不知道,我也只是因为这个问题才刚接触php

非常谢谢你能这么积极讨论这个贴子,非常让我感动!!!
你一定是一个好人,赞一个:wink:

[ 本帖最后由 别爱我我没钱 于 2007-12-24 08:53 编辑 ]
作者: Kagilo    时间: 2007-12-24 10:08
应该不会吧, 用浏览器访问的时候,  不过也是构造一段HTTP header啊,

自己写软件,只要构造一段HTTP  header 就可以了,

服务端PHP不可能接受不到啊,  不过是ASP,PHP,ASP。NET,JSP都是一样的。
作者: myaxl2008    时间: 2007-12-24 22:51
我做过用的是header来传值的
作者: Aryang    时间: 2007-12-25 11:10
php://input
不错,又长见识了
作者: dhgdmw    时间: 2008-07-13 19:29
的确长见识了
作者: 艾斯尼勒    时间: 2008-07-13 23:40
最简单的办法,写个socket随便监听个端口,把所有发送过来的数据按字符串打印出来
然后用浏览器访问这个端口,看看这个程序都输出来啥了,就是http请求了,GET请求就是地址后面的?xxx=abc&yyy=cba这样子的
如果是post方法,你还要写个form表单。
照着分析就OK了,根本不用到网上搜索关于HTTP协议的玩意儿。
别的语言不会,拿JAVA写个
import java.io.*;
import java.net.*;
public class NetServer{
    public static void main(String[] args) throws Exception{
         ServerSocket ss = new ServerSocket(88);
         Socket socket = ss.accept();
         BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
         while(true){
              System.out.println(br.readLine());
         }
    }
}
以上代码就在快速回复里面手写的也没编译,可能有错误
就这样,javac NetServer.java编译java -cp . NetServer开启
开浏览器访问http://localhost:88/xxx.php?aaa=mm&bbb=kk
看看命令行里面打印出什么来了就是比较标准的http头信息了,模仿就是了。
你回头写php接受数据的时候就$_GET[aaa] $_GET[bbb]
如果是post,那就写个html表单,例如aa.html
<form action="localhost:88/abc.php" method="post">
    <input type="text" name="aaa">
    <!-- 你也可以多写几个表单项 -->
    <input type="submit">
</form>
用浏览器打开aa.html,并且填点数据提交,看看那个程序出啥就是POST的数据怎么发送了
你PHP里面接受POST数据$_POST[aaa]

无论是POST或者是GET都可以用$_REQUEST这个数组来接受的
不知道楼主是不是想要这样的东西,如果JAVA程序编译不过去不好意思,我手头也没JAVA环境
另外那个程序是死循环的,只有CTRL+C退出,或者杀进程
作者: 艾斯尼勒    时间: 2008-07-13 23:46
file_get_contents("php://input");
赞个。回完了才发现这个帖子这么老了。。。。
这是谁刨坟阿。。恨

[ 本帖最后由 艾斯尼勒 于 2008-7-13 23:47 编辑 ]
作者: jlspzxs    时间: 2008-07-14 00:34
$sDomain = 'www.yahoo.com.cn';
$iPort   = 80;
1、用socket函数连接 (没做测试)
$rSocket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP); //tcp link
if (!$rSocket) {
    printf('错误: %s',socket_strerror(socket_last_error()));
    exit;
}
$rLink   = socket_connect($rSocket,$sDomain,$iPort);
if (!$rLink) {
    printf('错误: %s',socket_strerror(socket_last_error()));
    exit;
}
$sRequest = 'GET / HTTP1.0'."\r\n\r\n"; //\r\n <CRLF>
$bWrite = socket_write($rSocket,);
if (!$bWrite) {
    printf('不能写入,%s',socket_strerror(socket_last_error()));
    exit;
}
$sContent = socket_read($rSocket,32767);
if (!sContent) {
    printf('不能读取数据,%s',socket_strerror(socket_last_error()));
    exit;
}
echo $sContent;
socket_close($rSocket); //详细说明看下面的RFC

2、使用函数fsockopen

$domain = 'www.yahoo.com.cn';
$port   = 80;
$time_limit = 30;
ini_set('max_execution_time',(ini_get('max_execution_time')>$time_limit)?ini_get('max_execution_time'):$time_limit);
ini_set('error_reporting',E_ALL);
$fp = fsockopen($domain,$port,$errno,$error,$time_limit);
if (!$fp)
{
    printf('failed: %s ',$error);
    exit('<font color="red">end</font>');
}
$cur = 'GET / HTTP/1.0'."\r\n\r\n"; //GET POST TRACE OPTIONS HEAD
fwrite($fp,$cur);
$content = '';
while (!feof($fp))
{
    $content .= fgets($fp); // 默认1000
}
fclose($fp);
echo $content
上面是get方式的,
<?PHP
/ $flag = 0;
//要post的数据
$argv = array(
  'var1'=>'abc',
  'var2'=>'你好吗');
//构造要post的字符串
foreach ($argv as $key=>$value) {
  if ($flag!=0) {
    $params .= "&";
    $flag = 1;
  }
  $params.= $key."="; $params.= urlencode($value);
  $flag = 1;
  }
  $length = strlen($params);
  //创建socket连接
  $fp = fsockopen("127.0.0.1",80,$errno,$errstr,10) or exit($errstr."--->".$errno);
  //构造post请求的头
  $header = "POST /mobile/try.php HTTP/1.1\r\n";
  $header .= "Host:127.0.0.1\r\n";
  $header .= "Referer:/mobile/sendpost.php\r\n";
  $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
  $header .= "Content-Length: ".$length."\r\n";
  $header .= "Connection: Close\r\n\r\n";
  //添加post的字符串
  $header .= $params."\r\n";
  //发送post的数据
  fputs($fp,$header);
  $inheader = 1;
  while (!feof($fp)) {
    $line = fgets($fp,1024); //去除请求包的头只显示页面的返回数据
    if ($inheader && ($line == "\n" || $line == "\r\n")) {
        $inheader = 0;
    }
    if ($inheader == 0) {
        echo $line;
    }
  }
fclose($fp);
?>
下面是post数据的。
对于服务器try.php程序接受传递数据可以通过
php://input 允许读取 POST 的原始数据。和 $HTTP_RAW_POST_DATA 比起来,它给内存带来的压力较小,并且不需要任何特殊的 php.ini 设置。php://input 不能用于 enctype="multipart/form-data"。
可以用这两
file_get_contents("php://input");或者$_SERVER['HTTP_RAW_POST_DATA'];取的。助于文件的上传可以enctype="multipart/form-data可以通过php://stdin标准输入进行写入




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2