You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

195 lines
4.3 KiB
PHTML

5 years ago
<?php
/**
* The Router class
*/
class LtRouter
{
public $configHandle;
public $routingTable;
public $module;
public $action;
public function __construct()
{
if (! $this->configHandle instanceof LtConfig)
{
if (class_exists("LtObjectUtil"))
{
$this->configHandle = LtObjectUtil::singleton("LtConfig");
}
else
{
$this->configHandle = new LtConfig;
}
}
}
public function init()
{
$this->routingTable = $this->configHandle->get("router.routing_table");
if (empty($this->routingTable))
{
$this->routingTable = array('pattern' => ":module/:action/*",
'default' => array('module' => 'default', 'action' => 'index'),
'reqs' => array('module' => '[a-zA-Z0-9\.\-_]+',
'action' => '[a-zA-Z0-9\.\-_]+'
),
'varprefix' => ':',
'delimiter' => '/',
'postfix' => '',
'protocol' => 'PATH_INFO', // REWRITE STANDARD
);
}
$delimiter = $this->routingTable['delimiter'];
$postfix = $this->routingTable['postfix'];
$protocol = strtoupper($this->routingTable['protocol']);
$module = '';
$action = '';
$params = array();
// HTTP HTTPS
if (isset($_SERVER['SERVER_PROTOCOL']))
{
if (isset($_SERVER['PATH_INFO']) && !empty($_SERVER['PATH_INFO']))
{
// 忽略后缀
$url = rtrim($_SERVER['PATH_INFO'], "$postfix");
$url = explode($delimiter, trim($url, "/"));
}
else if (isset($_SERVER['REQUEST_URI']))
{
if ('REWRITE' == $protocol)
{
if (0 == strcmp($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']))
{
$url = array();
}
else
{
$url = substr($_SERVER['REQUEST_URI'], strlen(pathinfo($_SERVER['SCRIPT_NAME'], PATHINFO_DIRNAME)));
$url = rtrim($url, "$postfix");
$url = explode($delimiter, trim($url, "/"));
}
}
else if ('PATH_INFO' == $protocol)
{
$url = substr($_SERVER['REQUEST_URI'], strlen($_SERVER['SCRIPT_NAME']));
$url = rtrim($url, "$postfix");
$url = explode($delimiter, trim($url, "/"));
}
else //STANDARD
{
$url = array();
foreach($_GET as $v)
{
$url[] = $v;
}
}
}
else
{
$url = array();
foreach($_GET as $v)
{
$url[] = $v;
}
}
$params = $this->matchingRoutingTable($url);
$module = $params['module'];
$action = $params['action'];
}
else
{
// CLI
$i = 0;
while (isset($_SERVER['argv'][$i]) && isset($_SERVER['argv'][$i + 1]))
{
if (("-m" == $_SERVER['argv'][$i] || "--module" == $_SERVER['argv'][$i]))
{
$module = $_SERVER['argv'][$i + 1];
}
else if (("-a" == $_SERVER['argv'][$i] || "--action" == $_SERVER['argv'][$i]))
{
$action = $_SERVER['argv'][$i + 1];
}
else
{
$key = $_SERVER['argv'][$i];
$params[$key] = $_SERVER['argv'][$i + 1];
}
$i = $i + 2;
}
}
// 如果$_GET中不存在配置的变量则添加
foreach($params as $k => $v)
{
!isset($_GET[$k]) && $_GET[$k] = $v;
}
$this->module = $module;
$this->action = $action;
}
/**
* url 匹配路由表
*
* @param $ [string|array] $url
* @return
* @todo 修复导致$_GET多出属性的BUG
* @todo 如果是rewrite或者path_info模式可能需要unset module和action两个$_GET变量
*/
public function matchingRoutingTable($url)
{
$ret = $this->routingTable['default']; //初始化返回值为路由默认值
$reqs = $this->routingTable['reqs'];
$delimiter = $this->routingTable['delimiter'];
$varprefix = $this->routingTable['varprefix'];
$postfix = $this->routingTable['postfix'];
$pattern = explode($delimiter, trim($this->routingTable['pattern'], $delimiter));
/**
* 预处理url
*/
if (is_string($url))
{
$url = rtrim($url, $postfix); //忽略后缀
$url = explode($delimiter, trim($url, $delimiter));
}
foreach($pattern as $k => $v)
{
if ($v[0] == $varprefix)
{
// 变量
$varname = substr($v, 1);
// 匹配变量
if (isset($url[$k]))
{
if (isset($reqs[$varname]))
{
$regex = "/^{$reqs[$varname]}\$/i";
if (preg_match($regex, $url[$k]))
{
$ret[$varname] = $url[$k];
}
}
}
}
else if ($v[0] == '*')
{
// 通配符
$pos = $k;
while (isset($url[$pos]) && isset($url[$pos + 1]))
{
$ret[$url[$pos ++]] = urldecode($url[$pos]);
$pos++;
}
}
else
{
// 静态
}
}
return $ret;
}
}