Curl和PHP - 我如何通过PUT、POST、GET方法使用Curl传递JSON?

67

我出于兴趣一直在构建一个Rest API,并通过使用命令行中的curl进行测试,这对于CRUD非常容易。

我可以成功地从命令行进行这些调用。

curl -u username:pass -X GET http://api.mysite.com/pet/1
curl -d '{"dog":"tall"}' -u username:pass -X GET http://api.mysite.com/pet
curl -d '{"dog":"short"}' -u username:pass -X POST http://api.mysite.com/pet
curl -d '{"dog":"tall"}' -u username:pass -X PUT http://api.mysite.com/pet/1

上述调用可以在命令行中轻松执行,并且在我的API中运行良好,但现在我想使用PHP创建curl。如您所见,我将数据作为json字符串传递。我已经查阅了相关资料,认为我可能可以执行POST并包含POST字段,但我无法找到如何通过GET传递HTTP主体数据的方法。我看到的所有内容都说您必须将其附加到URL上,但在命令行表单上看起来并不是这样。无论如何,如果有人能够在此处编写正确的四个操作以在PHP中执行它们,我会非常感激。我希望看到使用curl和php最简单的方法。我认为我需要通过http主体传递一切,因为我的php api使用php://input捕获所有内容

5个回答

182

放置

$data = array('username'=>'dog','password'=>'tall');
$data_json = json_encode($data);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($data_json)));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS,$data_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response  = curl_exec($ch);
curl_close($ch);

提交

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$data_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response  = curl_exec($ch);
curl_close($ch);

获取 参见@Dan H的回答

删除

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_POSTFIELDS,$data_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response  = curl_exec($ch);
curl_close($ch);

谢谢你的PUT请求,如果你能添加GET请求(带有JSON格式的请求体)和POST请求,我会接受的。 - Gilberg
1
@Gilberg为POST添加了表单。在GET请求中,数据通过URL传递 :) - voodoo417
谢谢,我不能使用丹的方法,因为我的API正在等待php://input,如果我将其包含在URL中,它就不会进入php://input流。简而言之,我无法从$_GET中获取它,虽然我可以这样做,但这会带来一些小麻烦。我可以通过命令行轻松地执行curl -d '{json-string}' -X GET http://api.mysite.com/user,所以肯定有一种方法可以在PHP中模拟它。 - Gilberg
谢谢@voodoo4q7,我会接受,但我仍然想看看如何在GET请求的正文中传递数据。我知道我的服务器可以接受它,所以这对我不是问题。 - Gilberg
1
你能同时使用CURLOPT_PUT吗? - robsch
显示剩余10条评论

11
您可以使用这个小型库:https://github.com/ledfusion/php-rest-curl 发起一次调用很简单:
// GET
$result = RestCurl::get($URL, array('id' => 12345678));

// POST
$result = RestCurl::post($URL, array('name' => 'John'));

// PUT
$result = RestCurl::put($URL, array('$set' => array('lastName' => "Smith")));

// DELETE
$result = RestCurl::delete($URL); 

关于$result变量:

  • $result['status']是HTTP响应代码
  • $result['data']是解析JSON响应的数组
  • $result['header']是响应头的字符串

希望能有所帮助。


5

对于我自己,我只是在URL中编码并在目标页面上使用 $_GET 。以下是一行示例:

$ch = curl_init();
$this->json->p->method = "whatever";
curl_setopt($ch, CURLOPT_URL, "http://" . $_SERVER['SERVER_NAME'] . $this->json->path . '?json=' . urlencode(json_encode($this->json->p)));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);

编辑:添加目标代码片段...(根据OP的要求,EDIT 2在上面添加了更多内容)
<?php
if(!isset($_GET['json']))
    die("FAILURE");
$json = json_decode($_GET['json']);
$method = $json->method;
...
?>

1
谢谢,你能否将你的完整curl代码用php写出来,以便清楚地说明如何定义POST、GET、PUT、DELETE。我的API需要这些方法。 - Gilberg
已添加。这只是一个简单的HTTP请求,但如您所见,在目标地址中我使用了GET方法。这只是为了传递一个JSON字符串(例如,从我的应用程序前端到脚本1,再到脚本2,最后回复给应用程序前端--源代码未包含此部分)。 - Dan H
+1,但我打算等待POST、PUT和DELETE,因为我编写的REST API需要这些。 - Gilberg

1

我正在使用Elastic SQL插件进行编程工作。 查询是通过以下方式使用GET方法和cURL完成的:

curl -XGET http://localhost:9200/_sql/_explain -H 'Content-Type: application/json' \
-d 'SELECT city.keyword as city FROM routes group by city.keyword order by city'

我在公共服务器上暴露了一个自定义端口,并使用基本身份验证进行反向代理。

这段代码,加上基本身份验证头部,可以正常工作:

$host = 'http://myhost.com:9200';
$uri = "/_sql/_explain";
$auth = "john:doe";
$data = "SELECT city.keyword as city FROM routes group by city.keyword order by city";

function restCurl($host, $uri, $data = null, $auth = null, $method = 'DELETE'){
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $host.$uri);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    if ($method == 'POST')
        curl_setopt($ch, CURLOPT_POST, 1);
    if ($auth)
        curl_setopt($ch, CURLOPT_USERPWD, $auth);
    if (strlen($data) > 0)
        curl_setopt($ch, CURLOPT_POSTFIELDS,$data);

    $resp  = curl_exec($ch);
    if(!$resp){
        $resp = (json_encode(array(array("error" => curl_error($ch), "code" => curl_errno($ch)))));
    }   
    curl_close($ch);
    return $resp;
}

$resp = restCurl($host, $uri); //DELETE
$resp = restCurl($host, $uri, $data, $auth, 'GET'); //GET
$resp = restCurl($host, $uri, $data, $auth, 'POST'); //POST
$resp = restCurl($host, $uri, $data, $auth, 'PUT'); //PUT

-3

设置一个额外的属性 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , false);


这是错误的建议。设置该标志意味着您不验证SSL证书。它会让您面临DNS劫持的风险。 - Machavity

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接