如何在 CMS 的基础 URL 上创建动态 URL?

How to create dynamic URLs at the base URL of a CMS?

我在 PHP 网站上显示用户个人资料,使用用户名作为链接到给定用户个人资料的 URL 的一部分。

我可以通过控制器 ProfileController 来实现,但是 URL 看起来像这样 thewebsite.com/profile/show_profile/ANYUSERNAMEHERE

我想要的是类似于 Facebook 的东西,其中用户名附加在基本 URL 之后:

https://www.facebook.com/zuck

我尝试将变量传递给 主页控制器的 Index 函数 (Index()) (IndexController),但是 URL 变为 thewebsite.com/index/ANYUSERNAMEHERE 并且基础 url thewebsite.com 抛出错误:

Too few arguments to function IndexController::index(), 0 passed and exactly 1 expected.

主页控制器:

<?php
class IndexController extends Controller
{

    public function __construct()
    {
        parent::__construct();
    }

    // IF LEFT, THE VARIABLE $profile THROWS AN ERROR AT THE BASE URL

    public function index($profile)  
    {
        /** AFTER REMOVING THE $profile VARIABLE ABOVE AND THE 'if'
         *  STATEMENT BELOW, THE ERROR THROWN AT THE BASE URL VANISHES AND                     
         *  THE WEBSITE GOES BACK TO IT'S NORMAL STATE. THIS CODE WAS USED
         *  TRYING TO RENDER THE URL thewebsite.com/ANYUSERNAMEHERE BUT IT  
         *  ONLY WORKS WITH thewebsite.com/index/ANYUSERNAMEHERE
         */  

        if (isset($profile)) {
        $this->View->render('profiles/show_profile', array(
        'profiles' => ProfileModel::getSelectedProfile($profile))
        );

        } else {
        $this->View->render('index/index', array(
        'profiles' => ProfileModel::getAllProfiles()));
    }  

}

配置文件控制器:

<?php
class ProfileController extends Controller
{

    public function __construct()
    {
        parent::__construct();
        Auth::checkAuthentication();
    }

    public function index()
    {

        $this->View->render('profiles/index', array(
        'profiles' => ProfileModel::getAllProfiles())
        );

    }

    public function show_profile($profile)
    {
        if (isset($profile)) {
        $this->View->render('profiles/show_profile', array(
        'profiles' => ProfileModel::getSelectedProfile($profile))
        );

        } else {

        Redirect::home();

        }
    }
}

我期待 base URL 将参数(用户名)传递给 IndexController 的 Index($profile) 函数,但网页抛出错误,预期结果显示错误 URL: thewebsite.com/index/ANYUSERNAMEHERE

您需要使用基于正则表达式的路由器,例如 FastRoute, or Aura.Router

例如,使用 FastRoute,您可以定义一个路由并将其添加到所谓的 路由收集器 ($r),如下所示:

$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r) {
    // The /{profile} suffix is optional
    $r->addRoute('GET', '[/{profile}]', 'handler');
});

其中 handler 只是可调用形式的可自定义 路由处理程序 的通用名称。例如,如果您另外使用 PHP-DI/Invoker 库,则路由处理程序 ('handler') 可能看起来像以下可调用项之一(至少):

  • [ProfileController::class, 'show_profile']
  • 'ProfileController::show_profile'

所以完整的路由定义如下:

  • $r->addRoute('GET', '[/{profile}]', [ProfileController::class, 'show_profile']);
  • $r->addRoute('GET', '[/{profile}]', 'ProfileController::show_profile');

占位符名称(profile)对应方法的参数名称ProfileController::show_profile:

class ProfileController extends Controller {

    public function show_profile($profile) {
        ...
    }

}

即使 URL 看起来像您想要的,例如thewebsite.com/zuck,我想上面路由定义的占位符{profile}会和其他路由定义中定义的固定模式部分发生冲突,比如/books in:

$r->addRoute('GET', '[/books/{bookName}]', 'handler');

所以我建议维护一个URL形式的thewebsite.com/profiles/zuck,路由定义:

$r->addRoute('GET', '/profiles/{profile}', 'handler');

我还建议阅读并在您的代码中应用 PHP Standards Recommendations。特别是 PSR-1、PSR-4 和 PSR-12。