Router class 개선 및 오류 수정

- RewriteRule의 break 문법 지원
-- Apache RewriteRule의 [L] 플래그
-- Nginx RewriteRule의 break 문법

-성능 이슈 및 deprecated 이슈로 preg_replace() 대신에 substr_compare() 함수와 substr()
함수를 이용하여 동작하도록 개선

ps. preg_replace() 함수의 /e modifier가 PHP 5.5에서 deprecated 처리됨

- URI Segment가 1개인 경우 해당 Segment를 Unset 하던 오류 수정
This commit is contained in:
SMaker 2014-08-16 23:19:18 +09:00
parent 3f4bef0c46
commit 8cf12f63b8

View file

@ -18,29 +18,29 @@ class Router
*/ */
private static $routes = array( private static $routes = array(
// rss , blogAPI // rss , blogAPI
'(rss|atom)' => array('module' => 'rss', 'act' => '$1'), '(rss|atom)' => array('module' => 'rss', 'act' => '$1', '[L]' => TRUE),
'([a-zA-Z0-9_]+)/(rss|atom|api)' => array('mid' => '$1', 'act' => '$2'), '([a-zA-Z0-9_]+)/(rss|atom|api)' => array('mid' => '$1', 'act' => '$2', '[L]' => TRUE),
'([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/(rss|atom|api)' => array('vid' => '$1', 'mid' => '$2', 'act' => '$3'), '([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/(rss|atom|api)' => array('vid' => '$1', 'mid' => '$2', 'act' => '$3', '[L]' => TRUE),
// trackback // trackback
'([0-9]+)/(.+)/trackback' => array('document_srl' => '$1', 'key' => '$2', 'act' => 'trackback'), '([0-9]+)/(.+)/trackback' => array('document_srl' => '$1', 'key' => '$2', 'act' => 'trackback', '[L]' => TRUE),
'([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback' => array('mid' => '$1', 'document_srl' => '$2', 'key' => '$3', 'act' => 'trackback'), '([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback' => array('mid' => '$1', 'document_srl' => '$2', 'key' => '$3', 'act' => 'trackback', '[L]' => TRUE),
'([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback' => array('vid' => '$1', 'mid' => '$2', 'document_srl' => '$3' , 'key' => '$4', 'act' => 'trackback'), '([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback' => array('vid' => '$1', 'mid' => '$2', 'document_srl' => '$3' , 'key' => '$4', 'act' => 'trackback', '[L]' => TRUE),
// mid
'([a-zA-Z0-9_]+)/?' => array('mid' => '$1'),
// mid + document_srl
'([a-zA-Z0-9_]+)/([0-9]+)' => array('mid' => '$1', 'document_srl' => '$2'),
// vid + mid
'([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/' => array('vid' => '$1', 'mid' => '$2'),
// vid + mid + document_srl
'([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)?' => array('vid' => '$1', 'mid' => '$2', 'document_srl' => '$3'),
// document_srl // document_srl
'([0-9]+)' => array('document_srl' => '$1'), '([0-9]+)' => array('document_srl' => '$1', '[L]' => TRUE),
// mid
'([a-zA-Z0-9_]+)/?' => array('mid' => '$1', '[L]' => TRUE),
// mid + document_srl
'([a-zA-Z0-9_]+)/([0-9]+)' => array('mid' => '$1', 'document_srl' => '$2', '[L]' => TRUE),
// vid + mid
'([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/' => array('vid' => '$1', 'mid' => '$2', '[L]' => TRUE),
// vid + mid + document_srl
'([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)?' => array('vid' => '$1', 'mid' => '$2', 'document_srl' => '$3', '[L]' => TRUE),
// mid + entry title // mid + entry title
'([a-zA-Z0-9_]+)/entry/(.+)' => array('mid' => '$1', 'entry' => '$2'), '([a-zA-Z0-9_]+)/entry/(.+)' => array('mid' => '$1', 'entry' => '$2', '[L]' => TRUE),
// vid + mid + entry title // vid + mid + entry title
'([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/(.+)' => array('vid' => '$1', 'mid' => '$2', 'entry' => '$3'), '([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/(.+)' => array('vid' => '$1', 'mid' => '$2', 'entry' => '$3', '[L]' => TRUE),
// shop / vid / [category|product] / identifier // shop / vid / [category|product] / identifier
'([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([a-zA-Z0-9_\.-]+)' => array('act' => 'route', 'vid' => '$1', 'type' => '$2', 'identifier'=> '$3') '([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([a-zA-Z0-9_\.-]+)' => array('act' => 'route', 'vid' => '$1', 'type' => '$2', 'identifier'=> '$3', '[L]' => TRUE)
); );
/** /**
@ -72,6 +72,7 @@ class Router
return; return;
} }
// Get relative path from request uri
$path = parse_url($uri, PHP_URL_PATH); $path = parse_url($uri, PHP_URL_PATH);
// Do some final cleaning of the URI and return it // Do some final cleaning of the URI and return it
@ -80,33 +81,80 @@ class Router
if(strlen($path) > 0) if(strlen($path) > 0)
{ {
self::$segments = explode('/', $path); self::$segments = explode('/', $path);
// Remove the meanless segment
unset(self::$segments[0]);
} }
if(isset(self::$routes[$path])) if(isset(self::$routes[$path]))
{ {
foreach(self::$routes[$path] as $key => $val) foreach(self::$routes[$path] as $key => $val)
{ {
$val = preg_replace('#^\$([0-9]+)$#e', '\$matches[$1]', $val); if(strlen($val) > 0)
{
if(substr_compare($val, '$', 0, 1) == 0)
{
$segment_index = (int) substr($val, 1) - 1;
if($segment_index < 0)
{
continue;
}
Context::set($key, $val, TRUE); Context::set($key, self::$segments[$segment_index], TRUE);
}
else
{
Context::set($key, $val, TRUE);
}
}
else
{
Context::set($key, '', TRUE);
}
} }
return; return;
} }
$break = FALSE;
// Apply routes // Apply routes
foreach(self::$routes as $regex => $query) foreach(self::$routes as $regex => $query)
{ {
// Stop the routing proccess
if($break)
{
break;
}
if(preg_match('#^' . $regex . '$#', $path, $matches)) if(preg_match('#^' . $regex . '$#', $path, $matches))
{ {
foreach($query as $key => $val) foreach($query as $key => $val)
{ {
$val = preg_replace('#^\$([0-9]+)$#e', '\$matches[$1]', $val); // If [L] keyword is defined
if($key == '[L]')
{
// Stop the routing process and don't apply any more rules
$break = TRUE;
continue;
}
Context::set($key, $val, TRUE); if(strlen($val) > 0)
{
if(substr($val, 0, 1) == '$')
{
$segment_index = (int) substr($val, 1) - 1;
if($segment_index < 0)
{
continue;
}
Context::set($key, self::$segments[$segment_index], TRUE);
}
else
{
Context::set($key, $val, TRUE);
}
}
else
{
Context::set($key, '', TRUE);
}
} }
} }
} }
@ -150,7 +198,7 @@ class Router
*/ */
public static function getSegment($index) public static function getSegment($index)
{ {
return self::$segments[$index]; return self::$segments[$index - 1];
} }