首页 > 解决方案 > 在 Yii2 应用中获取所有路由(模块、控制器、动作)

问题描述

我想从我在 Yii2 Advanced 中的应用程序中获得所有路线。我已经完成了这个问题,但是我想让它与目录匹配。

我的前端/模块代码以及其中的所有内容:

    $dir = Yii::getAlias('@frontend');
$getFile = \yii\helpers\FileHelper::findFiles($dir,['only'=>['*.php']]);
$files['controllers'] = [];
$files['modules'] = [];
foreach($getFile as $file){
    if (substr($file, strrpos($file, '.') - 6) == 'Module.php') {
        $mname = strtolower(str_replace('Module','',basename($file,".php")));
        $mfilename = basename($file,".php").'.php';
        $mpath = str_replace($mfilename,'',$file);
        $mroute = '/'.str_replace('Module','',$mname);
        $files['modules'][$mname]['path'] = $mpath;
        $files['modules'][$mname]['filename'] = $mfilename;
        $files['modules'][$mname]['route'] = strtolower($mroute);
        $getFileCont = \yii\helpers\FileHelper::findFiles($mpath,['only'=>['*.php']]);
        foreach($getFileCont as $file){
            if (substr($file, strrpos($file, '.') - 10) == 'Controller.php') {
                $cname = strtolower(str_replace('Controller','',basename($file,".php")));
                $cfilename = basename($file, ".php").'.php';
                $cpath = str_replace($cfilename,'',$file);
                $croute = $mroute.'/'.str_replace('Controller','',$cname);
                $files['modules'][$mname]['controllers'][$cname]['path'] = $cpath;
                $files['modules'][$mname]['controllers'][$cname]['filename'] = $cfilename;
                $files['modules'][$mname]['controllers'][$cname]['route'] = strtolower($croute);
                $content = file_get_contents($file);
                preg_match_all('#function action(.*)\(#ui', $content, $aData);
                $files['modules'][$mname]['controllers'][$cname]['actions'] = [];
                foreach($aData[1] as $action){
                    $act = strtolower($action);
                    // $files['modules'][$mname]['controllers'][$cname]['actions'][$act]['name'] = $action;
                    // $files['modules'][$mname]['controllers'][$cname]['actions'][$act]['function'] = 'function'.$action;
                    $files['modules'][$mname]['controllers'][$cname]['actions'][$act]['route'] = strtolower($croute.'/'.$action);
                }
            }
        }
    }
}

这是前端/站点控制器的代码:

$getFileController = \yii\helpers\FileHelper::findFiles($dir.'/controllers',['only'=>['*.php']]);
foreach($getFileController as $file){
    if (substr($file, strrpos($file, '.') - 10) == 'Controller.php') {
        $cname = strtolower(str_replace('Controller','',basename($file,".php")));
        $cfilename = basename($file, ".php").'.php';
        $cpath = str_replace($cfilename,'',$file);
        $croute = '/'.str_replace('Controller','',$cname);
        $files['controllers'][$cname]['path'] = $cpath;
        $files['controllers'][$cname]['filename'] = $cfilename;
        $files['controllers'][$cname]['route'] = strtolower($croute);
        $content = file_get_contents($file);
        preg_match_all('#function action(.*)\(#ui', $content, $aData);
        $files['controllers'][$cname]['actions'] = [];
        foreach($aData[1] as $action){
            if($action !== 's') {
                $act = strtolower($action);
                $files['controllers'][$cname]['actions'][$act]['route'] = strtolower($croute.'/'.$action);
            }
        }
    }
}
print_r($files);

输出值为:

Array
(
    [controllers] => Array
        (
            [site] => Array
                (
                    [path] => /var/www/html/aoisora/_protected/src/frontend/controllers/
                    [filename] => SiteController.php
                    [route] => /site
                    [actions] => Array
                        (
                            [index] => Array
                                (
                                    [route] => /site/index
                                )

                            [login] => Array
                                (
                                    [route] => /site/login
                                )

                            [logout] => Array
                                (
                                    [route] => /site/logout
                                )

                            [contact] => Array
                                (
                                    [route] => /site/contact
                                )

                            [about] => Array
                                (
                                    [route] => /site/about
                                )

                            [signup] => Array
                                (
                                    [route] => /site/signup
                                )

                            [requestpasswordreset] => Array
                                (
                                    [route] => /site/requestpasswordreset
                                )

                            [resetpassword] => Array
                                (
                                    [route] => /site/resetpassword
                                )

                            [verifyemail] => Array
                                (
                                    [route] => /site/verifyemail
                                )

                            [resendverificationemail] => Array
                                (
                                    [route] => /site/resendverificationemail
                                )

                        )

                )

        )

    [modules] => Array
        (

            [post] => Array
                (
                    [path] => /var/www/html/aoisora/_protected/src/frontend/modules/blog/modules/post/
                    [filename] => PostModule.php
                    [route] => /post
                    [controllers] => Array
                        (
                            [default] => Array
                                (
                                    [path] => /var/www/html/aoisora/_protected/src/frontend/modules/blog/modules/post/controllers/
                                    [filename] => DefaultController.php
                                    [route] => /post/default
                                    [actions] => Array
                                        (
                                            [index] => Array
                                                (
                                                    [route] => /post/default/index
                                                )

                                        )

                                )

                        )

                )

            [blog] => Array
                (
                    [path] => /var/www/html/aoisora/_protected/src/frontend/modules/blog/
                    [filename] => BlogModule.php
                    [route] => /blog
                    [controllers] => Array
                        (
                            [default] => Array
                                (
                                    [path] => /var/www/html/aoisora/_protected/src/frontend/modules/blog/controllers/
                                    [filename] => DefaultController.php
                                    [route] => /blog/default
                                    [actions] => Array
                                        (
                                            [index] => Array
                                                (
                                                    [route] => /blog/default/index
                                                )

                                        )

                                )

                        )

                )

        )

)

问题是:[route] => /post/default/index必须是[route] => /blog/post/default/index 因为帖子在博客模块中可用。我使用带有文件助手的方法,每个名称为 ..Module.php 或 ..Controller.php 的文件都可以是返回值。

标签: phpyii2yii2-advanced-app

解决方案


有同样的问题,制作了这个代码(在控制器动作中发布):

$controller = \Yii::$app->controller->id;
$methods = [];// public methods 
    foreach (get_class_methods($this) as $m)
        if( preg_match('/^(action[^s])/s', $m))
            $methods[] = $controller.'/'.str_replace('action', '', strtolower($m) );

如果您需要获取这些方法的操作,请使用此字符串

$action = preg_replace_callback(
                            '/([A-Z+])/s',
                            function ($word)
                            {
                                return strtolower('-'.$word[1]);
                            },
                    $m);
$action = str_replace('action', '', strtolower($action) );
$methods[] = $controller.'/'.substr($action, 1);

推荐阅读