PHP错误请求中的HTTP请求失败

PHP错误请求中的HTTP请求失败,php,http,Php,Http,我可以直接从浏览器请求URL web服务“WS”,但当我在代码中使用file_get_contents()或fopen方法时,会收到一条错误消息。有人有没有不使用curl的解决方案 public function sendHttpRequest($data) { ini_set('user_agent', 'PHP'); $context_options = array( 'http' => array( 'method' =>

我可以直接从浏览器请求URL web服务“WS”,但当我在代码中使用file_get_contents()或fopen方法时,会收到一条错误消息。有人有没有不使用curl的解决方案

public function sendHttpRequest($data) {
   ini_set('user_agent', 'PHP');

    $context_options = array(
        'http' => array(
            'method' => 'POST',
            'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
            'content' => json_encode($data)
        )
    );


    $context = stream_context_create($context_options);

    //line error "line 196"
    $result = file_get_contents($this->WS, false, $context);
}
错误消息:

无法打开流:HTTP请求失败!HTTP/1.1400错误请求 在第196行的/mnt/hgfs/case/src/bat/abc/send-entry.php中

空的

我已将上下文选项更改为此,但仍然得到
HTTP/1.1400错误请求

$context_options = array(
        'http' => array(
            'method' => 'POST',
            'header' => "Date: " . gmdate("D, d M Y H:i:s T", time()) . "\r\n"
            . get_headers($this->WS)[2] . "\r\n"
            . " x-powered-by: PHP/" . phpversion() . "\r\n"
            . " " . get_headers($this->WS)[5] . "\r\n"
            . " Pragma: no-cache" . "\r\n"
            . " Content-Length: " . strlen($this->content) . "\r\n"
            . " Content-Type: text/xml" . "\r\n"
            . " " .get_headers($this->WS)[9] . "\r\n"
            . " Connection: close",
            'content' => $this->content
        )

var_dump(get_headers($this->WS))
数据被发送到地址为的服务器

下面是要发送的数组的var_转储

array(16) {
  ["method"]=>
  string(24) "WS"
  ["LOGIN"]=>
  string(12) "xxx"
  ["DATE1"]=>
  string(10) "1970-01-01"
  ["DATE2"]=>
  string(0) ""
  ["TRANSMISSION"]=>
  INT(8)
  ["REF"]=>
  int(206)
  ["FORMAT"]=>
  int(7)
  ["DOMAIN"]=>
  int(3)
  ["TYPE1"]=>
  int(15)
  ["TYPE2"]=>
  NULL
  ["NAME"]=>
  string(12) "JDOE"
  ["ADRESSE"]=>
  string(0) ""
  ["ADRESSE2"]=>
  string(0) ""
  ["ADRESSE3"]=>
  string(0) ""
  ["ADRESSE4"]=>
  string(0) ""
  ["REF2"]=>
  string(0) ""
}
下面是完整的错误消息

警告:文件\获取\内容():无法打开流:HTTP请求失败!HTTP/1.1400错误请求 在第182行的/mnt/hgfs/case/src/bat/abc/send-entry.php中

工作守则:

    $context_options1 = array(
        'http' => array(
            'method' => 'POST',
            'header' => "Date: " . gmdate("D, d M Y H:i:s T", time())
            . "Accept: application/xml"
            . "Content-Type: application/xml"
            . "Content-Length: " . strlen($this->content),
            'content' => $this->content
        )
    );

POST
请求需要
内容长度
标题:

$content = json_encode($data);
$context_options = array(
        'http' => array(
            'method' => 'POST',
            'header' => "Content-Type: application/x-www-form-urlencoded\r\n" 
                         . "Content-Length: " . strlen($content) . "\r\n",
            'content' => $content
        )
    );

这显然是由包装器自动完成的,所以还有其他的东西。也许可以省略标题中的最后一个换行符(\r\n)。

首先模拟您的浏览器。检查哪个开发人员工具会准确地将哪些头发送给服务。并模仿它。这将有助于找出你错在哪里


例如,服务可能需要“内容类型:多部分/表单数据”,而不是应用程序/x表单类型。可能需要提供内容编码或其他内容。

我怀疑这是由于公布的mediatype与实际负载不匹配。正确的状态代码为,但也可能出现400

以您的第一个示例为例:您宣布的是来自html表单的URL编码数据,后跟JSON。我认为正确的代码如下:

public function sendHttpRequest($data) {
    $data = json_encode($data)

    $context = stream_context_create(array(
        'http' => array(
            'method' => 'POST',
            'header' => array(
                'Content-Type: application/json',
                'Content-Length: ' . strlen($data),
                'Connection: close',
            ),
            'content' => $data,
        ),
    ));

    $result = file_get_contents($this->WS, false, $context);
}
您似乎还在请求中放入了许多不属于请求的头,例如
Pragma
和其他缓存控制头。这些应该由服务器发送,而不是客户端


此外,请确保
$this->WS
包含的任何内容都已正确编码。

这是否适用于多字节字符串,并且流上下文不会处理设置内容长度标头的问题?“14.13内容长度Content Length entity header字段表示发送给收件人的实体正文的大小,以十进制的八位字节数表示。”因此,是的:您表示的是字节数,HTTP不关心字符。至于包装器:可能(我知道默认情况下cURL会这样做),或者可能不是。我在问您创建的stream\u context\u是否会自行设置内容长度头(the),在这种情况下,此建议不会解决OP的问题。忽略
strlen()
part,返回字节数,而不是字符数,这样就行了。显然,你是这样做的,因为你问我内容长度是否需要字符数(不,字节数,这就是strlen计算的:用2个字节编码的单个字符会得到2个字符,这比直接引用经文好吗?).至于流包装器,文档不清楚;也许检查传出数据是正确的(我喜欢cURL扩展的原因之一)@CodeCaster:啊,好吧。我当时对丢失的标题错了,加上我误读了你的意图。我为两者道歉。如果你在这里做的和在浏览器中做的一样,那么页面中有大量Javascript调用你没有告诉我们的服务。没有“直接从浏览器”“我的意思是,当我在浏览器中键入url时,对web服务的请求起作用,但当我在代码中调用函数时,请求不起作用,因此问题出在我的函数中,而不是web服务中。那么,也许你应该开始尝试在PHP代码中执行相同的操作(即GET not POST)。谢谢你的建议。它正在使用GET方法。那么,这篇文章有什么问题吗?谢谢你的回复。我已经和web开发人员联系过了。以下是发送的标题:
日期:2016年4月28日星期四15:06:20 GMT
服务器:Apache/2.2.15(CentOS)
过期:1981年11月19日星期四08:52:00 GMT
缓存控制:无存储,无缓存,必须重新验证,post check=0,pre check=0
Pragma:no cache
内容长度:794``内容类型:text/xml
连接:close
是否必须将它们包含在代码中?是。尝试连接此请求。它有效吗?我添加了标题,但仍然通过post方法获得了
“HTTP/1.1400错误请求”
。我对这篇文章做了详细的描述。谢谢你能提供你想要发送的网址和参数吗?我已经添加了地址和参数。谢谢你的时间