PHP-CI框架中如何实现类库的自动加载及别名逻辑处理

缘由app/controllers/Index.php中有如下代码 public function disable(){ $this->yredis->set('name','tb'); var_dump($this->yredis->get('name')); $this->load->view('welcome_message'); }发现这个yredis没有load,怎么来的?翻翻手册,有自动加载配置 在app/config/autoload.php中配置,部分内容如下| -------------------------------------------------------------------| Auto-load Libraries| -------------------------------------------------------------------| These are the classes located in system/libraries/ or your| application/libraries/ directory, with the addition of the| 'database' library, which is somewhat of a special case.|| Prototype:|| $autoload['libraries'] = array('database', 'email', 'session');|| You can also supply an alternative library name to be assigned| in the controller:|| $autoload['libraries'] = array('user_agent' => 'ua');*/$autoload['libraries'] = array('Yredis','validation'=>'sn');追踪一下那么他这个自动加载是在代码内如何实现的呢?肯定从头$CI大对象来看。在system/core/Controller.php中,有如下两句 $this->load =& load_class('Loader', 'core');$this->load->initialize();通过common.php中定义的load_class方法,加载了loader类。不得不说ci的核心基本都在这里了。(这个load还是个未定义的属性么...?)我们去看system/core/Loader.php中的initialize方法,不过load的时候肯定是先加载__construct方法 ...

May 28, 2019 · 5 min · jiezi

CodeIgniter框架中抽取部分类库做问题追踪的思路

背景由于各种原因,没有接入完整的调用链追踪,(┬_┬)。但是我们自身再通过php的curl调用各端接口时,会请求多次。那么有没有一种方法可以在不植入业务代码的前提下,捕捉到这些curl的请求呢。显然,ci有基本的hook操作。我们可以在相关节点时,可选择的把这些收集到到的通过异步的方式发送给指定的监听者。 curl类库(部分代码)class Ycurl{ public $resource_arr; public static $resource_id = 0; //资源(resource handle id public $save_requests = true;//是否保存,默认全部保存 public $requests = array();//n次请求参数、返回参数,错误(如果有) public $request_counts = 0;//总的请求次数,可能一个页面调用多次 public $send_redis_email = false;//是否需要以异常方式发送邮件 ... $ret = curl_exec($ch); $curl_info_arr = curl_getinfo($ch); $this->request_counts += 1; if ($this->save_requests === true) { $arg_list = func_get_args(); $this->requests[$resource_id]['url'] = $curl_info_arr['url']; $this->requests[$resource_id]['req_params'] = json_encode([$arg_list], 320); $this->requests[$resource_id]['response'] = $ret; $this->requests[$resource_id]['http_code'] = $curl_info_arr['http_code']; $this->requests[$resource_id]['is_error'] = curl_error($ch); $this->requests[$resource_id]['total_time'] = $curl_info_arr['total_time']; $this->requests[$resource_id]['primary_ip'] = $curl_info_arr['primary_ip']; if($this->send_redis_email){ redis_list_add(json_encode($this->requests,320)); } }hooks config从ci对象中抽取curl对象,其他自定义的对象也可以同样思路。 ...

April 23, 2019 · 2 min · jiezi

CodeIgniter3.0+框架自定义异常处理实现

背景ci3.0框架核心代码自动实现了异常,并实现了抛出的对应页面和方法,对于一些个性化需求特别是接口类型的应用,会不合适。因此需要在不改版核心代码 (system目录下文件),来改变对异常及404等相关异常的处理。方法说明ci框架3.0比2.0有比较大的改动,其中之一就是对异常的处理。以下是CodeIgniter-3.1.8\system\core\CodeIgniter.php 中对异常处理的部分代码/* * —————————————————— * Define a custom error handler so we can log PHP errors * —————————————————— / set_error_handler(’_error_handler’); set_exception_handler(’_exception_handler’); register_shutdown_function(’_shutdown_handler’);…以上括号内的方法均在common.php中以function_exists为前提声明。…if ( ! function_exists(’_exception_handler’)){…代码实现我们简单粗暴的在项目入口文件index.php中重写以下方法/* * 推送到redis 异常队列 * @time 2019/3/21 15:29 * @author * @param $msg * @return bool|int|string /function redis_list_add($msg){ ini_set(‘default_socket_timeout’, -1); $v = explode(’:’, $_SERVER[‘SITE_REDIS_SERVER’]); if (is_array($v) && !empty($v)) { try { $redis = new redis(); $redis->pconnect($v[0], $v[1]); $trace = $_SERVER[‘SERVER_NAME’] . " exception\n"; $trace .= “clint ip is {$_SERVER[‘REMOTE_ADDR’]} " . “,server is " . $_SERVER[‘SERVER_NAME’] . “(” . $_SERVER[‘SERVER_ADDR’] . “)”."\n”; $trace.= “path is “.(isset($_SERVER[‘REQUEST_URI’])?$_SERVER[‘REQUEST_URI’]:“empty”)."\n”; $trace .= “request params is =” . print_r($_POST, true); return $redis->LPUSH(‘CC_PHP_ERROR_WARNING’, $trace . $msg); } catch (Exception $e) { return $e->getMessage(); } }}/* * 优先重写common.php中对应方法 * @time 2019/3/21 16:19 * @author * @param $severity * @param $message * @param $filepath * @param $line /function _error_handler($severity, $message, $filepath, $line){ $is_error = (((E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR | E_STRICT) & $severity) === $severity); if ($is_error) { $error_msg = ($message . “\n” . $filepath . “\n” . $line); redis_list_add($error_msg); exit(json_encode([‘success’ => ‘-1’, ‘code’ => 501, ‘msg’ => ’error’])); }}/* * 捕获php本身语法,对象调用,参数类型传递等错误 * 优先重写common.php中对应方法 * ParseError,object(Error),TypeError,Error * @time 2019/3/20 18:33 * @author * @param $exception /function _exception_handler($exception){ $_tmp =& load_class(‘Exceptions’, ‘core’); if (!empty($exception)) { $error_msg = ($exception->getMessage() . “\n” . $exception->getTraceAsString()); redis_list_add($error_msg); exit(json_encode([‘success’ => ‘-1’, ‘code’ => 501, ‘msg’ => ’exception’])); }}/* * 优先重写common.php中对应方法 * require_once(’no_exists.php’) * @time 2019/3/21 9:49 * @author /function _shutdown_handler(){ $last_error = error_get_last(); if (isset($last_error) && ($last_error[’type’] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING))) { redis_list_add($msg = $last_error[‘message’] . “\n” . $last_error[‘file’] . “\n” . $last_error[’line’] . “\n”); exit(json_encode([‘success’ => ‘-1’, ‘code’ => 501, ‘msg’ => ‘shutdown’])); }}/* * 优先重写common.php中对应方法 * ci 框架内部的load异常、config异常、loader异常等会自动抛出, * 但common.php中的函数定义之类错误无法捕捉 * @time 2019/3/20 18:46 * @author * @param $message * @param int $status_code /function show_error($message){ redis_list_add($message); exit(json_encode([‘success’ => ‘-1’, ‘code’ => ‘503’, ‘msg’ => ‘ci_exception_1’]));}/* * 优先重写common.php中对应方法 * @time 2019/3/21 15:34 * @author * @param string $page */function show_404($page = ‘’){ redis_list_add(“url: " . $page . " not found”); exit(json_encode([‘success’ => ‘-1’, ‘code’ => ‘404’, ‘msg’ => ‘Not Found’]));}延伸在基类中可以处理错误等级区分对待 ...

March 27, 2019 · 2 min · jiezi