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安装问题
Oct 09 PHP
如何在PHP中使用Oracle数据库(6)
Oct 09 PHP
如何写php程序?
Dec 08 PHP
PHP 的几个配置文件函数
Dec 21 PHP
php初学者写及时补给skype用户充话费的小程序
Nov 02 PHP
php读取文件内容的三种可行方法示例介绍
Feb 08 PHP
PHP实现将视频转成MP4并获取视频预览图的方法
Mar 12 PHP
php获取远程图片并下载保存到本地的方法分析
Oct 08 PHP
浅谈php和js中json的编码和解码
Oct 24 PHP
php获取POST数据的三种方法实例详解
Dec 20 PHP
浅谈PHP面向对象之访问者模式+组合模式
May 22 PHP
laravel 实现关闭CSRF(全部关闭、部分关闭)
Oct 21 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
做个自己站内搜索引擎
2006/10/09 PHP
在任意字符集下正常显示网页的方法一
2007/04/01 PHP
php 遍历数据表数据并列表横向排列的代码
2009/09/05 PHP
php getimagesize 上传图片的长度和宽度检测代码
2010/05/15 PHP
php 操作数组(合并,拆分,追加,查找,删除等)
2012/07/20 PHP
CentOS 7.2 下编译安装PHP7.0.10+MySQL5.7.14+Nginx1.10.1的方法详解(mini版本)
2016/09/01 PHP
php+mysql开发的最简单在线题库(在线做题系统)完整案例
2019/03/30 PHP
javascript 强制刷新页面的实现代码
2009/12/13 Javascript
纯JavaScript实现的完美渐变弹出层效果代码
2010/04/02 Javascript
三级下拉菜单的js实现代码
2011/05/23 Javascript
Javascript中的delete操作符详细介绍
2014/06/06 Javascript
nodejs创建web服务器之hello world程序
2015/08/20 NodeJs
仿Angular Bootstrap TimePicker创建分钟数-秒数的输入控件
2016/07/01 Javascript
Jquery实现上下移动和排序代码
2016/10/17 Javascript
AngularJs表单验证实例代码解析
2016/11/29 Javascript
微信小程序微信支付接入开发实例详解
2017/04/12 Javascript
vue实现裁切图片同时实现放大、缩小、旋转功能
2018/03/02 Javascript
微信小程序学习笔记之获取位置信息操作图文详解
2019/03/29 Javascript
vue百度地图 + 定位的详解
2019/05/13 Javascript
vue setInterval 定时器失效的解决方式
2020/07/30 Javascript
Flask入门教程实例:搭建一个静态博客
2015/03/27 Python
python去除字符串中的换行符
2017/10/11 Python
python使用turtle绘制分形树
2018/06/22 Python
将tensorflow模型打包成PB文件及PB文件读取方式
2020/01/23 Python
解决windows下python3使用multiprocessing.Pool出现的问题
2020/04/08 Python
python统计mysql数据量变化并调用接口告警的示例代码
2020/09/21 Python
Jupyter Notebook安装及使用方法解析
2020/11/12 Python
纯HTML5+CSS3制作生日蛋糕(代码易懂)
2016/11/16 HTML / CSS
加拿大消费电子和手机购物网站:The Source
2017/01/28 全球购物
人事专员岗位职责
2013/11/20 职场文书
父亲生日宴会答谢词
2014/01/10 职场文书
写给女朋友的检讨书
2014/01/28 职场文书
村干部承诺书
2014/03/28 职场文书
《陈毅探母》教学反思
2014/05/01 职场文书
党员作风建设自查报告
2014/10/23 职场文书
导游词之南迦巴瓦峰
2019/11/19 职场文书