在Yii2中是否可以检索包含整个应用程序的所有控制器和操作的数组?
答案 0 :(得分:6)
我终于结束了:
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;
}
答案 1 :(得分:1)
据我所知,Yii 2没有任何内置方法来实现这一目标。您只能获取当前控制器及其操作。
它的目的是什么?如果你真的需要这个,你可以自己编写这样的功能。
要获取所有控制器,您应该搜索以 Conroller 结尾的文件。它们可以位于不同的应用场所。例如,在嵌套文件夹,模块,嵌套模块等中。因此,搜索的位置不仅仅是一个。
要获取所有操作,您应该在每个控制器中搜索所有以操作为前缀的方法。
也不要忘记控制器actions()
方法中的附加操作。在框架中,它们通常以 Action 结尾,例如在休息操作中查看。但没有人强迫你这样命名,所以有些外部行为可能只有不同的命名惯例(例如,如果你在团队中工作而不遵守这个惯例)。
您可能需要排除供应商等文件夹。
所以这不是一项微不足道的任务,但可能存在一些不准确之处。我只是不明白这是什么意思。
答案 2 :(得分:1)
我从Andreas Hinderberger的答案开始,并对其进行了微调。我最终得到了类似的东西:
它使用FileHelper
递归获取所有文件,如果您从基类扩展控制器,这将非常有用。它还使用Inflector::camel2id
格式化controller-id / action-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;
}
答案 3 :(得分:0)
按照示例步行所有模块并收集所有模块控制器操作(未测试):
<?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;
}