PHP - 通过file_get_contents发布JSON

Ben*_*Ben 21 php rest post json file-get-contents

我正在尝试将JSON内容发布到远程REST端点,但是"内容"值在传递时似乎是空的.正确接收所有其他标头等,并且Web服务使用基于浏览器的测试客户端成功测试.

我的语法是否存在问题,我指定了"内容"字段?

$data = array("username" => "duser", "firstname" => "Demo", "surname" => "User", "email" => "example@example.com");   
$data_string = json_encode($data);

$result = file_get_contents('http://test.com/api/user/create', null, stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => array('Content-Type: application/json'."\r\n"
. 'Authorization: username:key'."\r\n"
. 'Content-Length: ' . strlen($data_string) . "\r\n"),
'content' => $data_string)
)
));

echo $result;
Run Code Online (Sandbox Code Playgroud)

Bob*_*ies 22

这是我一直使用的代码,它看起来非常相似(虽然这当然是x-www-form-urlencoded).也许你的username:key需要是base64_encode'd.

function file_post_contents($url, $data, $username = null, $password = null)
{
    $postdata = http_build_query($data);

    $opts = array('http' =>
        array(
            'method'  => 'POST',
            'header'  => 'Content-type: application/x-www-form-urlencoded',
            'content' => $postdata
        )
    );

    if($username && $password)
    {
        $opts['http']['header'] = ("Authorization: Basic " . base64_encode("$username:$password"));
    }

    $context = stream_context_create($opts);
    return file_get_contents($url, false, $context);
}
Run Code Online (Sandbox Code Playgroud)

  • 如果有人遇到问题,即后期数据编码不正确(字典的每个键在开头都有一个"amp;"):将第三行更改为$ postdata = http_build_query($ data,'', '&'); (4认同)
  • 这不是发布 JSON,这是发布名称-值对。它没有回答原来的问题,认为它可能有效。 (2认同)

Yev*_*yev 6

问题是关于json,为什么接受的答案是关于x-www-form

Json 有很多很酷的东西要争取,比如 utf8_encode

function my_utf8_encode(array $in): array
{
    foreach ($in as $key => $record) {
        if (is_array($record)) {
            $in[$key] = my_utf8_encode($record);
        } else {
            $in[$key] = utf8_encode($record);
        }
    }

    return $in;
}


function file_post_contents(string $url, array $data, string $username = null, string $password = null)
{
    $data     = my_utf8_encode($data);
    $postdata = json_encode($data);
    if (is_null($postdata)) {
        throw new \Exception('decoding params');
    }

    $opts = array('http' =>
        array(
            'method'  => 'POST',
            'header'  => 'Content-type: application/json',
            'content' => $postdata
        )
    );

    if (!is_null($username) && !is_null($password)) {
        $opts['http']['header'] .= "Authorization: Basic " . base64_encode("$username:$password");
    }

    $context = stream_context_create($opts);

    try {
        $response = file_get_contents($url, false, $context);
    } catch (\ErrorException $ex) {

        throw new \Exception($ex->getMessage(), $ex->getCode(), $ex->getPrevious());
    }
    if ($response === false) {

        throw new \Exception();
    }

    return $response;
}
Run Code Online (Sandbox Code Playgroud)

查看我的存储库以获取更多详细信息https://github.com/Eugene-Melbourne/-HTTP_client-


小智 5

较早的回应

function file_post_contents($url, $data, $username = null, $password = null) {
$postdata = http_build_query($data);

$opts = array('http' =>
    array(
        'method'  => 'POST',
        'header'  => 'Content-type: application/x-www-form-urlencoded',
        'content' => $postdata
    )
);

if($username && $password)
{
    $opts['http']['header'] = ("Authorization: Basic " . base64_encode("$username:$password"));
}

$context = stream_context_create($opts);
return file_get_contents($url, false, $context);}
Run Code Online (Sandbox Code Playgroud)

是不正确的。此功能有时可以使用,但是它不准确,如果您未使用Content-type of application / x-www-form-urlencoded,并且您输入了用户名和密码,则该功能将失败。

它对作者有效,因为application / x-www-form-urlencoded是默认的Content-type,但是他对用户名和密码的处理将覆盖内容类型的早期声明。

这是更正后的函数:

function file_post_contents($url, $data, $username = null, $password = null){
$postdata = http_build_query($data);

$opts = array('http' =>
    array(
        'method'  => 'POST',
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
        'content' => $postdata
    )
);

if($username && $password)
{
    $opts['http']['header'] .= ("Authorization: Basic " . base64_encode("$username:$password")); // .= to append to the header array element
}

$context = stream_context_create($opts);
return file_get_contents($url, false, $context);}
Run Code Online (Sandbox Code Playgroud)

请注意以下行:$ opts ['http'] ['header'。=(点号等于附加到数组元素。)