php实现的一个简单json rpc框架实例


Posted in PHP onMarch 30, 2015

json rpc 是一种以json为消息格式的远程调用服务,它是一套允许运行在不同操作系统、不同环境的程序实现基于Internet过程调用的规范和一系列的实现。这种远程过程调用可以使用http作为传输协议,也可以使用其它传输协议,传输的内容是json消息体。

下面我们code一套基于php的rpc框架,此框架中包含rpc的服务端server,和应用端client;

(一)PHP服务端RPCserver jsonRPCServer.php

class jsonRPCServer {

    /**

     *处理一个request类,这个类中绑定了一些请求参数

     * @param object $object

     * @return boolean

     */

    public static function handle($object) {

       // 判断是否是一个rpc json请求

        if ($_SERVER['REQUEST_METHOD'] != 'POST' || empty($_SERVER['CONTENT_TYPE'])

            ||$_SERVER['CONTENT_TYPE'] != 'application/json') {

            return false;

        }

        // reads the input data

        $request = json_decode(file_get_contents('php://input'),true);

        // 执行请求类中的接口

        try {

            if ($result = @call_user_func_array(array($object,$request['method']),$request['params'])) {

                $response = array ( 'id'=> $request['id'],'result'=> $result,'error'=> NULL );

            } else {

                $response = array ( 'id'=> $request['id'], 'result'=> NULL,

                                        'error' => 'unknown method or incorrect parameters' );}

        } catch (Exception $e) {

            $response = array ('id' => $request['id'],'result' => NULL, 'error' =>$e->getMessage());

        }

       // json 格式输出

        if (!empty($request['id'])) { // notifications don't want response

            header('content-type: text/javascript');

            echo json_encode($response);

        }

        return true;

    }

}

(二)Rpc客户端,jsonRPCClient.php

<?php

/*

 */

class jsonRPCClient {
    private $debug;

    private $url;

    // 请求id

    private $id;

    private $notification = false;

    /**

     * @param $url

     * @param bool $debug

     */

    public function __construct($url,$debug = false) {

        // server URL

        $this->url = $url;

        // proxy

        empty($proxy) ? $this->proxy = '' : $this->proxy = $proxy;

        // debug state

        empty($debug) ? $this->debug = false : $this->debug = true;

        // message id

        $this->id = 1;

    }
    /**

     *

     * @param boolean $notification

     */

    public function setRPCNotification($notification) {

        empty($notification) ? $this->notification = false  : $this->notification = true;

    }
    /**

     * @param $method

     * @param $params

     * @return bool

     * @throws Exception

     */

    public function __call($method,$params) {

        // 检验request信息

        if (!is_scalar($method)) {

            throw new Exception('Method name has no scalar value');

        }

        if (is_array($params)) {

            $params = array_values($params);

        } else {

            throw new Exception('Params must be given as array');

        }
        if ($this->notification) {

            $currentId = NULL;

        } else {

            $currentId = $this->id;

        }
       // 拼装成一个request请求

        $request = array(  'method' => $method,  'params' => $params,'id' => $currentId);

        $request = json_encode($request);

        $this->debug && $this->debug.='***** Request *****'."\n".$request."\n".'***** End Of request *****'."\n\n";

        $opts = array ('http' => array (

                                    'method'  => 'POST',

                                    'header'  => 'Content-type: application/json',

                                    'content' => $request

        ));

        //  关键几部

        $context  = stream_context_create($opts);

  if ( $result = file_get_contents($this->url, false, $context)) {

            $response = json_decode($result,true);

  } else {

   throw new Exception('Unable to connect to '.$this->url);

  }

        // 输出调试信息

        if ($this->debug) {

            echo nl2br(($this->debug));

        }

        // 检验response信息

        if (!$this->notification) {

            // check

            if ($response['id'] != $currentId) {

                throw new Exception('Incorrect response id (request id: '.$currentId.', response id: '.$response['id'].')');

            }

            if (!is_null($response['error'])) {

                throw new Exception('Request error: '.$response['error']);

            }

            return $response['result'];
        } else {

            return true;

        }

    }

}

?>

(三) 应用实例
(1)服务端 server.php

<?php

require_once 'jsonRPCServer.php';
// member 为测试类

require 'member.php';

// 服务端调用

$myExample = new member();

// 注入实例

jsonRPCServer::handle($myExample)

 or print 'no request';

?>

(2)测试类文件,member.php

class member{

    public function getName(){

        return 'hello word ' ;  // 返回字符串

    }

}

(3)客户端 client.php

require_once 'jsonRPCClient.php';
$url = 'http://localhost/rpc/server.php';

$myExample = new jsonRPCClient($url);
// 客户端调用

try {

 $name = $myExample->getName();

    echo $name ;

} catch (Exception $e) {

 echo nl2br($e->getMessage()).'<br />'."\n";

}
PHP 相关文章推荐
如何提高MYSQL数据库的查询统计速度 select 索引应用
Apr 11 PHP
PHP的变量总结 新手推荐
Apr 18 PHP
Zend studio文件注释模板设置方法
Sep 29 PHP
php获取文件夹路径内的图片以及分页显示示例
Mar 11 PHP
php获取随机数组列表的方法
Nov 13 PHP
简单实用的PHP防注入类实例
Dec 05 PHP
PHP文件缓存类示例分享
Jan 30 PHP
php返回相对时间(如:20分钟前,3天前)的方法
Apr 14 PHP
微信公众平台开发教程③ PHP实现微信公众号支付功能图文详解
Apr 10 PHP
详解提高使用Java反射的效率方法
Apr 29 PHP
php解压缩zip和rar压缩包文件的方法
Jul 10 PHP
laravel5环境隐藏index.php后缀(apache)的方法
Oct 12 PHP
php实现读取内存顺序号
Mar 29 #PHP
php实现插入排序
Mar 29 #PHP
php实现插入数组但不影响原有顺序的方法
Mar 27 #PHP
WordPress自定义时间显示格式
Mar 27 #PHP
在php和MySql中计算时间差的方法详解
Mar 27 #PHP
PHP连接access数据库
Mar 27 #PHP
使用新浪微博API的OAuth认证发布微博实例
Mar 27 #PHP
You might like
php实现字符串首字母大写和单词首字母大写的方法
2015/03/14 PHP
WordPress中用于获取搜索表单的PHP函数使用解析
2016/01/05 PHP
详解PHP的Yii框架中扩展的安装与使用
2016/04/01 PHP
ExtJS GTGrid 简单用户管理
2009/07/01 Javascript
js获取IP地址的方法小结
2014/07/01 Javascript
JS实现鼠标点击展开或隐藏表格行的方法
2015/03/03 Javascript
jquery中表单 多选框的一种巧妙写法
2015/09/06 Javascript
jquery移动端TAB触屏切换实现效果
2020/12/22 Javascript
AngularJS extend用法详解及实例代码
2016/11/15 Javascript
微信小程序开发(一) 微信登录流程详解
2017/01/11 Javascript
深入浅析ES6 Class 中的 super 关键字
2017/10/20 Javascript
Angular js 实现添加用户、修改密码、敏感字、下拉菜单的综合操作方法
2017/10/24 Javascript
浅析Vue 生命周期
2018/06/21 Javascript
纯javascript前端实现base64图片下载(兼容IE10+)
2018/09/14 Javascript
JavaScript工具库之Lodash详解
2019/06/15 Javascript
JS document文档的简单操作完整示例
2020/01/13 Javascript
[02:15]2015国际邀请赛选手档案IG.Ferrari 430
2015/07/30 DOTA
浅谈python中字典append 到list 后值的改变问题
2018/05/04 Python
Python 学习教程之networkx
2019/04/15 Python
python自动化测试之DDT数据驱动的实现代码
2019/07/23 Python
Python 实现将大图切片成小图,将小图组合成大图的例子
2020/03/14 Python
使用pycharm和pylint检查python代码规范操作
2020/06/09 Python
Python 处理日期时间的Arrow库使用
2020/08/18 Python
Python安装并操作redis实现流程详解
2020/10/13 Python
Mavi牛仔裤美国官网:土耳其著名牛仔品牌
2016/09/24 全球购物
什么是smarty? Smarty的优点是什么?
2013/08/11 面试题
企业管理专业个人求职信范文
2013/09/24 职场文书
高中生学习生活的自我评价
2013/10/09 职场文书
行政前台岗位职责
2013/12/04 职场文书
施工安全生产承诺书
2014/05/23 职场文书
师范类求职信
2014/06/21 职场文书
部队反四风对照检查材料
2014/09/26 职场文书
2014年林业工作总结
2014/12/05 职场文书
全陪导游词
2015/02/04 职场文书
班主任高考寄语
2015/02/26 职场文书
护士自我推荐信范文
2015/03/24 职场文书