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

PHP 實作 JSON-RPC 2.0 簡易框架 (Server/Client)

     編輯:PHP 相關知識

PHP 實作 JSON-RPC 2.0 簡易框架 (Server/Client)

JSON-RPC 是輕量級遠端呼叫協定,以 JSON 為訊息格式,支援 HTTP 等傳輸層。本文提供一組極簡的 PHP Server/Client 實作,展示核心流程:請求解析、方法分派、回應封裝、錯誤處理。

1. Server 端 (jsonRPCServer.php)

<?php
class JsonRPCServer {
    public static function handle(object $service): bool {
        // 僅接受 POST + application/json
        if ($_SERVER['REQUEST_METHOD'] !== 'POST' ||
            empty($_SERVER['CONTENT_TYPE']) ||
            stripos($_SERVER['CONTENT_TYPE'], 'application/json') === false) {
            return false;
        }

        $input = file_get_contents('php://input');
        $request = json_decode($input, true);
        if (!isset($request['method'], $request['params'], $request['id'])) {
            self::respond(null, -32600, 'Invalid Request');
            return true;
        }

        try {
            if (!method_exists($service, $request['method'])) {
                throw new Exception('Method not found', -32601);
            }
            $result = call_user_func_array([$service, $request['method']], $request['params']);
            self::respond($request['id'], null, $result);
        } catch (Throwable $e) {
            self::respond($request['id'], $e->getCode() ?: -32603, $e->getMessage());
        }
        return true;
    }

    private static function respond($id, $error, $result = null): void {
        header('Content-Type: application/json');
        $payload = ['jsonrpc' => '2.0', 'id' => $id];
        if ($error !== null) {
            $payload['error'] = ['code' => $error, 'message' => $result];
        } else {
            $payload['result'] = $result;
        }
        echo json_encode($payload);
    }
}
?>

2. Client 端 (jsonRPCClient.php)

<?php
class JsonRPCClient {
    private string $url;
    private int $id = 1;
    private bool $debug = false;

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

    public function __call(string $method, array $params) {
        $request = [
            'jsonrpc' => '2.0',
            'method'  => $method,
            'params'  => array_values($params[0] ?? []), // 支援 call($method, [params...])
            'id'      => $this->id++,
        ];
        $payload = json_encode($request);

        $ctx = stream_context_create([
            'http' => [
                'method'  => 'POST',
                'header'  => 'Content-Type: application/json',
                'content' => $payload,
                'timeout' => 10,
            ]
        ]);

        $response = @file_get_contents($this->url, false, $ctx);
        if ($response === false) throw new Exception("Connection failed: {$this->url}");

        $data = json_decode($response, true);
        if ($this->debug) var_dump($data);

        if (isset($data['error'])) throw new Exception($data['error']['message'], $data['error']['code']);
        return $data['result'] ?? null;
    }
}
?>

3. 使用範例

// member.php - 服務類
class Member {
    public function getName(): string { return 'Hello JSON-RPC'; }
    public function add(int $a, int $b): int { return $a + $b; }
}

// server.php
require 'jsonRPCServer.php';
require 'member.php';
JsonRPCServer::handle(new Member()) or exit('No request');

// client.php
require 'jsonRPCClient.php';
$client = new JsonRPCClient('https://localhost/rpc/server.php');
echo $client->getName();        // Hello JSON-RPC
echo $client->add(3, 5);        // 8

擴充建議

  • 加入批次請求支援 (JSON-RPC 批次陣列)。
  • Server 端加入簽名驗證、速率限制、日誌記錄。
  • Client 端支援非同步 (Swoole/ReactPHP)、重試機制、連線池。
  • 生產環境建議使用成熟庫:reactphp/json-rpc、softcreatr/jsonrpc。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved