如何在 Laravel 4 中创建数据库驱动的路由别名?

How do I create database driven route aliases in Laravel 4?

我正在开发一个带有数据库驱动菜单系统的内容管理系统,它允许用户为 routes.php 中定义的应用程序路由生成 SEO 友好的 URL。

例如,用户为具有所需路径的页面创建菜单项 /about-us。发出请求时,应用程序会检查数据库中当前路径是否存在别名,然后根据别名路由请求。

期望的结果是当您请求 /about-us 时,应用程序实际上将其视为 /pages/1,但用户在地址栏中看到 /about-us

用户需要能够link访问任何资源,而不仅仅是页面 - 所以类别、帖子等

示例菜单项模型:

{
    "id": 1,
    "name": "About us page",
    "path": "/about-us",
    "alias": "/pages/1"
}

示例目标路线:

Route::get('pages/{id}', 'PageController@show');
Route::get('categories/{id}', 'CategoryController@show');

我想也许我可以简单地使用在 start/global.php 中注册的前过滤器覆盖 REQUEST_URI 变量,但这没有效果。

App::before(function(\Illuminate\Http\Request $request)
{
    $request_uri = $request->server->get('REQUEST_URI');
    $request_uri_string = urldecode(substr($request_uri, 1));

    if (strlen($request_uri_string)>1) 
    {
        if ($menuItem = MenuItem::where('path', '=', $request_uri_string)->first())
        {
            $request->server->set('REQUEST_URI', $menuItem->alias);
        }
    }
});

有什么实现方法吗?

我相信我已经通过扩展 \Illuminate\Http\Request 并将此自定义请求 class 注入到 bootstrap/start.php 中的应用程序中找到了解决方案。

自定义请求 class:

namespace Vendor\Package;

class Request extends \Illuminate\Http\Request {

    /**
     * Override the request uri so we can create menu aliases
     *
     * @param $value
     */
    public function setRequestUri($value)
    {
        $this->requestUri = $value;
        $this->pathInfo = $value;
        $this->server->set('REQUEST_URI', $value);
    }

}

将自定义请求 class 注入 bootstrap/start.php

顶部的应用程序
$request = \Vendor\Package\Request::createFromGlobals();
$app = new Illuminate\Foundation\Application($request);

检查是否存在具有请求路径的菜单项,并将请求 uri 设置为其别名 (app/start/global.php)。

App::before(function(Vendor\Package\Request $request)
{
    $request_uri = $request->server->get('REQUEST_URI');
    $request_uri_string = urldecode(substr($request_uri, 1));

    if (strlen($request_uri_string)>1)
    {
        if ($menuItem = MenuItem::where('path', '=', $request_uri_string)->first())
        {
            $request->setRequestUri($menuItem->alias);
        }
    }
});