定制 n-car/rpc-php-toolkit 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

n-car/rpc-php-toolkit

最新稳定版本:v1.0.3

Composer 安装命令:

composer require n-car/rpc-php-toolkit

包简介

PHP JSON-RPC 2.0 client/server toolkit with middleware, schema validation, batch processing, introspection, and optional Safe Mode

README 文档

README

License

PHP JSON-RPC 2.0 client/server toolkit with middleware, schema validation, batch processing, introspection, and optional RPC Toolkit Safe Mode.

Table of Contents

Features

Core Features

  • JSON-RPC 2.0 Compliance: Fully adheres to JSON-RPC 2.0 specification
  • Server & Client Support: Provides server endpoints and PHP & JavaScript client classes
  • Async Support: Handles asynchronous operations with Promises
  • BigInt & Date Serialization: Robust serialization/deserialization with timezone support
  • Cross-Platform: Works in both browser and PHP server environments
  • Error Handling: Comprehensive error responses with sanitization options

Operational Features

  • Structured Logging: Configurable logging with multiple transports and levels
  • Middleware System: Extensible middleware with built-in rate limiting, CORS, auth
  • Schema Validation: JSON Schema validation with schema builder utilities
  • Batch Processing: Batch request handling with concurrent processing
  • Health & Metrics: Built-in health check endpoints and metrics
  • Security Controls: Method whitelisting, authentication hooks, and error sanitization
  • Request Diagnostics: Request timing, caching support, and optimized serialization

Installation

After publication, install from Packagist with Composer:

composer require n-car/rpc-php-toolkit

Quick Start

Basic Setup

<?php
require_once 'vendor/autoload.php';

use RpcPhpToolkit\RpcEndpoint;

// Context object to pass to method handlers
$context = ['database' => $db, 'config' => $config];

// Create the RPC endpoint
$rpc = new RpcEndpoint('/api/rpc', $context);

// Add methods
$rpc->addMethod('getTime', function($params, $context) {
    return [
        'timestamp' => time(),
        'datetime' => date('c')
    ];
});

$rpc->addMethod('echo', function($params, $context) {
    return ['message' => $params['message'] ?? 'Hello World!'];
});

// Handle requests
$input = file_get_contents('php://input');
echo $rpc->handleRequest($input);

PHP Client

use RpcPhpToolkit\Client\RpcClient;

// Create client
$client = new RpcClient('http://localhost:8000/api/rpc', [], [
    'timeout' => 30,
    'verifySSL' => true,
    'safeEnabled' => false  // Enable safe serialization if needed
]);

// Single call
$result = $client->call('getTime');

// Call with parameters
$result = $client->call('echo', ['message' => 'Hello!']);

// With authentication
$client->setAuthToken('your-token-here');
$result = $client->call('protected.method');

// Batch request
$results = $client->batch([
    ['method' => 'getTime', 'id' => 1],
    ['method' => 'echo', 'params' => ['message' => 'Test'], 'id' => 2]
]);

// Notification (no response)
$client->notify('log.event', ['data' => 'something']);

JavaScript Client

// Import ES Module
import RpcClient from './rpc-client.mjs';

// Or classic script loading
// <script src="rpc-client.js"></script>

const client = new RpcClient('http://localhost:8000/api/rpc');

// Single call
const result = await client.call('getTime');

// Call with parameters
const echo = await client.call('echo', {message: 'Hello!'});

// Batch request
const results = await client.batch([
    {method: 'getTime', id: 1},
    {method: 'echo', params: {message: 'Test'}, id: 2}
]);

Advanced Usage

Middleware

use RpcPhpToolkit\Middleware\RateLimitMiddleware;
use RpcPhpToolkit\Middleware\AuthMiddleware;
use RpcPhpToolkit\Middleware\CorsMiddleware;

// CORS support
$rpc->getMiddleware()->add(
    new CorsMiddleware([
        'origin' => '*',  // or specific origin(s)
        'methods' => ['GET', 'POST', 'OPTIONS'],
        'headers' => ['Content-Type', 'Authorization', 'X-RPC-Safe-Enabled', 'X-RPC-Safe'],
        'credentials' => false,
        'maxAge' => 86400
    ]),
    'before'
);

// Rate limiting
$rpc->getMiddleware()->add(
    new RateLimitMiddleware(100, 60, 'ip'), 
    'before'
);

// Authentication
$rpc->getMiddleware()->add(
    new AuthMiddleware(function($token) {
        return $this->authenticateUser($token);
    }),
    'before'
);

Schema Validation

$rpc->addMethod('createUser', function($params, $context) {
    // User creation logic
    return ['id' => 123, 'name' => $params['name']];
}, [
    'type' => 'object',
    'properties' => [
        'name' => [
            'type' => 'string',
            'minLength' => 2,
            'maxLength' => 50
        ],
        'email' => [
            'type' => 'string',
            'format' => 'email'
        ]
    ],
    'required' => ['name', 'email']
]);

Introspection Methods

Enable introspection to expose metadata about registered methods via reserved __rpc.* methods:

// Create endpoint with introspection enabled
$rpc = new RpcEndpoint('/api/rpc', $context, [
    'enableIntrospection' => true,      // Enable __rpc.* methods (default: false)
    'introspectionPrefix' => '__rpc'    // Prefix for introspection methods (configurable)
]);

// Register methods with public schemas
$rpc->addMethod('add', function($params, $context) {
    return $params['a'] + $params['b'];
}, [
    'schema' => [
        'type' => 'object',
        'properties' => [
            'a' => ['type' => 'number'],
            'b' => ['type' => 'number']
        ],
        'required' => ['a', 'b']
    ],
    'exposeSchema' => true,              // Make schema publicly queryable
    'description' => 'Add two numbers'   // Method description
]);

// Available introspection methods:

// __rpc.listMethods() → ["add", "multiply", ...]
$methods = $client->call('__rpc.listMethods');

// __rpc.describe(['method' => 'add']) → {name, schema, description}
$info = $client->call('__rpc.describe', ['method' => 'add']);

// __rpc.describeAll() → [{name, schema, description}, ...]
$allPublic = $client->call('__rpc.describeAll');

// __rpc.version() → {toolkit, version, phpVersion}
$version = $client->call('__rpc.version');

// __rpc.capabilities() → {batch, introspection, validation, ...}
$capabilities = $client->call('__rpc.capabilities');

Security Notes:

  • Methods with exposeSchema: false are hidden from __rpc.describe
  • Introspection methods cannot describe themselves
  • Users cannot register methods starting with the introspection prefix
  • The prefix is configurable to avoid conflicts with existing methods

See examples/introspection/ for complete examples.

Structured Logging

use RpcPhpToolkit\Logger\Logger;
use RpcPhpToolkit\Logger\FileTransport;

$logger = new Logger([
    'level' => Logger::INFO,
    'transports' => [
        new FileTransport([
            'filename' => 'logs/rpc.log',
            'format' => 'json'
        ])
    ]
]);

$rpc = new RpcEndpoint('/api/rpc', $context, [
    'logger' => $logger
]);

JavaScript Client

Browser

<!DOCTYPE html>
<html>
<head>
    <script src="rpc-client.js"></script>
</head>
<body>
    <script>
        const client = new RpcClient('http://localhost:8000/api/rpc');
        
        client.call('getTime').then(result => {
            console.log('Server time:', result);
        });
    </script>
</body>
</html>

Node.js

const RpcClient = require('./rpc-client.js');

const client = new RpcClient('http://localhost:8000/api/rpc');

async function test() {
    try {
        const result = await client.call('getTime');
        console.log(result);
    } catch (error) {
        console.error('RPC Error:', error.message);
    }
}

ES Modules

import RpcClient from './rpc-client.mjs';

const client = new RpcClient('http://localhost:8000/api/rpc');
const result = await client.call('getTime');

Examples

The examples/ folder contains:

  • basic-server.php - Complete RPC server with all middleware
  • client.php - Example PHP client with all tests
  • browser-test.html - Interactive browser testing

Quick start test server

cd examples
php -S localhost:8000 basic-server.php

Then open browser-test.html in your browser to test the interface.

API Reference

RpcEndpoint

Constructor

new RpcEndpoint(string $endpoint = '/rpc', mixed $context = null, array $options = [])

Main Methods

  • addMethod(string $name, callable $handler, array $schema = null, array $middleware = []): self
  • removeMethod(string $name): self
  • handleRequest(string $input): string
  • getLogger(): ?Logger
  • getMiddleware(): ?MiddlewareManager

Configuration Options

$options = [
    'sanitizeErrors' => true,        // Sanitize errors in production
    'enableBatch' => true,           // Enable batch requests
    'enableLogging' => true,         // Enable logging
    'enableValidation' => true,      // Enable schema validation
    'enableMiddleware' => true,      // Enable middleware system
    'maxBatchSize' => 100,          // Maximum batch size
    'timeout' => 30,                // Timeout in seconds
    'safeEnabled' => false,         // Enable safe type serialization (S:, D:, n markers)
    'requireSafeHeader' => false,   // Require X-RPC-Safe-Enabled when Safe Mode is enabled
    'warnOnUnsafe' => true,         // Warn when BigInt/Date serialized without safe mode
    'errorProperties' => [...]      // Error properties to include
];

Safe Serialization Mode

Like the Express version, PHP toolkit supports Safe Mode for type-safe serialization. Standard JSON-RPC 2.0 remains the default when safeEnabled is false.

// Enable safe mode with explicit HTTP header negotiation
$rpc = new RpcEndpoint('/api/rpc', $context, [
    'safeEnabled' => true,
    'requireSafeHeader' => true
]);

// Client with safe mode
$client = new RpcClient('http://localhost:8000/api/rpc', [], [
    'safeEnabled' => true
]);

How it works:

  • Strings: Prefixed with S:"hello" becomes "S:hello"
  • Dates: Prefixed with D: → ISO string becomes "D:2025-11-26T10:30:00Z"
  • Large integers: Suffixed with n9007199254740992 becomes "9007199254740992n"
  • HTTP negotiation: Safe clients and servers exchange X-RPC-Safe-Enabled: true

This prevents ambiguity when deserializing JSON, especially useful when:

  • You control both client and server
  • Type safety is critical
  • Working with BigInt or Date values

Use RpcSafeEndpoint and RpcSafeClient when both sides are RPC Toolkit implementations and Safe Mode should be enabled by default. PHP preserves BigInt markers as strings; it does not expose JavaScript BigInt semantics.

Default behavior (safeEnabled: false):

  • Maximum JSON-RPC 2.0 compatibility
  • Standard serialization without prefixes
  • Warnings logged when BigInt/Date detected (disable with warnOnUnsafe: false)

JSON-RPC Error Codes

  • -32600 - Invalid Request
  • -32601 - Method not found
  • -32602 - Invalid params
  • -32603 - Internal error
  • -32000 to -32099 - Implementation specific errors

Security

  • Error Sanitization: In production, set sanitizeErrors: true
  • Rate Limiting: Use RateLimitMiddleware to limit requests
  • Authentication: Implement AuthMiddleware for protected methods
  • Input Validation: Use schema validation for all parameters
  • CORS: Configure CORS appropriately for browser clients

Performance

  • Batch Processing: Use batch requests for multiple operations
  • Efficient Middleware: Middleware is executed in optimized order
  • Async Logging: Configurable logger for different levels
  • Caching: Implement caching at middleware level if needed

⚠️ SSL and self-signed certificates in development (PHP)

If you need to connect to a server with a self-signed certificate during development in PHP, you can disable SSL verification for testing purposes (not recommended in production). For example, with cURL:

$ch = curl_init('https://localhost:8000/api/rpc');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Disable certificate verification (development only)
$response = curl_exec($ch);
curl_close($ch);

Or with Guzzle:

$client = new \GuzzleHttp\Client([
    'verify' => false // Disable certificate verification (development only)
]);
$response = $client->get('https://localhost:8000/api/rpc');

Warning: Disabling SSL verification exposes you to security risks. Use only in local development environments.

Contributing

  1. Fork the project
  2. Create a feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

This project is distributed under the MIT License. See the LICENSE file for details.

🔗 Related Projects

RPC PHP Toolkit - A JSON-RPC 2.0 implementation for PHP with middleware, schema validation, batch processing, introspection, and optional Safe Mode.

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 3
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-11

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固