Location: PHPKode > scripts > web20vnRouter > web20vnrouter/web20vn_router.php
<?php
/**
 * web20vn.com Router
 *
 * @author     Le Khac Nhu <hide@address.com>
 * @author     brandlover <hide@address.com>
 * @copyright  http://web20vn.com
 * @version    1.0 [20080128]
 */

$time_start = microtime(true);

class web20vnRouter
{
	public static $uri				= null;
	public static $url_suffix		= '.html';
	public static $index_file		= 'web20vn_router.php';

	public static $routes			= array();
	public static $placeholder		= array(
		':any'		=> '.+',
		':alias'	=> '[a-zA-Z0-9\_\-\.]+',
		':num'		=> '[0-9]+',
		':year'		=> '[0-9]{4}',
		':month'	=> '[0-9]{2}',
		':day'		=> '[0-9]{2}',
	);
	
	public static $routed			= array(
		'controller'	=> '',
		'action'		=> '',
		'args'			=> '',
	);

	public static $default = array(
		'controller'	=> 'welcome',
		'action'		=> 'index',
	);

	public static function call($uri = null)
	{
		if(empty($uri))
		{
			self::getUri();
		}
		self::start();
	}

	public static function getUri()
	{
		$temp_url = '';

		if(isset($_GET['q']) && $_GET['q'] != '')
		{
			$temp_url = $_GET['q'];
		}
		elseif (isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'])
		{
			$temp_url = $_SERVER['PATH_INFO'];
		}
		elseif (isset($_SERVER['ORIG_PATH_INFO']) && $_SERVER['ORIG_PATH_INFO'])
		{
			$temp_url = $_SERVER['ORIG_PATH_INFO'];
		}
		elseif (isset($_SERVER['PHP_SELF']) && $_SERVER['PHP_SELF'])
		{
			$temp_url = $_SERVER['PHP_SELF'];
		}

		$temp_url = trim($temp_url, '/');

		if (($offset = strpos($temp_url, self::$index_file)) !== false)
		{
			$offset += strlen(self::$index_file);
			$temp_url = substr($temp_url, $offset);
		}
		
		if (strpos($temp_url, self::$url_suffix) !== false)
		{
			$temp_url = preg_replace('#'.preg_quote(self::$url_suffix).'$#u', '', $temp_url);
			//$temp_url = replace_once(self::$url_suffix, '', $temp_url);
		}

		self::$uri = preg_replace('#/+#', '/', $temp_url);
	}

	public static function start()
	{
		$is_routed = false;
		
		// Neu rong => mac dinh (trang chu)
		if (empty(self::$uri) || self::$uri === '/')
		{
			self::$routed['controller'] = self::$default['controller'];
			self::$routed['action'] = self::$default['controller'];
			$is_routed = true;
		}
		else
		{
			if(count(self::$routes) > 0)
			{
				foreach(self::$routes as $rule => &$route)
				{
					if(!isset($route['u']))
					{
						exit('Route khong hop le: '.$rule);
					}
					
					$routed_c = isset($route['c']) ? $route['c'] : self::$default['controller'];
					$routed_a = isset($route['a']) ? $route['a'] : self::$default['action'];

					if($route['u'] === self::$uri)
					{
						self::$routed['controller'] = $routed_c;
						self::$routed['action'] = $routed_a;
						$is_routed = true;
						break;
					}
					
					if(strpos($route['u'], '?') !== false)
					{
						if(!isset($route['r']))
						{
							exit('Trong route ('.$rule.') chua co regex!!!');
						}
						
						// Tao params...
						$i = 0;
						foreach($route['r'] as $rr)
						{
							if($rr[0] == '(')
							{
								$p = isset($route['p'][$i]) ? $route['p'][$i] : 'p'.$i;
								$route['r'][$i] = replace_once('(', '(?P<'.$p.'>', $rr);
							}
							++$i;
						}
						
						$r_ex = web20vnReplace($route['u'], $route['r']);

						// Placeholder
						if (strpos($r_ex, ':') !== false) {
							$r_ex = strtr($r_ex, self::$placeholder);
						}

						if(preg_match('#^'.$r_ex.'$#ui', self::$uri, $matches))
						{
							self::$routed['args']		= array_slice($matches, 1);
							self::$routed['controller'] = $routed_c;
							self::$routed['action']		= $routed_a;
							$is_routed = true;
							break;
						}
					}
				}
				
				if(!$is_routed)
				{
					$rs = explode('/', self::$uri);

					//Controller:
					if (count($rs) && !empty($rs[0])) {
						self::$routed['controller'] = array_shift($rs);
			        }
					else
					{
						self::$routed['controller'] = self::$default['controller'];
					}
					
					//Action:
			        if (count($rs) && !empty($rs[0])) {
			        	self::$routed['action'] = array_shift($rs);
			        }
					else
					{
						self::$routed['action'] = self::$default['action'];
					}
			
					$segs = count($rs);
					if($segs)
					{
						for ($i = 0; $i < $segs; ++$i)
						{
							$as[$i] = isset($rs[$i]) ? urldecode($rs[$i]) : null;
						}
						
						self::$routed['args'] = $as;
					}
					unset($rs, $as);
				}

			}
		}
	}

}

function web20vnReplace($str, $args = array(), $sc = '?')
{
	if(strpos($str, $sc) !== false && !empty($args))
	{
		$s = '';
		$arr = explode($sc, $str);
		
		for($i = 0, $count = count($arr); $i < $count; $i++)
		{
			if(!isset($args[$i]))
			{
				$s .= $arr[$i]; 
				continue;
			}
			$s .= $arr[$i].$args[$i];
		}

		return $s;
	}

	return $str;
}

function replace_once($search, $replace, $subject)
{
    if(($pos = strpos($subject, $search)) !== false)
    {
        $ret = substr($subject, 0, $pos).$replace.substr($subject, $pos + strlen($search));
    }
    else
    {
        $ret = $subject;
    }
   
    return $ret;
}

/******************************************************
// Example
// http://localhost/web20vn_router.php?q=welcome/index

.htacess
RewriteEngine ON
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ web20vn_router.php?q=$1 [L,QSA]
*******************************************************/

web20vnRouter::$routes += array(
	'blog1'	=> array(
		'u' => 'blog/?/?',
		'r' => array('(:year/:month/:day)', '(:alias)'),
		'p' => array('ymd', 'alias'),
		'c' => 'welcome', 'a' => 'view_blog',
	)
);

web20vnRouter::call();

?>

<a href="/web20vn_router.php?q=welcome/index">Welcome =&gt; index</a>
<br />
<a href="/web20vn_router.php?q=blog/2008/02/07/chuc-mung-nam-moi.html">Blog =&gt; chuc-mung-nam-moi</a>
<br />

<?php
echo '<pre>';
echo web20vnRouter::$uri."\n";
print_r(web20vnRouter::$routed);
echo '</pre>';

$time_end = microtime(true);
$time = $time_end - $time_start;

exit('Time: '.$time);
Return current item: web20vnRouter