o-log / php-router
基于类的PHP路由器
Requires
- php: >=7.1
- o-log/php-http: 0.*
Requires (Dev)
- phpunit/phpunit: 4.8.*
README
以下是一个动作类示例,该类根据/term/ID这样的地址输出术语页面,并从地址中获取术语ID
<?php
namespace PHPRouterDemo;
use OLOG\InterfaceAction;
class DemoTermAction implements InterfaceAction
{
protected $term_id;
public function __construct($term_id)
{
$this->term_id = $term_id;
}
static public function urlMask()
{
return '/term/(\d+)';
}
public function url(){
return '/term/' . $this->term_id;
}
public function action(){
echo '<div>TERM ' . $this->term_id . '</div>';
}
}
这里有一个
- 构造函数,它接受动作的上下文(需要输出到页面的对象ID)
- urlMask()方法,它返回用于路由的地址掩码:一个匹配请求地址的正则表达式,并从中提取动作参数
- url()方法,它为特定参数返回此动作的页面地址
- action()方法,它为特定参数生成页面
动作类必须实现InterfaceAction接口。
要输出此动作的页面链接,需要创建一个动作对象(向构造函数传递上下文)并调用此对象的url()方法。例如,以下是术语ID为3的页面链接
(new DemoTermAction(3))->url()
如果动作不使用参数,则可以不编写urlMask()方法,在这种情况下,url()方法同时返回页面地址和地址掩码。以下是一个示例
public function url(){
return '/terms';
}
可能存在这样的情况,即对象ID在地址中未以明确的形式出现 - 例如,当对象地址存储在数据库中时。在这种情况下,不需要返回地址掩码,而是需要实现特殊的方法parse()
/**
* @param $requested_url
* @return null|RubricFeedPageAction
*/
static public function parse($requested_url){
$matches_arr = array();
if (!preg_match('@^(.+)$@', $requested_url, $matches_arr)) {
return null;
}
$term_id = Term::getIdForUrl($matches_arr[1]);
if (!$term_id) {
return null;
}
$name = self::class;
return new DemoTermAction($term_id);
}
此方法接受请求地址,可以返回null(如果动作无法处理此地址)或已传递参数的动作对象。此外,动作类必须实现ParseActionInterface接口。
POST请求
action()方法调用处理程序,而不考虑请求方法。对于仅路由POST请求,可以使用post()方法。使用此方法时,如果处理程序适合但请求不是POST,则返回405错误。
路由器解决的问题
生成动作地址
要生成动作地址,需要创建一个包含参数的动作对象,并调用其url()方法。
方便的代码导航
用于生成地址和输出结果使用的是同一个类。因此,如果代码中某处生成了动作地址,则可以简单地通过在IDE中单击url()方法的调用来转到动作类。
可以通过查找url()方法的调用来找到代码中使用动作地址的所有点。
代码中不应有类名、函数名和URL作为字符串常量的情况
动作地址仅在代码的一个地方存储:在动作本身中。在其他所有地方,为了获取地址,可以使用动作对象的url()方法的调用,这样就可以集中更改地址。
用于路由的类名通过将class作为保留常量传递给路由器,这样就可以重构动作类,例如,更改它们的名称,而无需在代码中查找和更改字符串。此外,还可以使用IDE的功能找到所有类使用。