PHP - 使用无cURL的http Web请求向网关发布XML数据

pri*_*nce 0 xml postdata httpwebrequest file-get-contents http-headers

我试图找到一种无需cURL的方法,通过http web请求将数据发送到第三方支付网关.我开发了以下代码,实际上它与接收页面成功通信,但显然POST数据没有被发送.

<?php
function makeWebRequest()
{
    //URL where to send the data via POST
    $url = 'http://localhost/connect_to_gateway/receive.php';

    //the actual data
    $xml = '<?xml version="1.0" encoding="UTF-8"?>' .
            '<test>' .
                'Hi there!' .
            '</test>';
    $data = array('xml' => $xml);

    //prepare the HTTP Headers
    $content_type = 'text/xml';
    $data = http_build_query($data);
    // use key 'http' even if you send the request to https://...
    $options = array(
        'http' => array(
            'method'  => 'POST',
            'header'  => 'Content-type: ' . addslashes($content_type) .'\r\n'
                            . 'Content-Length: ' . strlen($data) . '\r\n',
            'content' => $data,
        ),
    );
    $context  = stream_context_create($options);

    /*send the data using a cURL-less method*/
    $result = file_get_contents($url, false, $context);
    echo 'file_get_contents<br/>';
    var_dump($result); /*  <===  POST DATA NOT ARRIVING AT DESTINATION (I only receive a string with "START- FINISH - ") */
    echo '<br/><br/><br/><br/>';
}

//call the function
makeWebRequest(); 
?>
Run Code Online (Sandbox Code Playgroud)

为了检查第三方页面没有收到数据的原因,我创建了自己的接收页面(receive.php),我将请求发送到我自己的脚本:

<?php

echo 'START- ';
if($_POST)
{
    echo 'INSIDE- ';
    echo htmlentities($_POST[0]);
}
echo 'FINISH -';
?>
Run Code Online (Sandbox Code Playgroud)

我可以确认它是真的:(.接收脚本没有收到POST数据,因为我从我自己的页面获得的响应是​​一个值为" START- FINISH-" 的字符串.如果收到POST数据,响应文本将有INSIDE-至少包含了这个词.

你知道我做错了什么吗?

虽然我想专门将内容类型设置为'text/xml',但我也试过'application/x-www-form-urlencoded'但仍然没有成功,$ _POST仍然是空的.我还试过(a)省略标题中的Content-Length,(b)直接发送$ xml而不是$ data.

关于brugbart.com的这个教程展示了我的一个示例similair.这个论坛帖子在sitepoint上提到了一些我仍然不理解的东西,即如果用#with-curlwrappers编译PHP,那么标题应该作为一个简单的数组而不是纯文本发送(他的意思是什么?).我解释sitepoint评论的方式是这样的,但我仍然没有进展:$ o

$options = array(
        'http' => array(
            'method'  => 'POST',
            'header'  => array(
                'Content-type' => addslashes($content_type),
                'Content-Length' => strlen($data)),
            'content' => $data,
        ),
    );
Run Code Online (Sandbox Code Playgroud)

任何帮助将非常感激.

对于那些问我为什么要避免使用cURL的人,这是因为libcurl并不总是安装在每个人的服务器上,我试图找到一种方法来实现同样的事情,而不必要求管理员安装libcurl,如果它没有安装在原始安装中..我正在尝试使用'vanilla php'.

像这样的其他stackoverflow帖子没有帮助:

pri*_*nce 7

我找到了麻烦的解决办法:)

我发现当Content-type不是application/x-www-form-urlencoded时,PHP中的$ _POST将无法读取任何数据.相反,应该访问$ HTTP_RAW_POST_DATA.

因此,通过POST通过file_get_contents发送xml数据的代码如下:

<?php

function makeWebRequest()
{
    //URL where to send the data via POST
    $url = 'http://localhost/connect_to_gateway/receive.php';

    //the actual data
    $xml = '<?xml version="1.0" encoding="UTF-8"?>' .
            '<test>' .
                'Hi there!' .
            '</test>';

    //prepare the HTTP Headers
    $content_type = 'text/xml';
    // use key 'http' even if you send the request to https://...
    $options = array(
        'http' => array(
            'method'  => 'POST',
            'header'  => 'Content-type: ' . addslashes($content_type) .'\r\n'
                            . 'Content-Length: ' . strlen($xml) . '\r\n',
            'content' => $xml,
        ),
    );
    $context  = stream_context_create($options);

    /*send the data using a cURL-less method*/
    $result = file_get_contents($url, false, $context);
    echo 'file_get_contents<br/>';
    var_dump($result);
}

//call the function
makeWebRequest(); 
?>
Run Code Online (Sandbox Code Playgroud)

RECEIVE数据的方法如下:

if ($HTTP_RAW_POST_DATA)
{   
    //create an xml parser and attempt to read it outputting errors if any
    $xml_parser=xml_parser_create();
    if(!xml_parse_into_struct($xml_parser, $HTTP_RAW_POST_DATA, $vals, $index))
        var_dump(array("ERROR"=>sprintf("XML error: %s at line %d",xml_error_string(xml_get_error_code($xml_parser)),xml_get_current_line_number($xml_parser))));
}
Run Code Online (Sandbox Code Playgroud)

谢谢大家.. p ..这真是太痛苦了!