PHP中类似于JSON-RPC的简单API

参赛作品


什么是JSON-RPC API? 这只是API类型之一,也是一个清晰的标准,本文可能未介绍(是的,会有一个samopis)。

在我摆弄了RESTful API一段时间后,对此感到非常恼火,因为它在外面很简单并且可以折叠在里面,所以我去了Google寻找替代品。

我碰到了一篇有关JSON-RPC API的文章,我对它的概念非常感兴趣,以至于我决定尽可能简单地实现我的自行车。

JSON-RPC API概念

该标准的主要思想是采用某种面向对象的方法。

在语义上,查询如下所示:

{ "api version": 0.1, "method": "object.method", "params": { "user id": 1234 } } 

而且这只是一个请求,这种API的最大魅力在于可以将它们完美地组合在一起,这使我们有机会将其用于批处理请求(部分加载某些内容)。

也就是说,一个完整的请求可能看起来像这样。

 { "api_v": "0.1", "reqs": [ { "name": "my_important_request", "method": "user.kick_out", "params": { "id": "1234", "when": "now", ... } }, ... ] } 

此处api_v是API版本,而reqs是请求数组。 重要的是,每个请求都有一个方法(class.method),参数和名称。 这个名字在这里起着重要的作用。 从服务器收到响应时,可以通过查询名称来引用查询结果。 示例:带有添加用户方法的请求应称为“ user_creating”,但这取决于您;)

让我们开始写作


需要做的第一件事是API类,就我而言,它做的甚至比应做的要少。 有些过程与我分开,但这并没有改变本质。

 <?php // @package 'api_0.1.php' // API  0.1 class API { private $last_resp; //    private $resp = []; //   public function __call( $method, $params ) { //  ,     $object = substr($method, 0, strpos($method, '.')); $method_name = substr($method, strpos($method, '.')+1); //   include_once __DIR__.'/source/'.$object.'.methods.php'; //      $resp = $object::$method_name($params); if(!empty($resp)) $this->last_resp = $resp; else $this->last_resp = null; } //          - pulbic function add_resp($req_name){ if($this->last_resp === null) return false; $req = $this->last_resp; $this->resp[$req_name] = $req; } //  ,    public function response(){ exit ( json_encode($this->resp) ); } } 

代码中有注释,但这是一个简短的题外话……我们称API为未知函数,为此使用了魔术__call函数。 也就是说,通过调用API的“ Object.method”函数($ api-> {“ Object.method”}),它会自动将字符串拆分为一对对象方法并进行调用。 然后,将所有查询的结果添加到一个数组中,并以json格式发送回去。 一切都很简单。

班级


这非常重要-这些类存储在源文件夹中,这就是该类的外观

 <?php class object{ function method($params){ /* ... */ } } 

类名必须与请求中的请求名相匹配,并与方法名相同。 其他一切都没有关系。 方法可以执行任何操作并返回任何操作。

但是我们还需要一个控制脚本。 这是将在请求时调用的脚本。

 <?php // @package api.php header('Content-Type: application/json'); //     json $api_v = $_POST['api_v']; // $path = __DIR__.'/APIs/api_'.$api_v.'.php'; //       ,    if(!file_exists($path)) exit; //       include_once __DIR__.'/APIs/api_'.$api_v.'.php'; //  API $api = new API(); $reqs = $_POST['reqs']; $reqs = @json_decode($reqs, true); //  json  php  () //    ,          API foreach ($reqs as $req) { $method = $req['method']; $params = $req['params']; $req_name = $req['name']; $api->$method($params); $api->add_resp($req_name); } //    $api->response(); 

这是怎么回事 我们根据请求中指定的版本启用API。 我们解码json请求并逐一处理。 我们调用类型为“ object.method”的API方法,并将其结果保存在此请求的名称下(上面写过,每个请求都有自己的名称)。 执行完所有请求后,我们返回结果的json数组...基本上就是这样。

小js


这是js函数的一个小示例,它将发出这种类型的API请求。 它是使用jQuery编写的,对此我深表歉意,但是在没有太多内容的情况下展示其实质是如此简单。

 function api_call(reqs, callback){ //  (  ,    ,     )   json var json = JSON.stringify( (Array.isArray(reqs) ? reqs : [reqs]) ); //  POST  $.post({ url: '/api/api.php', //    api.php dataType: 'json', //   json,     data: ({ api_v: '0.1', reqs: json }), //   API   ( json ) success: function(res){ //         window,      .     for(var key in res){ window.loaded[key] = res[key]; } //      callback(res); } }); } 

这是一个简单的POST请求,几乎没有什么特别之处,除了可以仅指定一个请求,而不指定数组,而且我还将所有响应保存在一个已下载响应的数组中,只是为了方便起见,这根本没有必要。

好吧,我希望主要思想对您清楚。 我想制作一个简单直观的API-我做到了。 在大多数情况下,我只想展示创建多功能API的简单方法。

待会儿见...

Source: https://habr.com/ru/post/zh-CN446348/


All Articles