<?php
declare(strict_types=1);
* +----------------------------------------------------------------------
* | ThinkAdmin Plugin for ThinkAdmin
* +----------------------------------------------------------------------
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
* +----------------------------------------------------------------------
* | 官方网站: https://thinkadmin.top
* +----------------------------------------------------------------------
* | 开源协议 ( https://mit-license.org )
* | 免责声明 ( https://thinkadmin.top/disclaimer )
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
* +----------------------------------------------------------------------
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
* +----------------------------------------------------------------------
*/
namespace think\admin\extend;
use think\App;
use think\Container;
use think\exception\HttpResponseException;
* JsonRpc 服务端.
* @class JsonRpcServer
*/
class JsonRpcServer
{
* 当前App对象
* @var App
*/
protected $app;
* JsonRpcServer constructor.
*/
public function __construct(App $app)
{
$this->app = $app;
}
* 静态实例对象
* @param array $args
* @return static
*/
public static function instance(...$args): JsonRpcServer
{
return Container::getInstance()->make(static::class, $args);
}
* 设置监听对象
* @param mixed $object
*/
public function handle($object)
{
if ($this->app->request->method() !== 'POST' || $this->app->request->contentType() !== 'application/json') {
$this->printMethod($object);
} else {
$request = json_decode(file_get_contents('php://input'), true) ?: [];
if (empty($request)) {
$error = ['code' => '-32700', 'message' => lang('Syntax parsing error.'), 'meaning' => lang('Invalid JSON parameter.')];
$response = ['jsonrpc' => '2.0', 'id' => '0', 'result' => null, 'error' => $error];
} elseif (!isset($request['id']) || !isset($request['method']) || !isset($request['params'])) {
$error = ['code' => '-32600', 'message' => lang('Invalid request.'), 'meaning' => lang('Invalid JSON parameter.')];
$response = ['jsonrpc' => '2.0', 'id' => $request['id'] ?? '0', 'result' => null, 'error' => $error];
} else {
try {
if ($object instanceof \Exception) {
throw $object;
}
if (strtolower($request['method']) === '_get_class_name_') {
$response = ['jsonrpc' => '2.0', 'id' => $request['id'], 'result' => get_class($object), 'error' => null];
} elseif (method_exists($object, $request['method'])) {
$result = call_user_func_array([$object, $request['method']], $request['params']);
$response = ['jsonrpc' => '2.0', 'id' => $request['id'], 'result' => $result, 'error' => null];
} else {
$info = lang('method not exists: %s::%s', [class_basename($object), $request['method']]);
$error = ['code' => '-32601', 'message' => $info, 'meaning' => lang('The method does not exist or is invalid.')];
$response = ['jsonrpc' => '2.0', 'id' => $request['id'], 'result' => null, 'error' => $error];
}
} catch (\think\admin\Exception $exception) {
$error = ['code' => $exception->getCode(), 'message' => lang($exception->getMessage()), 'meaning' => lang('Business Exception.')];
$response = ['jsonrpc' => '2.0', 'id' => $request['id'], 'result' => $exception->getData(), 'error' => $error];
} catch (\Exception $exception) {
$error = ['code' => $exception->getCode(), 'message' => lang($exception->getMessage()), 'meaning' => lang('System Exception.')];
$response = ['jsonrpc' => '2.0', 'id' => $request['id'], 'result' => null, 'error' => $error];
}
}
throw new HttpResponseException(json($response));
}
}
* 打印输出对象方法.
* @param mixed $object
*/
protected function printMethod($object)
{
try {
$object = new \ReflectionClass($object);
echo "<h2>{$object->getName()}</h2><hr>";
foreach ($object->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
if (stripos($method->getName(), '_') === 0) {
continue;
}
$params = [];
foreach ($method->getParameters() as $parameter) {
$type = $parameter->getType();
if ($type instanceof \ReflectionType) {
$type = $type->getName();
}
$params[] = ($type ? "{$type} $" : '$') . $parameter->getName();
}
$params = count($params) > 0 ? join(', ', $params) : '';
echo '<div style="color:#666">' . nl2br($method->getDocComment() ?: '') . '</div>';
echo "<div style='color:#00E'>{$object->getShortName()}::{$method->getName()}({$params})</div><br>";
}
} catch (\Exception $exception) {
echo "<h3>[{$exception->getCode()}] {$exception->getMessage()}</h3>";
}
}
}