如何在 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。
我在 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。