如何制作一个简单的 PHP API 处理程序?
How do I make a simple PHP API handler?
我已经使用 cURL 在 PHP 中编写了一个基本的 API 脚本 - 并成功地在另一个 API 上使用了它的一个版本,这个版本专门用于处理域 DNS 管理在 DigitalOcean 上 - 我无法发送数据?
序曲...
我知道有一个 PHP 库可用,我不想要功能齐全或因依赖项而臃肿的东西 - 只是一些小的东西可以在本地使用 并且主要是帮助我了解 RESTful API 如何在实践中更好地工作 - 教育练习
违规代码...
function basic_api_handle($key, $method, $URI, $data) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer '.$key,
'Content-Type: application/json')
);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_URL, $URI);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$result = curl_exec($ch);
if($result === false) error_log("API ERROR: Connection failure: $URI", 0);
curl_close($ch);
return json_decode($result, true);
}
var_dump(basic_api_handle($api_key, 'POST', 'https://api.digitalocean.com/v2/domains', array('name' => 'my-domain.tld', 'ip_address' => '1.2.3.4')));
这适用于 GET 请求,例如在帐户中列出域,但似乎在 posting/sending 数据处失败...这导致 "unprocessable_entity" 和 "Name can't be blank" - 如名称不是空白且格式正确(据我所知)它向我提示数据未正确发送?
到目前为止的解决方案尝试...
我试过 json 编码数据(在代码中看到),而不是 json 编码,url 编码有和没有 json 编码和各种其他选项没有运气。
我在网上看到一些关于这个完全相同的问题的帖子,特别是关于 DigitalOcean 的 API(和另一个),但没有人给出解释 (除了放弃并使用图书馆或其他影响)。
直接从终端使用 cURL 确实有效,因此 API 创建域没有任何问题。
据我所知,身份验证工作正常,一般设置工作正常,因为我可以在帐户中列出域,我只是不能 POST 或 PUT 新数据。我已经通过 API's documentation 并且看不出我做错了什么,也许是某种错误的编码?
如有任何帮助,我们将不胜感激! :)
编辑:
经过 大量 的工作和研究,甚至其他简单的 API 处理程序也无法与 Digital Ocean 一起工作(例如 https://github.com/ledfusion/php-rest-curl)- 这个 API 中有什么东西吗?特殊需求,还是我遗漏了关于 API 的一些基本信息?
添加 Content-Length
header 并为 POST 请求使用 CURLOPT_POST
选项
function basic_api_handle($key, $method, $URI, $data) {
$json = json_encode($data)
$headers = array(
'Authorization: Bearer '.$key,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $URI);
if ( $method === 'POST' ) {
curl_setopt($curl, CURLOPT_POST, 1);
} else {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
array_push($headers, 'Content-Length: ' . strlen($json) );
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers)
curl_setopt($ch, CURLOPT_POSTFIELDS, $json );
$result = curl_exec($ch);
if($result === false) error_log("API ERROR: Connection failure: $URI", 0);
curl_close($ch);
return json_decode($result, true);
}
您也可以尝试使用CURLOPT_POST
也许这对你有用:
function basic_api_handle($key, $method, $URI, $data) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); // <-- Should be set to "GET" or "POST"
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // <-- Maybe the SSL is the problem
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"); // <-- I am not familiar with this API, but maybe it needs a user agent?
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer '.$key,
'Content-Type: application/json')
);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_URL, $URI);
curl_setopt($ch, CURLOPT_POST, count($data)); // <-- Add this line which counts the inputs you send
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$result = curl_exec($ch);
if($result === false) error_log("API ERROR: Connection failure: $URI", 0);
curl_close($ch);
return json_decode($result, true);
}
也可能是 header 您应该发送但未发送的问题。
可能是 307 或 308 http 重定向。
也许“https://api.digitalocean.com/v2/domains”重定向到另一个 url。
如果是这种情况,请尝试添加:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
使curl遵循重定向并保留参数。
建议您同时使用:
curl_setopt($curl, CURLOPT_POSTREDIR, 3);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
保留请求正文。
希望对你有帮助。
从技术上讲,这不是修复,而是解决方法。 感谢大家的意见和想法,不幸的是 worked/fixed 代码和赏金已过期:(
尽管我不知道为什么 PHP cURL 选项不起作用(HTTP 起作用,只是 Digital Ocean 因未知原因吐出错误 linked 以验证 post数据)...
我确实有一个新方法 行得通 终于...(感谢 jtittle post on the Digital Ocean Community forum)
万一 link 将来死了...他是使用流和 file_get_contents 并且 不卷曲的工作函数 ...
<?php
function doapi( $key, $method, $uri, array $data = [] )
{
/**
* DigitalOcean API URI
*/
$api = 'https://api.digitalocean.com/v2';
/**
* Merge DigitalOcean API URI and Endpoint URI
*
* i.e if $uri is set to 'domains', then $api ends up as
* $api = 'https://api.digitalocean.com/v2/domains'
*/
$uri = $api . DIRECTORY_SEPARATOR . $uri;
/**
* Define Authorization and Content-Type Header.
*/
$headers = "Authorization: Bearer $key \r\n" .
"Content-Type: application/json";
/**
* If $data array is not empty, assume we're passing data, so we'll encode
* it and pass it to 'content'. If $data is empty, assume we're not passing
* data, so we won't sent 'content'.
*/
if ( ! empty( $data ) )
{
$data = [
'http' => [
'method' => strtoupper( $method ),
'header' => $headers,
'content' => json_encode( $data )
]
];
}
else
{
$data = [
'http' => [
'method' => strtoupper( $method ),
'header' => $headers
]
];
}
/**
* Create Stream Context
* http://php.net/manual/en/function.stream-context-create.php
*/
$context = stream_context_create( $data );
/**
* Send Request and Store to $response.
*/
$response = file_get_contents( $uri, false, $context );
/**
* Return as decoded JSON (i.e. an array)
*/
return json_decode( $response, true );
}
/**
* Example Usage
*/
var_dump(doapi(
'do-api-key',
'get',
'domains'
));
我用它实际上 post 数据成功...
var_dump(doapi(
$api_key,
'post',
'domains',
array("name" => (string) $newDomain, "ip_address" => "1.2.3.4")
));
我已经使用 cURL 在 PHP 中编写了一个基本的 API 脚本 - 并成功地在另一个 API 上使用了它的一个版本,这个版本专门用于处理域 DNS 管理在 DigitalOcean 上 - 我无法发送数据?
序曲...
我知道有一个 PHP 库可用,我不想要功能齐全或因依赖项而臃肿的东西 - 只是一些小的东西可以在本地使用 并且主要是帮助我了解 RESTful API 如何在实践中更好地工作 - 教育练习
违规代码...
function basic_api_handle($key, $method, $URI, $data) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer '.$key,
'Content-Type: application/json')
);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_URL, $URI);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$result = curl_exec($ch);
if($result === false) error_log("API ERROR: Connection failure: $URI", 0);
curl_close($ch);
return json_decode($result, true);
}
var_dump(basic_api_handle($api_key, 'POST', 'https://api.digitalocean.com/v2/domains', array('name' => 'my-domain.tld', 'ip_address' => '1.2.3.4')));
这适用于 GET 请求,例如在帐户中列出域,但似乎在 posting/sending 数据处失败...这导致 "unprocessable_entity" 和 "Name can't be blank" - 如名称不是空白且格式正确(据我所知)它向我提示数据未正确发送?
到目前为止的解决方案尝试...
我试过 json 编码数据(在代码中看到),而不是 json 编码,url 编码有和没有 json 编码和各种其他选项没有运气。
我在网上看到一些关于这个完全相同的问题的帖子,特别是关于 DigitalOcean 的 API(和另一个),但没有人给出解释 (除了放弃并使用图书馆或其他影响)。
直接从终端使用 cURL 确实有效,因此 API 创建域没有任何问题。
据我所知,身份验证工作正常,一般设置工作正常,因为我可以在帐户中列出域,我只是不能 POST 或 PUT 新数据。我已经通过 API's documentation 并且看不出我做错了什么,也许是某种错误的编码?
如有任何帮助,我们将不胜感激! :)
编辑: 经过 大量 的工作和研究,甚至其他简单的 API 处理程序也无法与 Digital Ocean 一起工作(例如 https://github.com/ledfusion/php-rest-curl)- 这个 API 中有什么东西吗?特殊需求,还是我遗漏了关于 API 的一些基本信息?
添加 Content-Length
header 并为 POST 请求使用 CURLOPT_POST
选项
function basic_api_handle($key, $method, $URI, $data) {
$json = json_encode($data)
$headers = array(
'Authorization: Bearer '.$key,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $URI);
if ( $method === 'POST' ) {
curl_setopt($curl, CURLOPT_POST, 1);
} else {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
array_push($headers, 'Content-Length: ' . strlen($json) );
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers)
curl_setopt($ch, CURLOPT_POSTFIELDS, $json );
$result = curl_exec($ch);
if($result === false) error_log("API ERROR: Connection failure: $URI", 0);
curl_close($ch);
return json_decode($result, true);
}
您也可以尝试使用CURLOPT_POST
也许这对你有用:
function basic_api_handle($key, $method, $URI, $data) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); // <-- Should be set to "GET" or "POST"
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // <-- Maybe the SSL is the problem
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"); // <-- I am not familiar with this API, but maybe it needs a user agent?
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer '.$key,
'Content-Type: application/json')
);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_URL, $URI);
curl_setopt($ch, CURLOPT_POST, count($data)); // <-- Add this line which counts the inputs you send
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$result = curl_exec($ch);
if($result === false) error_log("API ERROR: Connection failure: $URI", 0);
curl_close($ch);
return json_decode($result, true);
}
也可能是 header 您应该发送但未发送的问题。
可能是 307 或 308 http 重定向。
也许“https://api.digitalocean.com/v2/domains”重定向到另一个 url。
如果是这种情况,请尝试添加:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
使curl遵循重定向并保留参数。 建议您同时使用:
curl_setopt($curl, CURLOPT_POSTREDIR, 3);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
保留请求正文。 希望对你有帮助。
从技术上讲,这不是修复,而是解决方法。 感谢大家的意见和想法,不幸的是 worked/fixed 代码和赏金已过期:(
尽管我不知道为什么 PHP cURL 选项不起作用(HTTP 起作用,只是 Digital Ocean 因未知原因吐出错误 linked 以验证 post数据)...
我确实有一个新方法 行得通 终于...(感谢 jtittle post on the Digital Ocean Community forum)
万一 link 将来死了...他是使用流和 file_get_contents 并且 不卷曲的工作函数 ...
<?php
function doapi( $key, $method, $uri, array $data = [] )
{
/**
* DigitalOcean API URI
*/
$api = 'https://api.digitalocean.com/v2';
/**
* Merge DigitalOcean API URI and Endpoint URI
*
* i.e if $uri is set to 'domains', then $api ends up as
* $api = 'https://api.digitalocean.com/v2/domains'
*/
$uri = $api . DIRECTORY_SEPARATOR . $uri;
/**
* Define Authorization and Content-Type Header.
*/
$headers = "Authorization: Bearer $key \r\n" .
"Content-Type: application/json";
/**
* If $data array is not empty, assume we're passing data, so we'll encode
* it and pass it to 'content'. If $data is empty, assume we're not passing
* data, so we won't sent 'content'.
*/
if ( ! empty( $data ) )
{
$data = [
'http' => [
'method' => strtoupper( $method ),
'header' => $headers,
'content' => json_encode( $data )
]
];
}
else
{
$data = [
'http' => [
'method' => strtoupper( $method ),
'header' => $headers
]
];
}
/**
* Create Stream Context
* http://php.net/manual/en/function.stream-context-create.php
*/
$context = stream_context_create( $data );
/**
* Send Request and Store to $response.
*/
$response = file_get_contents( $uri, false, $context );
/**
* Return as decoded JSON (i.e. an array)
*/
return json_decode( $response, true );
}
/**
* Example Usage
*/
var_dump(doapi(
'do-api-key',
'get',
'domains'
));
我用它实际上 post 数据成功...
var_dump(doapi(
$api_key,
'post',
'domains',
array("name" => (string) $newDomain, "ip_address" => "1.2.3.4")
));