jsonRPC调用加载动态对象

adminppper

新手勿喷,大佬们。

我因为要使用 动态加载对象,而不是调用静态方法,所以我改造了一下,官方肯定也能做到,但是或许有别的考虑所有没有上线这种办法,想问问官方为啥不让他调用动态对象呢?

如果不喜欢,请联系我删除。。

改造1:

服务端的:start.php的部分代码

 $statistic_address = 'udp://127.0.0.1:55656';
    // 判断数据是否正确
    if(empty($data['class']) || empty($data['method']) || !isset($data['param_array']))
    {
        // 发送数据给客户端,请求包错误
       return $connection->send(array('code'=>400, 'msg'=>'bad request', 'data'=>null));
    }
    // 获得要调用的类、方法、及参数
    $class = $data['class'];
    //获取实例化对象的时候构造函数所要携带的参数
    $class_param= $data['class_param']??null;
    $method = $data['method'];
    $param_array = $data['param_array'];

    StatisticClient::tick($class, $method);
    $success = false;
    // 判断类对应文件是否载入

    //注册自动加载对象机制
    spl_autoload_register(function ($class)use ($method,$statistic_address,$connection){
        //根据   Folder1.NameSpace.Class1 解析,加载/Services/Folder1/NameSpace/Class1.php
        $disk_path=__DIR__.'/Services/'.str_replace('\\','/',$class).'.php';

        //如果文件不存在
        if(!is_file($disk_path)){
            $code=500;
            $msg='文件不存在'.$disk_path;
            StatisticClient::report($class, $method, false, $code, $msg, $statistic_address);
            // 发送数据给客户端 类不存在
            return $connection->send(['code'=>$code, 'msg'=>$msg, 'data'=>null]);
        }

        //这里只能加载一次,否则出现重复定义
        require_once $disk_path;
    });

    $class_=explode('.',$class);
    $class_name=array_pop($class_);//获取到对象名
    $class_namespace=implode('\\',$class_);//获取对象命名空间
    $obj=$class_namespace.'\\'.$class_name;// Folder1\NameSpace\Class1();

    try{
        //获取反射对象
        $con=new ReflectionClass($obj);
        //利用反射机制加载,并且传入非限定数量参数 __construct($arg1,$arg2...)
        $new=$con->newInstanceArgs($class_param);
        //调用 对象的method方法,并且动态传入非限定数量参数$param_array
        $ret=call_user_func_array([$new,$method],$param_array);
        //释放变量
        unset($new);
    }catch (Exception $e){
        //捕捉到异常
        $code = $e->getCode() ? $e->getCode() : 500;
        StatisticClient::report($class, $method, $success, $code, $e, $statistic_address);

        if(strpos($e->getMessage(),'not exist')!==false){
            $msg='捕捉到异常:加载文件成功!但是实例化对象'.$obj.'失败,请注意命名空间';
        }else{
            $msg='捕捉到异常:加载文件成功!实例化对象成功!执行出错'.$e->getMessage();
        }
        return $connection->send(['code'=>$code, 'msg'=>$msg, 'data'=>$e]);
    }catch (Error $e){
        //捕捉到错误
        $code = $e->getCode() ? $e->getCode() : 500;
        $msg='捕捉到错误'.$e->getMessage();
        return $connection->send(['code'=>$code, 'msg'=>$msg, 'data'=>$e]);

    }

    return $connection->send(['code'=>0, 'msg'=>'ok', 'data'=>$ret]);

修改RPClient.php 客户端文件

/**
     * 获取一个实例
     * @param string $service_name
     * @return instance of RpcClient
     */
    public static function instance($service_name,array $serviceParam=[])
    {
        if(!isset(self::$instances[$service_name]))
        {
            self::$instances[$service_name] = new self($service_name,$serviceParam);
        }
        return self::$instances[$service_name];
    }

    /**
     * 构造函数
     * @param string $service_name
     */
    protected function __construct($service_name,$serviceParam)
    {
        $this->serviceParam=$serviceParam;
        $this->serviceName = $service_name;
    }

客户端调用


// 配置服务端列表
RpcClient::config($address_array);

// qq.qrlogin对应  /JsonRpc/Services/qq/qrlogin.php 中的qrlogin类
//第二个参数填写 __construct($arg1,$arg2=[],$arg3)  但是不能传入 资源类对象
$user_client = RpcClient::instance('qq.qrlogin',['arg1','arg2'=>[],'arg3'=>123]);

$a=$user_client->getqrpic('1','22',[]);
2036 1 0
1个回答

walkor

静态方法性能好一些,没有其它考虑。
有很多用户改造成了非静态调用,没有问题。

  • 暂无评论
年代过于久远,无法发表回答
🔝