getInfo(1); //实例化model中的model实现 * Model("share_to")->find(1); //实例化库,ModelBase-Model基类直接调用库 */ function Model($name = '', $tablePrefix = '', $connection = '') { static $cache = array(); if($name === '_destroy_'){$cache = array();return;} // 清除缓存; $guid = strtolower($tablePrefix . '_' . $name); if(is_string($connection)){ $guid .= '_'.$connection; }else if($connection && is_array($connection)){ return new ModelBase($name, $tablePrefix, $connection); } // 没有该类,则为表名或空model if(!$connection){$connection = $GLOBALS['config']['database'];} if(isset($cache[$guid])) return $cache[$guid]; if($name){//有该类的情况(已经引入了类) $name = strtoupper($name[0]).substr($name,1); $modelName = $name.'Model'; if( class_exists($modelName) ){ $cache[$guid] = new $modelName('',$tablePrefix, $connection); return $cache[$guid]; } } $cache[$guid] = new ModelBase($name, $tablePrefix, $connection); return $cache[$guid]; } /** * action函数用于实例化一个控制器文件的Action * @param string $name 控制器名称 * @return Object * * eg: 控制器/model/ 插件方法/插件模块方法; * Action('user.index')->appConfig(); * Action('UserModel')->count(); * * Action('chartPlugin')->view(); //chartPlugin; plugin/chart/app.php; * Action('chartPlugin.user.view')->listData(); // chartUserView;plugin/chart/controller/user/view.chass.php; * Action('chartPlugin.userModel')->listData(); // chartUserModel; */ function Action($name = '') { static $_cache = array(); $nameBefore = $name; if(isset($_cache[$nameBefore])) return $_cache[$nameBefore]; $name = trim(str_replace('/','.',$name),'/'); $arr = explode('.',$name); $mod = strtolower($arr[0]); if( substr($mod,-6) == 'plugin'){ $name = substr($arr[0],0,-6); $className = $name.'Plugin'; $file = 'app.php'; if(isset($arr[1]) && substr(strtolower($arr[1]),-5) == 'model'){ $className = $name.$arr[1];// chartUserModel $file = "model/".$arr[1].".class.php"; }else if(count($arr) == 3){ $className = $name.$arr[1].$arr[2];//chartUserView $file = "controller/".$arr[1]."/".$arr[2].".class.php"; } $file = PLUGIN_DIR.$name.'/'.$file; }else if( substr($mod,-5) == 'model'){ $name = substr($arr[0],0,-5); return Model($name); }else{ $className = $arr[0].$arr[1]; $file = CONTROLLER_DIR.$arr[0].'/'.$arr[1].'.class.php'; } $guid = strtolower($className); if (isset($_cache[$guid])) return $_cache[$guid]; if (is_file($file)){ include_once($file); } if (!class_exists($className)) { return actionCallError("[$name => $className] class not exists!"); } $_cache[$guid] = new $className(); $_cache[$nameBefore] = $_cache[$guid]; return $_cache[$guid]; } /** * 调用控制器,插件方法,或直接调用函数; * * 参数合并为数组; 类似于js的 apply($object,$args); * ActionApply('user.index.appConfig',array("add",'123')); * * 支持: * 1. 直接调用:函数,类方法,静态类方法;eg: 'clear_html', array($this,'pathInfo'), array('IO','exist'); * 2. 控制器方法; eg: 'user.index.appConfig'; * 3. 模型方法; eg: 'sourceModel.targetSpaceUpdate'; * * 4. 插件方法; eg: 'testPlugin.echoJs'; * 4. 插件模型方法; eg: 'testPlugin.chartUserModel.getInfo'; */ function ActionApply($action,$args=array()){ static $_cache = array(); if(is_array($action)){ //可调用方法; array($this,'log'); return call_user_func_array($action,$args); } if(isset($_cache[$action])){ return call_user_func_array($_cache[$action],$args); } if(function_exists($action)){ //全局函数; $_cache[$action] = $action; }else{ $arrs = explode('.',$action); $arrs = is_array($arrs) ? $arrs : array(); $className = substr($action,0,strrpos($action,'.')); $method = $arrs[count($arrs) - 1]; $obj = Action($className); if(!$method || !is_object($obj)){ return actionCallError("$action method not exists!"); } // 类查存在,最后一个不是方法时,默认将第三个参数作为参数; 支持多参数调用方式; // http://127.0.0.1/kod/kodbox/?test/test/index/page/1/limit/10 if(!method_exists($obj,$method)){ if(!$arrs[2] || !method_exists($obj,$arrs[2])){ return actionCallError("$action method not exists!"); } $method = $arrs[2]; } $_cache[$action] = array($obj,$method); } return call_user_func_array($_cache[$action], $args); } function actionCallError($msg){ return false; // think_exception($msg,false); write_log($msg."\n".get_caller_msg(),'error'); return false; } /** * 调用控制器,插件方法,或直接调用函数; * 参数合并为数组; 类似于js的 call($object,$arg1,$arg2,...); * * ActionCall('user.index.appConfig',"add",'123'); * ActionCall('UserModel.count'); * * ActionCall('chartPlugin.view','5'); * ActionCall('chartPlugin.user.view.list'); * ActionCall('chartPlugin.userModel.list'); */ function ActionCall($action){ $args = array_slice(func_get_args(),1); return ActionApply($action,$args); } function ActionCallApi($uri,$param='',$allowExec=true){ $paramStr = $param; if(is_array($param)){ $paramStr = ''; foreach($param as $key => $value){ $value = is_array($value) ? json_encode($value) : $value; $value = is_bool($value) ? intval($value) : $value; $paramStr .= '&'.$key.'='.rawurlencode($value); } } $token = Action('user.index')->accessToken(); $uri = str_replace('.','/',$uri).'&accessToken='.$token.$paramStr; $res = ''; $phpBin = phpBinCommand(); if($allowExec && $phpBin && function_exists('shell_exec')){ $command = $phpBin.' '.BASIC_PATH.'index.php '.escapeshellarg($uri); $res = shell_exec($command); } if(!$res){ $streamContext = stream_context_create(array('http'=>array('timeout'=>20,'method'=>"GET"))); $res = file_get_contents(APP_HOST.'index.php?'.$uri,false,$streamContext); } $json = json_decode($res,true); $result = is_array($json) ? $json:array('code'=>null,'data'=>$res); if(!$json){echo $res;} return $result; } /** * 调用控制器,插件方法,或直接调用函数; 拦截show_json退出;返回show_json的内容数组; * * 调用方法有多个show_json;默认返回第一个调用的结果; * 注: 为避免后续继续执行引起其他问题,需要在前面show_json前加上return (容易出bug,逐步废弃,用ActionCallResult替代) */ function ActionCallHook($action){ ob_start(); $args = array_slice(func_get_args(),1); $GLOBALS['SHOW_JSON_NOT_EXIT'] = 1; $result = ActionApply($action,$args); $echo = ob_get_clean(); $result = $echo ? json_decode($echo,true) : $result;// 优先使用输出内容; $GLOBALS['SHOW_JSON_NOT_EXIT_DONE'] = 0; $GLOBALS['SHOW_JSON_NOT_EXIT'] = 0; return $result; } /** * 调用控制器,插件方法,或直接调用函数; 并对show_json输出进行处理; */ function ActionCallResult($action,$resultParse){ $args = array_slice(func_get_args(),2); $GLOBALS['SHOW_JSON_RESULT_PARSE'] = $resultParse; ActionApply($action,$args); } function beforeShutdown(){ Hook::trigger('beforeShutdown'); } $_SERVER['BASIC_PATH'] = BASIC_PATH; $_SERVER['LIB_DIR'] = LIB_DIR; // https://www.jianshu.com/p/1a443d542219; function beforeShutdownError($code=false,$msg='',$file='',$line=0){ switch ($code) { case E_PARSE: case E_ERROR: case E_CORE_ERROR: case E_COMPILE_ERROR: case E_USER_ERROR:$errorType = 'Fatal Error';break; case E_WARNING: case E_USER_WARNING: case E_COMPILE_WARNING: case E_RECOVERABLE_ERROR:$errorType = 'Warning';break; case E_STRICT:$errorType = 'Strict';break; case E_NOTICE: case E_USER_NOTICE:$errorType = 'Notice';break; case E_DEPRECATED: case E_USER_DEPRECATED:$errorType = 'Deprecated';break; default :break; } if(!$errorType || $errorType == 'Notice' || $errorType=='Deprecated') return; $file = '/'.str_replace($_SERVER['BASIC_PATH'],'',$file); $error = $errorType.','.$msg.','.$file.','.$line; write_log($error."\n".get_caller_msg(1)."\n".json_encode($GLOBALS['in']),'error'); } function beforeShutdownFatalError($e){ think_exception($e); } $errorLevel = E_ALL^E_NOTICE^E_WARNING^E_DEPRECATED; register_shutdown_function('beforeShutdown'); // 结束时调用;有exit则不会走到该处; set_error_handler('beforeShutdownError',$errorLevel); // 错误处理记录;notice,warning,error等都会进入; if(function_exists('set_exception_handler')){ set_exception_handler('beforeShutdownFatalError'); // } stream_wrapper_register('kodio','StreamWrapperIO');