php自动加载以及php简单路由功能php自动加载
前言:
项目中需要在workernman基础上自己完成基础框架,主要是将用户请求的api路由到具体控制器方法,同时用到的类需要自动加载,
原理:
路由:url形如admin/admin/login ,将url分割,获取到具体的类,方法,调用这个方法
自动加载:用spl_autoload_register,注册自动加载方法,通过命名空间找到文件路径,本项目中为了方便命名空间跟文件夹路径保持相同,比如 控制器admin的命名空间为
namespace Applications\admin\controller;项目目录结构如下
/Applications 应用目录
/Applications/admin admin模块
/Applications/admin/controller 控制器目录
/lib 类库文件
/vendor composer目录
实现
自动加载
/lib/Autoloader.php
将命名空间转化为文件路径
<?php namespace lib; /** * 自动加载 */ class Autoloader { public static function load($className) { $classPath = str_replace('\\', '/', $className); $classFile = __DIR__ .'/../'.$classPath.'.php'; if (is_file($classFile)) { require_once($classFile); if (class_exists($className, false)) { return true; } } return false; } } spl_autoload_register('\lib\Autoloader::load');2.路由分发
/lib/Route.php
找到api对于的控制器方法,然后调用它,此处不用引入控制器文件,会自动加载
其中request类是对请求参数的封装
<?php namespace lib; class Route { /** * 路由分发 * @param Request $request * @return mixed|void */ public static function dispatch(Request $request) { $module = $request->module(); $controller = $request->controller(); $action = $request->action(); //将api转换为对于控制器方法的命名空间 $className = '\\Applications\\' . $module . '\\controller\\' . ucfirst($controller); $obj = new $className($request); $res = call_user_func_array(array($obj, $action), array($request)); return $res; } }调用
首先引入
require_once __DIR__ . '/../../lib/Autoloader.php';use lib\Route;/** * 当客户端发来消息时触发 * @param int $client_id 连接id * @param mixed $message 具体消息 */ public static function onMessage($client_id, $message) { if ($message == 'ping') return; $message = json_decode($message,true) ?? []; try { $request = new Request($message); } catch (Exception $e){ $response = ['data' => '','code' => $e->getCode(),'msg' => $e->getMessage()]; Gateway::sendToClient($client_id, json_encode($response)); return; } try { $res = Route::dispatch($request); $response = $request->response($res['data'],$res['code'],$res['msg']); } catch (Exception $e) { echo 'Error: ' . $e . PHP_EOL; $response = $request->response('',$e->getCode(),$e->getMessage()); } catch (Error $error) { echo 'Error: ' . $error . PHP_EOL; $response = $request->response('',$error->getCode(),$error->getMessage()); } Log::info('response',$response); // 向当前client_id发送数据 Gateway::sendToClient($client_id, json_encode($response)); }