Yii2 怎么循环遍历全部 Module 下 Controller 下 action [ 2.0 版本 ]
现在需要做RBAC权限管理,但我不想一个 module->controller->action
的添加菜单,想一下循环出全部Module,controller,action|搞了两三天了。。。始终没找到解决办法
wpj130 补充于 2018-08-03 17:07
现在能获取到 Module 的列表。。。contoller 啥的都没法遍历出来
共 6 个回答
-
Yii::$app->getModule('user')->getControllerPath()
通过获取模块下的控制器文件,来取到所有控制器的名称。
共 2 条回复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; }
https://stackoverflow.com/questions/27912988/retrieving-array-of-controllers-actions
这是一个完整的例子。 -
╃巡洋艦㊣给的方法也不错,可以看一下别人实现的思路。但这种方法是从指定的文件夹去获取controller,然后去自动解析。如果放到更改controller文件夹的应用中,就需要修改代码去适应。Yii本身已经给我们提供了很多的方法,使用这些现有的,其适应性更强一些。再就是,yii的Application其实也是继承自Module,是一个特殊的module。
共 6 条回复 -
Yii admin 可以搜索一下:mdmsoft/yii2-admin
一个Configs.php,可以在配置文件中自己配置menu表和user表的名称,如下:namespace mdm\admin\components; use Yii; use yii\caching\Cache; use yii\db\Connection; use yii\di\Instance; use yii\helpers\ArrayHelper; use yii\rbac\ManagerInterface; /** * Configs * Used to configure some values. To set config you can use [[\yii\base\Application::$params]] * * * return [ * * 'mdm.admin.configs' => [ * 'db' => 'customDb', * 'menuTable' => '{{%admin_menu}}', * 'cache' => [ * 'class' => 'yii\caching\DbCache', * 'db' => ['dsn' => 'sqlite:@runtime/admin-cache.db'], * ], * ] * ]; * * * or use [[\Yii::$container]] * * * Yii::$container->set('mdm\admin\components\Configs',[ * 'db' => 'customDb', * 'menuTable' => 'admin_menu', * ]); * * * @author Misbahul D Munir <misbahuldmunir@gmail.com> * @since 1.0 */ class Configs extends \mdm\admin\BaseObject { const CACHE_TAG = 'mdm.admin'; /** * @var ManagerInterface . */ public $authManager = 'authManager'; /** * @var Connection Database connection. */ public $db = 'db'; /** * @var Connection Database connection. */ public $userDb = 'db'; /** * @var Cache Cache component. */ public $cache = 'cache'; /** * @var integer Cache duration. Default to a hour. */ public $cacheDuration = 3600; /** * @var string Menu table name. */ public $menuTable = '{{%menu}}'; /** * @var string Menu table name. */ public $userTable = '{{%user}}'; /** * @var integer Default status user signup. 10 mean active. */ public $defaultUserStatus = 10; /** * @var boolean If true then AccessControl only check if route are registered. */ public $onlyRegisteredRoute = false; /** * @var boolean If false then AccessControl will check without Rule. */ public $strict = true; /** * @var array */ public $options; /** * @var array|false */ public $advanced; /** * @var self Instance of self */ private static $_instance; private static $_classes = [ 'db' => 'yii\db\Connection', 'userDb' => 'yii\db\Connection', 'cache' => 'yii\caching\Cache', 'authManager' => 'yii\rbac\ManagerInterface', ]; /** * @inheritdoc */ public function init() { foreach (self::$_classes as $key => $class) { try { $this->{$key} = empty($this->{$key}) ? null : Instance::ensure($this->{$key}, $class); } catch (\Exception $exc) { $this->{$key} = null; Yii::error($exc->getMessage()); } } } /** * Create instance of self * @return static */ public static function instance() { if (self::$_instance === null) { $type = ArrayHelper::getValue(Yii::$app->params, 'mdm.admin.configs', []); if (is_array($type) && !isset($type['class'])) { $type['class'] = static::className(); } return self::$_instance = Yii::createObject($type); } return self::$_instance; } public static function __callStatic($name, $arguments) { $instance = static::instance(); if ($instance->hasProperty($name)) { return $instance->$name; } else { if (count($arguments)) { $instance->options[$name] = reset($arguments); } else { return array_key_exists($name, $instance->options) ? $instance->options[$name] : null; } } } /** * @return Connection */ public static function db() { return static::instance()->db; } /** * @return Connection */ public static function userDb() { return static::instance()->userDb; } /** * @return Cache */ public static function cache() { return static::instance()->cache; } /** * @return ManagerInterface */ public static function authManager() { return static::instance()->authManager; } /** * @return integer */ public static function cacheDuration() { return static::instance()->cacheDuration; } /** * @return string */ public static function menuTable() { return static::instance()->menuTable; } /** * @return string */ public static function userTable() { return static::instance()->userTable; } /** * @return string */ public static function defaultUserStatus() { return static::instance()->defaultUserStatus; } /** * @return boolean */ public static function onlyRegisteredRoute() { return static::instance()->onlyRegisteredRoute; } /** * @return boolean */ public static function strict() { return static::instance()->strict; } }
Route模型代码中,与你的问题有关的是几个function如下:
- public function getAppRoutes($module = null)
- protected function getRouteRecursive($module, &$result)
- protected function getControllerFiles($module, $namespace, $prefix, &$result)
- protected function getControllerActions($type, $id, $module, &$result)
- protected function getActionRoutes($controller, &$result)
可以重点看一下,具体代码如下:
namespace mdm\admin\models; use Exception; use mdm\admin\components\Configs; use mdm\admin\components\Helper; use mdm\admin\components\RouteRule; use Yii; use yii\caching\TagDependency; use yii\helpers\VarDumper; /** * Description of Route * * @author Misbahul D Munir <misbahuldmunir@gmail.com> * @since 1.0 */ class Route extends \mdm\admin\BaseObject { const CACHE_TAG = 'mdm.admin.route'; const PREFIX_ADVANCED = '@'; const PREFIX_BASIC = '/'; private $_routePrefix; /** * Assign or remove items * @param array $routes * @return array */ public function addNew($routes) { $manager = Configs::authManager(); foreach ($routes as $route) { try { $r = explode('&', $route); $item = $manager->createPermission($this->getPermissionName($route)); if (count($r) > 1) { $action = '/' . trim($r[0], '/'); if (($itemAction = $manager->getPermission($action)) === null) { $itemAction = $manager->createPermission($action); $manager->add($itemAction); } unset($r[0]); foreach ($r as $part) { $part = explode('=', $part); $item->data['params'][$part[0]] = isset($part[1]) ? $part[1] : ''; } $this->setDefaultRule(); $item->ruleName = RouteRule::RULE_NAME; $manager->add($item); $manager->addChild($item, $itemAction); } else { $manager->add($item); } } catch (Exception $exc) { Yii::error($exc->getMessage(), __METHOD__); } } Helper::invalidate(); } /** * Assign or remove items * @param array $routes * @return array */ public function remove($routes) { $manager = Configs::authManager(); foreach ($routes as $route) { try { $item = $manager->createPermission($this->getPermissionName($route)); $manager->remove($item); } catch (Exception $exc) { Yii::error($exc->getMessage(), __METHOD__); } } Helper::invalidate(); } /** * Returns route prefix depending on the configuration. * @return string Route prefix */ public function getRoutePrefix() { if (!$this->_routePrefix) { $this->_routePrefix = Configs::instance()->advanced ? self::PREFIX_ADVANCED : self::PREFIX_BASIC; } return $this->_routePrefix; } /** * Returns the correct permission name depending on the configuration. * @param string $route Route * @return string Permission name */ public function getPermissionName($route) { if (self::PREFIX_BASIC == $this->routePrefix) { return self::PREFIX_BASIC . trim($route, self::PREFIX_BASIC); } else { return self::PREFIX_ADVANCED . ltrim(trim($route, self::PREFIX_BASIC), self::PREFIX_ADVANCED); } } /** * Get available and assigned routes * @return array */ public function getRoutes() { $manager = Configs::authManager(); // Get advanced configuration $advanced = Configs::instance()->advanced; if ($advanced) { // Use advanced route scheme. // Set advanced route prefix. $this->_routePrefix = self::PREFIX_ADVANCED; // Create empty routes array. $routes = []; // Save original app. $yiiApp = Yii::$app; // Step through each configured application foreach ($advanced as $id => $configPaths) { // Force correct id string. $id = $this->routePrefix . ltrim(trim($id), $this->routePrefix); // Create empty config array. $config = []; // Assemble configuration for current app. foreach ($configPaths as $configPath) { // Merge every new configuration with the old config array. $config = yii\helpers\ArrayHelper::merge($config, require (Yii::getAlias($configPath))); } // Create new app using the config array. unset($config['bootstrap']); $app = new yii\web\Application($config); // Get all the routes of the newly created app. $r = $this->getAppRoutes($app); // Dump new app unset($app); // Prepend the app id to all routes. foreach ($r as $route) { $routes[$id . $route] = $id . $route; } } // Switch back to original app. Yii::$app = $yiiApp; unset($yiiApp); } else { // Use basic route scheme. // Set basic route prefix $this->_routePrefix = self::PREFIX_BASIC; // Get basic app routes. $routes = $this->getAppRoutes(); } $exists = []; foreach (array_keys($manager->getPermissions()) as $name) { if ($name[0] !== $this->routePrefix) { continue; } $exists[] = $name; unset($routes[$name]); } return [ 'available' => array_keys($routes), 'assigned' => $exists, ]; } /** * Get list of application routes * @return array */ public function getAppRoutes($module = null) { if ($module === null) { $module = Yii::$app; } elseif (is_string($module)) { $module = Yii::$app->getModule($module); } $key = [__METHOD__, Yii::$app->id, $module->getUniqueId()]; $cache = Configs::instance()->cache; if ($cache === null || ($result = $cache->get($key)) === false) { $result = []; $this->getRouteRecursive($module, $result); if ($cache !== null) { $cache->set($key, $result, Configs::instance()->cacheDuration, new TagDependency([ 'tags' => self::CACHE_TAG, ])); } } return $result; } /** * Get route(s) recursive * @param \yii\base\Module $module * @param array $result */ protected function getRouteRecursive($module, &$result) { $token = "Get Route of '" . get_class($module) . "' with id '" . $module->uniqueId . "'"; Yii::beginProfile($token, __METHOD__); try { foreach ($module->getModules() as $id => $child) { if (($child = $module->getModule($id)) !== null) { $this->getRouteRecursive($child, $result); } } foreach ($module->controllerMap as $id => $type) { $this->getControllerActions($type, $id, $module, $result); } $namespace = trim($module->controllerNamespace, '\\') . '\\'; $this->getControllerFiles($module, $namespace, '', $result); $all = '/' . ltrim($module->uniqueId . '/*', '/'); $result[$all] = $all; } catch (\Exception $exc) { Yii::error($exc->getMessage(), __METHOD__); } Yii::endProfile($token, __METHOD__); } /** * Get list controller under module * @param \yii\base\Module $module * @param string $namespace * @param string $prefix * @param mixed $result * @return mixed */ protected function getControllerFiles($module, $namespace, $prefix, &$result) { $path = Yii::getAlias('@' . str_replace('\\', '/', $namespace), false); $token = "Get controllers from '$path'"; Yii::beginProfile($token, __METHOD__); try { if (!is_dir($path)) { return; } foreach (scandir($path) as $file) { if ($file == '.' || $file == '..') { continue; } if (is_dir($path . '/' . $file) && preg_match('%^[a-z0-9_/]+$%i', $file . '/')) { $this->getControllerFiles($module, $namespace . $file . '\\', $prefix . $file . '/', $result); } elseif (strcmp(substr($file, -14), 'Controller.php') === 0) { $baseName = substr(basename($file), 0, -14); $name = strtolower(preg_replace('/(?<![A-Z])[A-Z]/', ' \0', $baseName)); $id = ltrim(str_replace(' ', '-', $name), '-'); $className = $namespace . $baseName . 'Controller'; if (strpos($className, '-') === false && class_exists($className) && is_subclass_of($className, 'yii\base\Controller')) { $this->getControllerActions($className, $prefix . $id, $module, $result); } } } } catch (\Exception $exc) { Yii::error($exc->getMessage(), __METHOD__); } Yii::endProfile($token, __METHOD__); } /** * Get list action of controller * @param mixed $type * @param string $id * @param \yii\base\Module $module * @param string $result */ protected function getControllerActions($type, $id, $module, &$result) { $token = "Create controller with cofig=" . VarDumper::dumpAsString($type) . " and id='$id'"; Yii::beginProfile($token, __METHOD__); try { /* @var $controller \yii\base\Controller */ $controller = Yii::createObject($type, [$id, $module]); $this->getActionRoutes($controller, $result); $all = "/{$controller->uniqueId}/*"; $result[$all] = $all; } catch (\Exception $exc) { Yii::error($exc->getMessage(), __METHOD__); } Yii::endProfile($token, __METHOD__); } /** * Get route of action * @param \yii\base\Controller $controller * @param array $result all controller action. */ protected function getActionRoutes($controller, &$result) { $token = "Get actions of controller '" . $controller->uniqueId . "'"; Yii::beginProfile($token, __METHOD__); try { $prefix = '/' . $controller->uniqueId . '/'; foreach ($controller->actions() as $id => $value) { $result[$prefix . $id] = $prefix . $id; } $class = new \ReflectionClass($controller); foreach ($class->getMethods() as $method) { $name = $method->getName(); if ($method->isPublic() && !$method->isStatic() && strpos($name, 'action') === 0 && $name !== 'actions') { $name = strtolower(preg_replace('/(?<![A-Z])[A-Z]/', ' \0', substr($name, 6))); $id = $prefix . ltrim(str_replace(' ', '-', $name), '-'); $result[$id] = $id; } } } catch (\Exception $exc) { Yii::error($exc->getMessage(), __METHOD__); } Yii::endProfile($token, __METHOD__); } /** * Ivalidate cache */ public static function invalidate() { if (Configs::cache() !== null) { TagDependency::invalidate(Configs::cache(), self::CACHE_TAG); } } /** * Set default rule of parameterize route. */ protected function setDefaultRule() { if (Configs::authManager()->getRule(RouteRule::RULE_NAME) === null) { Configs::authManager()->add(new RouteRule()); } } }
wpj130
注册时间:2018-07-03
最后登录:2022-04-20
在线时长:5小时16分
最后登录:2022-04-20
在线时长:5小时16分
- 粉丝2
- 金钱25
- 威望0
- 积分75