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));
}
更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。
程序员编程交流QQ群:805358732
如果你想用Python开辟副业赚钱,但不熟悉爬虫与反爬虫技术,没有接单途径,也缺乏兼职经验
关注下方微信公众号:Python编程学习圈,获取价值999元全套Python入门到进阶的学习资料以及教程,还有Python技术交流群一起交流学习哦。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!