PHP:Làm router

Bài từ dự án mở Ứng dụng mẫu.


Chấm điểm ( 26 votes )
3.50 / 5
User Comments ( 5 messages, page 1 of 1 )

UngDungMau:

2008-06-15 05:46:27

matthieu:
Hi from france. I integrated your router class into my framework. Even if i don't understand your webpage greetings for the router. It works great !!!

2008-05-26 05:18:31

jweur:
Cái này chỉ đáng vứt sọt rác hahahaahahhaha

2008-02-03 17:46:06

UngDungMau:
blog1 dùng để tạo uri từ uri trong route. Ví dụ: url('blog1', array('2008/02/07', 'tieu-de-bai-viet'));
Kết quả: blog/2008/02/07/tieu-de-bai-viet

2008-01-30 15:46:12

rd21:
blog1 để làm cái gì nhỉ?

2008-01-29 14:35:36

Tại phần chứa mảng routes:

  • uuri, chứa giá trị của uri để so sánh với web20vnRouter::$uri
  • rregex, thảm khảo Pattern Syntax
  • pparam, nếu rỗng, các tham số trên regex sẽ được đánh số và kèm theo p, ví dụ: p1 <=> ymd, p2 <=> alias)
echo web20vnRouter::$routed['args'][2];
// hoặc
echo web20vnRouter::$routed['args']['alias']; 
// Kết quả: chuc-mung-nam-moi
  • ccontroller
  • aaction
web20vnRouter::$routes += array(
	'blog_by_date'	=> array(
		'u' => 'blog/?/?',
		'r' => array('(:year/:month/:day)', '(:alias)'),
		'p' => array('ymd', 'alias'),
		'c' => 'welcome', 'a' => 'view_blog',
	)
);

Nếu không có route trùng với uri, mặc định sẽ tách theo kí tự /. Nếu uri là: welcome/index/123/xin-chao thì kết quả sẽ là:

welcome/index/123/xin-chao
Array
(
    [controller] => welcome
    [action] => index
    [args] => Array
        (
            [0] => 123
            [1] => xin-chao
        )
)

Nếu uri trùng với route có trong routes, kết quả sẽ là: http://localhost/web20vn_router.php?q=blog/2008/02/07/chuc-mung-nam-moi.html

blog/2008/02/07/chuc-mung-nam-moi
Array
(
    [controller] => welcome
    [action] => view_blog
    [args] => Array
        (
            [ymd] => 2008/02/07
            [0] => 2008/02/07
            [alias] => chuc-mung-nam-moi
            [1] => chuc-mung-nam-moi
        )

)

web20vn_router.php

  1. <?php
  2. /**
  3.  * web20vn.com Router
  4.  *
  5.  * @author     Le Khac Nhu <lekhacnhu@gmail.com>
  6.  * @author     brandlover <web20vn@gmail.com>
  7.  * @copyright  http://web20vn.com
  8.  * @version    1.0 [20080128]
  9.  */
  10.  
  11. $time_start = microtime(true);
  12.  
  13. class web20vnRouter
  14. {
  15.         public static $uri                              = null;
  16.         public static $url_suffix               = '.html';
  17.         public static $index_file               = 'web20vn_router.php';
  18.  
  19.         public static $routes                   = array();
  20.         public static $placeholder              = array(
  21.                 ':any'          => '.+',
  22.                 ':alias'        => '[a-zA-Z0-9\_\-\.]+',
  23.                 ':num'          => '[0-9]+',
  24.                 ':year'         => '[0-9]{4}',
  25.                 ':month'        => '[0-9]{2}',
  26.                 ':day'          => '[0-9]{2}',
  27.         );
  28.        
  29.         public static $routed                   = array(
  30.                 'controller'    => '',
  31.                 'action'                => '',
  32.                 'args'                  => '',
  33.         );
  34.  
  35.         public static $default = array(
  36.                 'controller'    => 'welcome',
  37.                 'action'                => 'index',
  38.         );
  39.  
  40.         public static function call($uri = null)
  41.         {
  42.                 if(empty($uri))
  43.                 {
  44.                         self::getUri();
  45.                 }
  46.                 self::start();
  47.         }
  48.  
  49.         public static function getUri()
  50.         {
  51.                 $temp_url = '';
  52.  
  53.                 if(isset($_GET['q']) && $_GET['q'] != '')
  54.                 {
  55.                         $temp_url = $_GET['q'];
  56.                 }
  57.                 elseif (isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'])
  58.                 {
  59.                         $temp_url = $_SERVER['PATH_INFO'];
  60.                 }
  61.                 elseif (isset($_SERVER['ORIG_PATH_INFO']) && $_SERVER['ORIG_PATH_INFO'])
  62.                 {
  63.                         $temp_url = $_SERVER['ORIG_PATH_INFO'];
  64.                 }
  65.                 elseif (isset($_SERVER['PHP_SELF']) && $_SERVER['PHP_SELF'])
  66.                 {
  67.                         $temp_url = $_SERVER['PHP_SELF'];
  68.                 }
  69.  
  70.                 $temp_url = trim($temp_url, '/');
  71.  
  72.                 if (($offset = strpos($temp_url, self::$index_file)) !== false)
  73.                 {
  74.                         $offset += strlen(self::$index_file);
  75.                         $temp_url = substr($temp_url, $offset);
  76.                 }
  77.                
  78.                 if (strpos($temp_url, self::$url_suffix) !== false)
  79.                 {
  80.                         $temp_url = preg_replace('#'.preg_quote(self::$url_suffix).'$#u', '', $temp_url);
  81.                         //$temp_url = replace_once(self::$url_suffix, '', $temp_url);
  82.                 }
  83.  
  84.                 self::$uri = preg_replace('#/+#', '/', $temp_url);
  85.         }
  86.  
  87.         public static function start()
  88.         {
  89.                 $is_routed = false;
  90.                
  91.                 // Neu rong => mac dinh (trang chu)
  92.                 if (empty(self::$uri) || self::$uri === '/')
  93.                 {
  94.                         self::$routed['controller'] = self::$default['controller'];
  95.                         self::$routed['action'] = self::$default['controller'];
  96.                         $is_routed = true;
  97.                 }
  98.                 else
  99.                 {
  100.                         if(count(self::$routes) > 0)
  101.                         {
  102.                                 foreach(self::$routes as $rule => &$route)
  103.                                 {
  104.                                         if(!isset($route['u']))
  105.                                         {
  106.                                                 exit('Route khong hop le: '.$rule);
  107.                                         }
  108.                                        
  109.                                         $routed_c = isset($route['c']) ? $route['c'] : self::$default['controller'];
  110.                                         $routed_a = isset($route['a']) ? $route['a'] : self::$default['action'];
  111.  
  112.                                         if($route['u'] === self::$uri)
  113.                                         {
  114.                                                 self::$routed['controller'] = $routed_c;
  115.                                                 self::$routed['action'] = $routed_a;
  116.                                                 $is_routed = true;
  117.                                                 break;
  118.                                         }
  119.                                        
  120.                                         if(strpos($route['u'], '?') !== false)
  121.                                         {
  122.                                                 if(!isset($route['r']))
  123.                                                 {
  124.                                                         exit('Trong route ('.$rule.') chua co regex!!!');
  125.                                                 }
  126.                                                
  127.                                                 // Tao params...
  128.                                                 $i = 0;
  129.                                                 foreach($route['r'] as $rr)
  130.                                                 {
  131.                                                         if($rr[0] == '(')
  132.                                                         {
  133.                                                                 $p = isset($route['p'][$i]) ? $route['p'][$i] : 'p'.$i;
  134.                                                                 $route['r'][$i] = replace_once('(', '(?P<'.$p.'>', $rr);
  135.                                                         }
  136.                                                         ++$i;
  137.                                                 }
  138.                                                
  139.                                                 $r_ex = web20vnReplace($route['u'], $route['r']);
  140.  
  141.                                                 // Placeholder
  142.                                                 if (strpos($r_ex, ':') !== false) {
  143.                                                         $r_ex = strtr($r_ex, self::$placeholder);
  144.                                                 }
  145.  
  146.                                                 if(preg_match('#^'.$r_ex.'$#ui', self::$uri, $matches))
  147.                                                 {
  148.                                                         self::$routed['args']           = array_slice($matches, 1);
  149.                                                         self::$routed['controller'] = $routed_c;
  150.                                                         self::$routed['action']         = $routed_a;
  151.                                                         $is_routed = true;
  152.                                                         break;
  153.                                                 }
  154.                                         }
  155.                                 }
  156.                                
  157.                                 if(!$is_routed)
  158.                                 {
  159.                                         $rs = explode('/', self::$uri);
  160.  
  161.                                         //Controller:
  162.                                         if (count($rs) && !empty($rs[0])) {
  163.                                                 self::$routed['controller'] = array_shift($rs);
  164.                                 }
  165.                                         else
  166.                                         {
  167.                                                 self::$routed['controller'] = self::$default['controller'];
  168.                                         }
  169.                                        
  170.                                         //Action:
  171.                                 if (count($rs) && !empty($rs[0])) {
  172.                                         self::$routed['action'] = array_shift($rs);
  173.                                 }
  174.                                         else
  175.                                         {
  176.                                                 self::$routed['action'] = self::$default['action'];
  177.                                         }
  178.                        
  179.                                         $segs = count($rs);
  180.                                         if($segs)
  181.                                         {
  182.                                                 for ($i = 0; $i < $segs; ++$i)
  183.                                                 {
  184.                                                         $as[$i] = isset($rs[$i]) ? urldecode($rs[$i]) : null;
  185.                                                 }
  186.                                                
  187.                                                 self::$routed['args'] = $as;
  188.                                         }
  189.                                         unset($rs, $as);
  190.                                 }
  191.  
  192.                         }
  193.                 }
  194.         }
  195.  
  196. }
  197.  
  198. function web20vnReplace($str, $args = array(), $sc = '?')
  199. {
  200.         if(strpos($str, $sc) !== false && !empty($args))
  201.         {
  202.                 $s = '';
  203.                 $arr = explode($sc, $str);
  204.                
  205.                 for($i = 0, $count = count($arr); $i < $count; $i++)
  206.                 {
  207.                         if(!isset($args[$i]))
  208.                         {
  209.                                 $s .= $arr[$i];
  210.                                 continue;
  211.                         }
  212.                         $s .= $arr[$i].$args[$i];
  213.                 }
  214.  
  215.                 return $s;
  216.         }
  217.  
  218.         return $str;
  219. }
  220.  
  221. function replace_once($search, $replace, $subject)
  222. {
  223.     if(($pos = strpos($subject, $search)) !== false)
  224.     {
  225.         $ret = substr($subject, 0, $pos).$replace.substr($subject, $pos + strlen($search));
  226.     }
  227.     else
  228.     {
  229.         $ret = $subject;
  230.     }
  231.    
  232.     return $ret;
  233. }
  234.  
  235.  
  236. /******************************************************
  237. // Vi du
  238. // http://localhost/web20vn_router.php?q=welcome/index
  239.  
  240. .htacess
  241. RewriteCond %{REQUEST_FILENAME} !-f
  242. RewriteCond %{REQUEST_FILENAME} !-d
  243. RewriteCond %{REQUEST_FILENAME} !-l
  244. RewriteRule ^(.*)$ web20vn_router.php?q=$1 [L,QSA]
  245. *******************************************************/
  246.  
  247. web20vnRouter::$routes += array(
  248.         'blog_by_date'  => array(
  249.                 'u' => 'blog/?/?',
  250.                 'r' => array('(:year/:month/:day)', '(:alias)'),
  251.                 'p' => array('ymd', 'alias'),
  252.                 'c' => 'welcome', 'a' => 'view_blog',
  253.         )
  254. );
  255.  
  256. web20vnRouter::call();
  257.  
  258. ?>
  259.  
  260. <a href="web20vn_router.php?q=welcome/index">Welcome =&gt; index</a>
  261. <br />
  262. <a href="web20vn_router.php?q=blog/2008/02/07/chuc-mung-nam-moi.html">Blog =&gt; chuc-mung-nam-moi</a>
  263. <br />
  264.  
  265. <?php
  266. echo '<pre>';
  267. echo web20vnRouter::$uri."\n";
  268. print_r(web20vnRouter::$routed);
  269. echo '</pre>';
  270.  
  271. $time_end = microtime(true);
  272. $time = $time_end - $time_start;
  273.  
  274. exit('Time: '.$time);

Để tạo URI từ uri trong routes, bạn có thể làm như sau:

  1. function url($uri, $args = array())
  2. {
  3.     if(isset(web20vnRouter::$routes[$uri]['u']))
  4.     {
  5.         return web20vnReplace(web20vnRouter::$routes[$uri]['u'], $args);
  6.     }
  7.    
  8.     return $uri;
  9. }
  10. echo url('blog_by_date', array('2008/02/07', 'chuc-mung-nam-moi'));

Beehost Vietnam
Beehost Vietnam


Web 2.0 Việt Nam
Thắng cảnh đẹp

(©) Xin hãy ghi rõ nguồn gốc nếu bạn copy những bài viết từ www.UngDungMau.com
Xin cảm ơn!

Vì spam nhiều hơn đóng góp nên bạn phải đăng ký tài khoản nếu muốn sửa bài