如何创建一个简单的PHP API处理程序?

时间:2017-04-25 19:36:57

标签: php json rest curl digital-ocean

我使用cURL在PHP中编写了一个基本的API脚本 - 并在另一个API上成功使用了它的一个版本,这个版本专门用于处理DigitalOcean上的域DNS管理 - 我无法发送数据?

前奏...

我知道有一个可用的PHP库,我不是在追求完全功能或者依赖于某些东西的东西之后 - 只是在本地使用的小东西主要是为了帮助我理解RESTful API和# 39;在实践中做得更好 - 一项教育练习

违规代码......

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请求,例如在帐户上列出域但在发布/发送数据时似乎失败...这导致" unprocessable_entity"和"姓名不能为空白" - 由于名称不是空白且格式正确(据我所知),它告诉我数据没有正确发送?

解决方案到目前为止尝试......

我已经尝试了json编码数据(在代码中看到),而不是json编码,带有和不带json编码的url编码以及其他没有运气的选项。

我在网上看过一些关于这个完全相同的问题的帖子,特别是与DigitalOcean的API(以及另一个),但没有人有解释(除了放弃和使用图书馆或对此有影响的事情)

直接从终端使用cURL可以正常工作,因此用于创建域的API没有任何问题。

据我了解,身份验证正常,一般设置正常,因为我可以在帐户中列出域名,我只是不能POST或PUT新数据。虽然我已经API's documentation了,但却无法看到我做错了什么,也许是某种错误的编码?

任何帮助将不胜感激! :)

修改很多工作和研究之后,即使其他简单的API处理程序也无法与Digital Ocean一起使用(例如https://github.com/ledfusion/php-rest-curl) - 这个API是否需要特别需要,或者我缺少API和#的基本内容39;一般情况下?

5 个答案:

答案 0 :(得分:1)

它可能是307或308 http重定向。

也许" https://api.digitalocean.com/v2/domains"重定向到另一个网址。

如果是这种情况,请尝试添加:

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

使curl遵循重定向并保留参数。 建议您也使用:

curl_setopt($curl, CURLOPT_POSTREDIR, 3);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");

保留请求正文。 希望它有所帮助。

答案 1 :(得分:0)

添加Content-Length标头并对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);
}

答案 2 :(得分:0)

也许这对你有用:

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);
}

这也可能是你应该发送的标题和你遗漏的问题。

答案 3 :(得分:0)

从技术上讲,这不是一个修复,而是一个解决方法。 感谢大家的意见和想法,遗憾的是没有任何工作/修复代码和赏金过期:(

虽然我不知道为什么PHP cURL选项不起作用(HTTP工作正常,但数字海洋吐出错误由于未知原因与发布数据的验证相关联)...

我确实有一种新的方法,工作最终......(感谢jtittle post on the Digital Ocean Community forum

只是因为这个链接将来会消失......他是使用流和file_get_contents的工作函数而不是curl ......

<?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'
));

我用它来实际成功发布数据......

var_dump(doapi(
    $api_key,
    'post',
    'domains',
    array("name" => (string) $newDomain, "ip_address" => "1.2.3.4")
));

答案 4 :(得分:-1)

您也可以尝试使用CURLOPT_POST

相关问题