這個方法有問題,最新的修改方法在評論中。
沒啥時間通讀代碼了,直接在Webman\app
類的findRoute
方法中將找到的路由直接賦值到請求對象上,然后可以在其他地方通過請求對象來訪問當前路由。就是不知道有沒有啥副作用,有大佬能看看不?
第一步 修改類Webman\Http\Request
,添加一個新的公共屬性currentRoute
來存儲在應(yīng)用中找到的路由對象。
第二部 修改類Webman\app
// 修改 Webman\app
protected static function findRoute($connection, $path, $key, Request $request)
{
$ret = Route::dispatch($request->method(), $path);
if ($ret[0] === Dispatcher::FOUND) {
$ret[0] = 'route';
$callback = $ret[1]['callback'];
$route = $request->currentRoute = $ret[1]['route']; // 將找到的路由賦值到當前請求對象上
$app = $controller = $action = '';
$args = !empty($ret[2]) ? $ret[2] : null;
if (\is_array($callback) && isset($callback[0]) && $controller = \get_class($callback[0])) {
$app = static::getAppByController($controller);
$action = static::getRealMethod($controller, $callback[1]) ?? '';
}
$callback = static::getCallback($app, $callback, $args, true, $route);
static::$_callbacks[$key] = [$callback, $app, $controller ? $controller : '', $action];
list($callback, $request->app, $request->controller, $request->action) = static::$_callbacks[$key];
static::send($connection, $callback($request), $request);
if (\count(static::$_callbacks) > 1024) {
static::clearCache();
}
return true;
}
return false;
}
上面的修改方案有問題,下面是新的修改方式。
修改類\Webman\App
,如下
protected static function findRoute($connection, $path, $key, Request $request)
{
$ret = Route::dispatch($request->method(), $path);
if ($ret[0] === Dispatcher::FOUND) {
$ret[0] = 'route';
$callback = $ret[1]['callback'];
$route = $ret[1]['route'];
$app = $controller = $action = '';
$args = !empty($ret[2]) ? $ret[2] : null;
if (\is_array($callback) && isset($callback[0]) && $controller = \get_class($callback[0])) {
$app = static::getAppByController($controller);
$action = static::getRealMethod($controller, $callback[1]) ?? '';
}
$callback = static::getCallback($app, $callback, $args, true, $route);
static::$_callbacks[$key] = [$callback, $app, $controller ? $controller : '', $action, $route]; // 將找到的路由對象緩存起來
list($callback, $request->app, $request->controller, $request->action, $request->currentRoute) = static::$_callbacks[$key]; // 將路由對象復制到請求對象中
static::send($connection, $callback($request), $request);
if (\count(static::$_callbacks) > 1024) {
static::clearCache();
}
return true;
}
return false;
}
public function onMessage(TcpConnection $connection, $request)
{
try {
static::$_request = $request;
static::$_connection = $connection;
$path = $request->path();
$key = $request->method() . $path;
if (isset(static::$_callbacks[$key])) {
list($callback, $request->app, $request->controller, $request->action, $request->currentRoute) = static::$_callbacks[$key]; // 從緩存的數(shù)據(jù)讀取相關(guān)信息并設(shè)置請求對象屬性
static::send($connection, $callback($request), $request);
return null;
}
if (static::findFile($connection, $path, $key, $request)) {
return null;
}
if (static::findRoute($connection, $path, $key, $request)) {
return null;
}
$controller_and_action = static::parseControllerAction($path);
if (!$controller_and_action || Route::hasDisableDefaultRoute()) {
$callback = static::getFallback();
$request->app = $request->controller = $request->action = '';
static::send($connection, $callback($request), $request);
return null;
}
$app = $controller_and_action['app'];
$controller = $controller_and_action['controller'];
$action = $controller_and_action['action'];
$callback = static::getCallback($app, [$controller_and_action['instance'], $action]);
static::$_callbacks[$key] = [$callback, $app, $controller, $action];
list($callback, $request->app, $request->controller, $request->action) = static::$_callbacks[$key];
static::send($connection, $callback($request), $request);
} catch (\Throwable $e) {
static::send($connection, static::exceptionResponse($e, $request), $request);
}
return null;
}
修改類\Webman\Http\Request
,添加一個新的公共屬性currentRoute
來存儲在應(yīng)用中找到的路由對象,然后就可以使用$request->currentRoute
來訪問當前路由。
需要注意的是,webman在判斷路由是否執(zhí)行上面似乎并沒有具體區(qū)分請求方法method
,導致使用不同方法訪問一個路由時,依舊會執(zhí)行下去,在某些時候會報錯,不過目前滿足了自己的開發(fā)需要。