Yii2 正在检索控制器/操作的数组
在Yi2中是否可以检索包含整个应用程序的所有控制器和操作的数组?据我所知,Yi2没有任何内置方法来实现这一点。您只能获取当前控制器及其操作 它的目的是什么?如果您真的需要它,您可以自己编写这样的功能 要获取所有控制器,您应搜索以Conroller结尾的文件。它们可以位于不同的应用位置。例如,在嵌套的文件夹、模块、嵌套的模块等中,因此搜索的位置不止一个 要获取所有操作,应在每个控制器中搜索前缀为操作的所有方法 另外,不要忘记控制器Yii2 正在检索控制器/操作的数组,yii2,Yii2,在Yi2中是否可以检索包含整个应用程序的所有控制器和操作的数组?据我所知,Yi2没有任何内置方法来实现这一点。您只能获取当前控制器及其操作 它的目的是什么?如果您真的需要它,您可以自己编写这样的功能 要获取所有控制器,您应搜索以Conroller结尾的文件。它们可以位于不同的应用位置。例如,在嵌套的文件夹、模块、嵌套的模块等中,因此搜索的位置不止一个 要获取所有操作,应在每个控制器中搜索前缀为操作的所有方法 另外,不要忘记控制器actions()方法中附加的操作。在框架中,它们通常以操作结尾,例
actions()
方法中附加的操作。在框架中,它们通常以操作结尾,例如看看rest操作。但没有人强迫您这样命名,所以有些外部操作可能只是具有不同的命名约定(例如,如果您在团队中工作而不遵循此约定)
您可能需要排除诸如供应商之类的文件夹
因此,这不是一项微不足道的任务,但可能存在一些不准确之处。我就是不明白这有什么意义。我最终得到了:
protected function actionGetcontrollersandactions()
{
$controllerlist = [];
if ($handle = opendir('../controllers')) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != ".." && substr($file, strrpos($file, '.') - 10) == 'Controller.php') {
$controllerlist[] = $file;
}
}
closedir($handle);
}
asort($controllerlist);
$fulllist = [];
foreach ($controllerlist as $controller):
$handle = fopen('../controllers/' . $controller, "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
if (preg_match('/public function action(.*?)\(/', $line, $display)):
if (strlen($display[1]) > 2):
$fulllist[substr($controller, 0, -4)][] = strtolower($display[1]);
endif;
endif;
}
}
fclose($handle);
endforeach;
return $fulllist;
}
我从安德烈亚斯·亨德伯格的答案开始,并对其进行了微调。我的结局是这样的: 它使用
FileHelper
递归地获取所有文件,这对于从基类扩展控制器非常有用。它还使用拐点::camel2id
格式化控制器id/动作id,以便它们与您的路线匹配
public function getAllControllerActions()
{
$controllers = \yii\helpers\FileHelper::findFiles(Yii::getAlias('@app/controllers'), ['recursive' => true]);
$actions = [];
foreach ($controllers as $controller) {
$contents = file_get_contents($controller);
$controllerId = Inflector::camel2id(substr(basename($controller), 0, -14));
preg_match_all('/public function action(\w+?)\(/', $contents, $result);
foreach ($result[1] as $action) {
$actionId = Inflector::camel2id($action);
$route = $controllerId . '/' . $actionId;
$actions[$route] = $route;
}
}
asort($actions);
return $actions;
}
以下示例:巡视所有模块并收集所有模块控制器动作(未测试):
其要点是获取所有控制器的列表,这些控制器的操作用于构建一个数据库表,其中包含每个经过身份验证的角色的控制器/操作,这些角色允许调用或不允许调用。在这种情况下,我可以预定义包含控制器的文件夹。您可以尝试按照我描述的方式执行此操作。但出于这个目的,我认为最好在每个控制器中设置RBAC并通过behaviors()配置AccessControl。这是推荐的标准方法。您可以使用类似于Thx Manquer的方法作为提示。我刚刚发布了我最终得到的解决方案。我想ActionRequestFile
给我请求文件
,所以我将其中一行更改为:$fulllist[substr($controller,0,-4)][]=ltrim(strtolower(内爆('-',预裂('/(?=[A-Z]),$display[1]),'-')代码>听起来很好,但也取决于您如何进一步使用它EndForeach;endif;etc看起来很糟糕这不适用于扩展控制器,例如,如果我使用博客模块并从基本控制器(即从供应商目录)扩展控制器,并且只将我的新自定义操作添加到扩展类中,它将只定义新操作,而不是该类的所有操作。
<?php
$controllerDirs = [];
$controllerDirs[] = \Yii::getAlias('@app/controllers');
if ($commonControllerDir = \Yii::getAlias('@common/controllers', false)) {
$controllerDirs['common'] = $commonControllerDir;
}
foreach (\Yii::$app->modules as $moduleId => $module) {
/*
* get module base path
*/
if (method_exists($module, 'getBasePath')) {
$basePath = $module->getBasePath();
} else {
$reflector = new \ReflectionClass($module['class']);
$basePath = StringHelper::dirname($reflector->getFileName());
}
$basePath .= '/controllers';
$controllerDirs[$moduleId] = $basePath;
}
$actions = [];
foreach ($controllerDirs as $moduleId => $cDir) {
$actions[$moduleId][$cDir] = actionGetcontrollersandactions($cDir);
}
print_r($actions);
function actionGetcontrollersandactions($controllerDir) {
$controllerlist = [];
if ($handle = opendir($controllerDir)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != ".." && substr($file, strrpos($file, '.') - 10) == 'Controller.php') {
$controllerlist[] = $file;
}
}
closedir($handle);
}
asort($controllerlist);
$fulllist = [];
foreach ($controllerlist as $controller):
$handle = fopen($controllerDir . '/' . $controller, "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
if (preg_match('/public function action(.*?)\(/', $line, $display)):
if (strlen($display[1]) > 2):
$fulllist[substr($controller, 0, -4)][] = strtolower($display[1]);
endif;
endif;
}
}
fclose($handle);
endforeach;
return $fulllist;
}