我因?yàn)橐褂?動態(tài)加載對象,而不是調(diào)用靜態(tài)方法,所以我改造了一下,官方肯定也能做到,但是或許有別的考慮所有沒有上線這種辦法,想問問官方為啥不讓他調(diào)用動態(tài)對象呢?
如果不喜歡,請聯(lián)系我刪除。。
改造1:
$statistic_address = 'udp://127.0.0.1:55656';
// 判斷數(shù)據(jù)是否正確
if(empty($data['class']) || empty($data['method']) || !isset($data['param_array']))
{
// 發(fā)送數(shù)據(jù)給客戶端,請求包錯(cuò)誤
return $connection->send(array('code'=>400, 'msg'=>'bad request', 'data'=>null));
}
// 獲得要調(diào)用的類、方法、及參數(shù)
$class = $data['class'];
//獲取實(shí)例化對象的時(shí)候構(gòu)造函數(shù)所要攜帶的參數(shù)
$class_param= $data['class_param']??null;
$method = $data['method'];
$param_array = $data['param_array'];
StatisticClient::tick($class, $method);
$success = false;
// 判斷類對應(yīng)文件是否載入
//注冊自動加載對象機(jī)制
spl_autoload_register(function ($class)use ($method,$statistic_address,$connection){
//根據(jù) 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);
// 發(fā)送數(shù)據(jù)給客戶端 類不存在
return $connection->send(['code'=>$code, 'msg'=>$msg, 'data'=>null]);
}
//這里只能加載一次,否則出現(xiàn)重復(fù)定義
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);
//利用反射機(jī)制加載,并且傳入非限定數(shù)量參數(shù) __construct($arg1,$arg2...)
$new=$con->newInstanceArgs($class_param);
//調(diào)用 對象的method方法,并且動態(tài)傳入非限定數(shù)量參數(shù)$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='捕捉到異常:加載文件成功!但是實(shí)例化對象'.$obj.'失敗,請注意命名空間';
}else{
$msg='捕捉到異常:加載文件成功!實(shí)例化對象成功!執(zhí)行出錯(cuò)'.$e->getMessage();
}
return $connection->send(['code'=>$code, 'msg'=>$msg, 'data'=>$e]);
}catch (Error $e){
//捕捉到錯(cuò)誤
$code = $e->getCode() ? $e->getCode() : 500;
$msg='捕捉到錯(cuò)誤'.$e->getMessage();
return $connection->send(['code'=>$code, 'msg'=>$msg, 'data'=>$e]);
}
return $connection->send(['code'=>0, 'msg'=>'ok', 'data'=>$ret]);
/**
* 獲取一個(gè)實(shí)例
* @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];
}
/**
* 構(gòu)造函數(shù)
* @param string $service_name
*/
protected function __construct($service_name,$serviceParam)
{
$this->serviceParam=$serviceParam;
$this->serviceName = $service_name;
}
// 配置服務(wù)端列表
RpcClient::config($address_array);
// qq.qrlogin對應(yīng) /JsonRpc/Services/qq/qrlogin.php 中的qrlogin類
//第二個(gè)參數(shù)填寫 __construct($arg1,$arg2=[],$arg3) 但是不能傳入 資源類對象
$user_client = RpcClient::instance('qq.qrlogin',['arg1','arg2'=>[],'arg3'=>123]);
$a=$user_client->getqrpic('1','22',[]);