首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 實現輕量級 JSON-RPC 2.0 框架:Server/Client 完整代碼與調用示例

     編輯:PHP 綜合知識

架構設計

  • 傳輸協議:HTTP POST
  • 消息格式:JSON-RPC 2.0 規範({jsonrpc:"2.0", method, params, id})
  • 組件:jsonRPCServer(服務端分發)、jsonRPCClient(客戶端代理)

服務端核心:jsonRPCServer

class jsonRPCServer {
    public static function handle($object) {
        // 1. 校驗請求
        if ($_SERVER['REQUEST_METHOD'] !== 'POST' ||
            empty($_SERVER['CONTENT_TYPE']) ||
            $_SERVER['CONTENT_TYPE'] !== 'application/json') {
            return false;
        }

        // 2. 解析輸入
        $request = json_decode(file_get_contents('php://input'), true);
        if (!$request || !isset($request['method'], $request['params'], $request['id'])) {
            return false;
        }

        // 3. 執行方法
        try {
            if ($result = @call_user_func_array([$object, $request['method']], $request['params'])) {
                $response = ['id'=>$request['id'], 'result'=>$result, 'error'=>null];
            } else {
                $response = ['id'=>$request['id'], 'result'=>null,
                             'error'=>'unknown method or incorrect parameters'];
            }
        } catch (Exception $e) {
            $response = ['id'=>$request['id'], 'result'=>null, 'error'=>$e->getMessage()];
        }

        // 4. 輸出響應
        if (!empty($request['id'])) { // 通知類無需響應
            header('Content-Type: application/json');
            echo json_encode($response);
        }
        return true;
    }
}

客戶端核心:jsonRPCClient

class jsonRPCClient {
    private $url, $id = 1, $debug = false, $notification = false;

    public function __construct($url, $debug = false) {
        $this->url = $url;
        $this->debug = $debug;
    }

    public function __call($method, $params) {
        if (!is_scalar($method)) throw new Exception('Method name must be scalar');
        $params = array_values((array)$params);

        $request = ['method'=>$method, 'params'=>$params, 'id'=>$this->notification ? null : $this->id++];
        $requestJson = json_encode($request);

        $opts = ['http'=>['method'=>'POST', 'header'=>'Content-Type: application/json', 'content'=>$requestJson]];
        $context = stream_context_create($opts);
        $result = file_get_contents($this->url, false, $context);
        if ($result === false) throw new Exception('Unable to connect to '.$this->url);

        $response = json_decode($result, true);
        if (!$this->notification) {
            if ($response['id'] !== $request['id']) throw new Exception('Response ID mismatch');
            if ($response['error'] !== null) throw new Exception('RPC Error: '.$response['error']);
            return $response['result'];
        }
        return true;
    }
}

完整調用示例

1. 服務端入口 server.php

require 'jsonRPCServer.php';
require 'MemberService.php'; // 業務類
$service = new MemberService();
jsonRPCServer::handle($service) or print 'no request';

2. 業務類 MemberService.php

class MemberService {
    public function getName() { return 'Hello JSON-RPC'; }
    public function getUser($id) { return ['id'=>$id, 'name'=>'User'.$id]; }
}

3. 客戶端調用 client.php

require 'jsonRPCClient.php';
$client = new jsonRPCClient('https://localhost/rpc/server.php', true); // 開啟調試

try {
    echo $client->getName()."\n";           // Hello JSON-RPC
    print_r($client->getUser(123));         // Array([id]=>123 [name]=>User123)
} catch (Exception $e) {
    echo 'Error: '.$e->getMessage();
}

進階擴展建議

  1. 批量請求:支援 [{id:1,method...}, {id:2,method...}] 數組請求,減少 HTTP 開銷。
  2. 異步/通知:$client->setRPCNotification(true) 發送無 ID 請求,不等待響應。
  3. 認證授權:在 HTTP Header 或 params 中傳遞 Token,Server 端驗證。
  4. Swoole/RoadRunner:替換阻塞式 file_get_contents 為異步 HTTP 客戶端,支援高併發。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved