如何从Slim 3 php框架访问所有路由?

时间:2016-11-09 11:10:07

标签: php slim psr-7

我正在尝试从Slim框架中定义的路径构建动态下拉菜单,这是我的问题 - 有没有办法从某种数组访问所有定义的静态路由?

例如,如果我像这样定义我的路线:

// Index page: '/'
require_once('pages/main.php');

// Example page: '/hello'
require_once('pages/hello.php');

// Example page: '/hello/world'
require_once('pages/hello/world.php');

// Contact page: '/contact'
require_once('pages/contact.php');

每个文件都是一个单独的页面,看起来像这样

// Index page
$app->get('/', function ($request, $response, $args) {

    // Some code

})->setName('index');

我想从某种数组中访问所有这些已定义的路由,然后使用该数组在我的模板文件中创建一个无序的HTML列表。

<ul>
  <li><a href="/">Index</a></li>
  <li><a href="/hello">Hello</a>
    <ul>
       <li><a href="/hello/world">World</a></li>
    </ul>
  </li>
  <li><a href="/contact">Contact</a></li>
</ul>

每当我更改已定义的路线时,我希望此菜单随之改变。有没有办法实现这个目标?

4 个答案:

答案 0 :(得分:10)

快速搜索Router class in GitHub project for Slim会显示一个公共方法getRoutes(),它返回$this->routes[]路由对象数组。从路径对象中,您可以使用getPattern()方法获取路径模式:

$routes = $app->getContainer()->router->getRoutes();
// And then iterate over $routes

foreach ($routes as $route) {
    echo $route->getPattern(), "<br>";
}

修改:添加了示例

答案 1 :(得分:2)

是。您可以在Slim中name your routes。这是以一种非常简单的方式完成的:

jQuery(function () {
// Create the chart
var chart = Highcharts.chart('container', {
    credits: {
        enabled: false
    },
    exporting: { enabled: true },
    chart: {
        type: 'column',
        renderTo: 'sampleChart',
    },
    credit:{enabled:false},
    title: {
        text: 'Reviews'
    },
    lang: {
        drillUpText: '◁ Back'
    },
    subtitle: {
        text: 'Details of reviews'
    },
    xAxis: {
        type: 'category',
        labels:{
            formatter: function() {
                return (this.value.toString()).replace(/[^\da-zA-Z]/g,' ');
            },
            showInLegend: true,
        },
        title: {
            text: 'Date of Reviews'
        }
    },
    yAxis: {
        allowDecimals: false,
        title: {
            text: 'Number of Reviews'
        }
    },
    legend: {
        // layout: 'vertical',
        // backgroundColor: '#FFFFFF',
        enabled: true,
        floating: false,
        shadow :false,
        // align: 'left',
        // verticalAlign: 'top',
        // x: 90,
        // y: 45,
        labelFormatter: function () {
            return (this.name).replace(/[^a-zA-Z0-9]/g,' ');
        }
    },
    plotOptions: {
        series: {               
            borderWidth: 2,
            cursor: 'pointer',
            groupPadding: 0.125,
            dataLabels: {
                enabled: true,
                format: '{point.y}'
            },
            point: {
                events: {
                    click: function (e) {
                       console.log(this)
                    }
                }
            }
        },
    },
    tooltip: {
        useHtml:true,
        headerFormat: '<span style="font-size:11px">{series.name}</span><br>',
        //pointFormat: '<span style="color:{point.color}">{point.name}</span>: <b>{point.y}</b> of total<br/>',
        formatter: function() {
            if(this.point.text)
                return '<b>'+this.point.text+'</b>';
            return '<b>'+ this.point.name+'</b>';
        }
    },
    series: [{
        name: 'Years',
        colorByPoint: true,
        data:[{"name":"Audio-2016","y":64,"drilldown":"audio_2016"},{"name":"Text-2016","y":8,"drilldown":"text_2016"},{"name":"Video-2016","y":10,"drilldown":"video_2016"}]        }],
    drilldown: {
        series: [{"name":"AUDIO_2016","id":"audio_2016","data":[{"name":"October-2016","y":54,"drilldown":"october_audio_2016"},{"name":"November-2016","y":10,"drilldown":"november_audio_2016"}]},{"name":"TEXT_2016","id":"text_2016","data":[{"name":"October-2016","y":7,"drilldown":"october_text_2016"},{"name":"November-2016","y":1,"drilldown":"november_text_2016"}]},{"name":"VIDEO_2016","id":"video_2016","data":[{"name":"October-2016","y":8,"drilldown":"october_video_2016"},{"name":"November-2016","y":2,"drilldown":"november_video_2016"}]},{"name":"OCTOBER_AUDIO_2016","id":"october_audio_2016","data":[{"name":"week-4","y":50,"drilldown":"week_4_october_audio_2016"},{"name":"week-1","y":4,"drilldown":"week_1_october_audio_2016"}]},{"name":"NOVEMBER_AUDIO_2016","id":"november_audio_2016","data":[{"name":"week-1","y":10,"drilldown":"week_1_november_audio_2016"}]},{"name":"OCTOBER_TEXT_2016","id":"october_text_2016","data":[{"name":"week-4","y":7,"drilldown":"week_4_october_text_2016"}]},{"name":"NOVEMBER_TEXT_2016","id":"november_text_2016","data":[{"name":"week-1","y":1,"drilldown":"week_1_november_text_2016"}]},{"name":"OCTOBER_VIDEO_2016","id":"october_video_2016","data":[{"name":"week-4","y":8,"drilldown":"week_4_october_video_2016"}]},{"name":"NOVEMBER_VIDEO_2016","id":"november_video_2016","data":[{"name":"week-1","y":2,"drilldown":"week_1_november_video_2016"}]},{"name":"WEEK_4_OCTOBER_AUDIO_2016","id":"week_4_october_audio_2016","data":[{"name":"26-October-2016_Inactive","y":13,"color":"#D6CBC9","text":""},{"name":"26-October-2016_Active","y":29,"color":"#FFD700","text":"Winner of the week"},{"name":"27-October-2016_Active","y":8,"color":null,"text":""}]},{"name":"WEEK_1_OCTOBER_AUDIO_2016","id":"week_1_october_audio_2016","data":[{"name":"02-October-2016_Inactive","y":1,"color":"#D6CBC9","text":""},{"name":"02-October-2016_Active","y":3,"color":"#FFD700","text":"Winner of the week"}]},{"name":"WEEK_4_OCTOBER_TEXT_2016","id":"week_4_october_text_2016","data":[{"name":"26-October-2016_Active","y":7,"color":"#FFD700","text":""}]},{"name":"WEEK_4_OCTOBER_VIDEO_2016","id":"week_4_october_video_2016","data":[{"name":"27-October-2016_Active","y":8,"color":"#FFD700","text":""}]},{"name":"WEEK_1_NOVEMBER_AUDIO_2016","id":"week_1_november_audio_2016","data":[{"name":"01-November-2016_Active","y":6,"color":"#FFD700","text":""},{"name":"03-November-2016_Inactive","y":2,"color":"#D6CBC9","text":""},{"name":"03-November-2016_Active","y":2,"color":null,"text":""}]},{"name":"WEEK_1_NOVEMBER_TEXT_2016","id":"week_1_november_text_2016","data":[{"name":"03-November-2016_Active","y":1,"color":"#FFD700","text":""}]},{"name":"WEEK_1_NOVEMBER_VIDEO_2016","id":"week_1_november_video_2016","data":[{"name":"07-November-2016_Active","y":2,"color":"#FFD700","text":""}]}],
    }
});

现在您可以按名称获取URL:

$app->get('/hello', function($request, $response) {
    // Processing request...
})->setName('helloPage'); // setting unique name for route

您也可以使用占位符命名路径:

$url = $app->getContainer()->get('router')->pathFor('helloPage');
echo $url; // Outputs '/hello'

这是确定的方法,因为如果您在模板中按名称引用路由,那么如果您需要更改URL,则只需要在路由防御中执行此操作。我发现这个特别酷。

答案 2 :(得分:0)

根据沃尔夫的回答,我已经找到了解决办法。

在您定义路线的页面中,在所有路线下方,我们将使用我们定义的路线制作一个容器。

// Get ALL routes
// --------------
$allRoutes = [];
$routes = $app->getContainer()->router->getRoutes();

foreach ($routes as $route) {
  array_push($allRoutes, $route->getPattern());
}

$container['allRoutes'] = $allRoutes;

这将创建一个包含所需路径的数组,以后我们可以在项目中使用。

然后,在您定义的路线中,您可以这样调用:

$app->get('/helloWorld', function ($request, $response, $args) {

  print_r ($this->allRoutes);

})->setName('helloWorld');

这将输出

Array
(
    [0] => /
    [1] => /helloWorld
    [2] => /someOtherRoute
    ...
)

这样我们就可以使用这个数组创建我们想要的任何东西。再次感谢沃尔夫!

答案 3 :(得分:0)

正如我在亭亭玉立的issue中评论的那样:

$routes = array_reduce($this->app->getContainer()->get('router')->getRoutes(), function ($target, $route) {
    $target[$route->getPattern()] = [
        'methods' => json_encode($route->getMethods()),
        'callable' => $route->getCallable(),
        'middlewares' => json_encode($route->getMiddleware()),
        'pattern' => $route->getPattern(),
    ];
    return $target;
}, []);
die(print_r($routes, true));