【发布时间】:2014-06-20 19:53:57
【问题描述】:
我正在尝试通过PHP 与Chef 集成
我使用库https://github.com/dv1r/php-chef 与Hosted Enterprise Chef 进行通信。当我从Chef 检索信息时,一切都很好。我也可以删除客户之类的。
当我尝试向服务器发送数据时,问题就开始了。我总是收到错误“无效的 JSON”。 我发送的 JSON 根据http://jsonlint.com/ 是有效的。
有人知道我是否需要向json_encode() 添加和编码类型以解决此问题?
代码示例:
try{
// Gets current data in Data-Bad `evns` Item `dev` (works)
$res = $this->chef->get('/data/envs/dev');
} catch (Exception $e){
echo("Exception: ".$e->getMessage());
}
// Alter Data
$res->testtt = "testess";
try{
// Set's new data to Data-bag `envs` Item `dev` (FAILS)
$ret = $this->chef->put("/data/envs/dev",$res);
} catch (Exception $e){
die("Exception: <br>".$e->getMessage());
}
图书馆的有趣部分:
// json encode data
if ($data && !is_string($data)) {
$data = json_encode($data,JSON_UNESCAPED_UNICODE);
$this->debug("data encoded to json: {$data}");
}
// sign the request
$this->sign($endpoint, $method, $data, $header);
$this->debug("request URL: {$url}");
// initiate curl
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeout);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
// most people are using self-signed certs for chef, so its easiest to just
// disable ssl verification
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
// add data to post and put requests
if ($method == 'POST' || $method == 'PUT')
{
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
// execute
$raw_response = curl_exec($ch);
如果我遗漏了一些重要信息,请发表评论,我会补充。
谢谢。
编辑:更多调试信息 -
原始响应:
第一次调用 API (GET) raw_response: {"name":"name","id":"dev"}
第二次调用(PUT)raw_response: {"error":["invalid JSON"]}
curl_getinfo($ch) [PUT] 的输出:
Array
(
[url] => https://api.opscode.com/organizations/MY_ORG/data/envs/dev
[content_type] => text/html
[http_code] => 400
[header_size] => 426
[request_size] => 1665
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 1
[total_time] => 0.175739
[namelookup_time] => 2.0E-5
[connect_time] => 0.02709
[pretransfer_time] => 0.093261
[size_upload] => 0
[size_download] => 26
[speed_download] => 147
[speed_upload] => 0
[download_content_length] => 26
[upload_content_length] => 0
[starttransfer_time] => 0.126115
[redirect_time] => 0.049605
[certinfo] => Array()
[primary_ip] => 184.106.28.81
[primary_port] => 443
[local_ip] => xxx.xxx.xxx.50
[local_port] => 33329
[redirect_url] =>
[request_header] => PUT /organizations/MY_ORG/data/envs/dev HTTP/1.1
Host: api.opscode.com
Accept: application/json
Content-Type: application/json
X-Chef-Version: 11.8.2
X-Ops-Sign: algorithm=sha1;version=1.0
X-Ops-UserId: USER
X-Ops-Timestamp: 2014-05-07T13:39:55Z
X-Ops-Content-Hash: qk8fSIReFrOMJ+Wk2y8yoe3EAgk=
X-Ops-Authorization-1: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-Ops-Authorization-2: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-Ops-Authorization-3: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-Ops-Authorization-4: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-Ops-Authorization-5: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-Ops-Authorization-6: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
)
【问题讨论】:
-
$data = json_encode($data,JSON_UNESCAPED_UNICODE);你玩过这条线吗?更改内容类型等? -
是的,我试过
JSON_HEX_TAG、JSON_HEX_APOS、JSON_HEX_QUOT、JSON_HEX_AMP和JSON_UNESCAPED_UNICODE。 (JSON_UNESCAPED_UNICODE 对我来说似乎最合乎逻辑。) -
我认为该错误具有误导性 - 也许您的有效负载解析为 JSON 就好了,但它不是有效的 Chef JSON。你能粘贴更多的调试输出吗?您发送的实际有效负载是什么?查看请求中的响应代码也很有帮助。该方法的 API 响应代码:docs.opscode.com/api_chef_server.html#data-name-item
-
@Christopher Armstrong,我添加了一些信息,但我不确定如何在请求有效负载发出之前检查它。在此处添加到请求中
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); -
你想
PUT做什么?因为您发送的标头是您要发送的 JSON,那是您真正要发送的吗?尝试发送 POST 而不是 PUT
标签: php json api rest chef-infra