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 相关文章推荐
php 的加密函数 md5,crypt,base64_encode 等使用介绍
Apr 09 PHP
curl不使用文件存取cookie php使用curl获取cookie示例
Jan 26 PHP
PHP版本如何选择?应该使用哪个版本?
May 13 PHP
php使用Jpgraph绘制3D饼状图的方法
Jun 10 PHP
在PHP程序中使用Rust扩展的方法
Jul 03 PHP
详细解读PHP的Yii框架中登陆功能的实现
Aug 21 PHP
php格式化json函数示例代码
May 12 PHP
PHP不使用递归的无限级分类简单实例
Nov 05 PHP
详解php用curl调用接口方法,get和post两种方式
Jan 13 PHP
PHP PDOStatement::debugDumpParams讲解
Jan 30 PHP
PHP实现会员账号单唯一登录的方法分析
Mar 07 PHP
设定php简写功能的方法
Nov 28 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
实时抓取YAHOO股票报价的代码
2006/10/09 PHP
PHP+.htaccess实现全站静态HTML文件GZIP压缩传输(一)
2007/02/15 PHP
适用于php-5.2 的 php.ini 中文版[金步国翻译]
2011/04/17 PHP
在Windows系统下使用PHP生成Word文档的教程
2015/07/03 PHP
PHP中set error handler函数用法小结
2015/11/11 PHP
PHP实现添加购物车功能
2017/03/06 PHP
实例讲解PHP表单
2020/06/10 PHP
javascript 设计模式之单体模式 面向对象学习基础
2010/04/18 Javascript
超越Jquery_01_isPlainObject分析与重构
2010/10/20 Javascript
jQuery方法简洁实现隔行换色及toggleClass的使用
2013/03/15 Javascript
js中传递特殊字符(+,&amp;)的方法
2014/01/16 Javascript
对之前写的jquery分页做下升级
2014/06/19 Javascript
js实现图片和链接文字同步切换特效的方法
2015/02/20 Javascript
iframe中子父类窗口调用JS的方法及注意事项
2015/08/25 Javascript
JS控制文本域只读或可写属性的方法
2016/06/24 Javascript
基于Phantomjs生成PDF的实现方法
2016/11/07 Javascript
深入研究React中setState源码
2017/11/17 Javascript
vue 通过下拉框组件学习vue中的父子通讯
2017/12/19 Javascript
webpack 模块热替换原理
2018/04/09 Javascript
Vue.js计算机属性computed和methods方法详解
2019/10/12 Javascript
Python实现统计代码行的方法分析
2017/07/12 Python
python 遍历目录(包括子目录)下所有文件的实例
2018/07/11 Python
python读取mysql数据绘制条形图
2020/03/25 Python
html5 跨文档消息传输示例探讨
2013/04/01 HTML / CSS
玩具反斗城葡萄牙官方商城:Toys"R"Us葡萄牙
2016/10/21 全球购物
美国学校用品、教室和教学商店:Discount School Supply
2018/04/04 全球购物
存储过程的优缺点是什么
2015/01/10 面试题
办公文员的工作岗位职责
2013/11/12 职场文书
高考备战决心书
2014/03/11 职场文书
家长对老师的感言
2014/03/11 职场文书
2015年公司新年寄语
2014/12/08 职场文书
军训个人总结
2015/03/03 职场文书
企业党建工作总结2015
2015/05/26 职场文书
2016年村党支部公开承诺书
2016/03/24 职场文书
创业计划书之密室逃脱
2019/11/08 职场文书
Python 机器学习工具包SKlearn的安装与使用
2021/05/14 Python