[ Milan Kragujevic @ 07.10.2013. 00:14 ] @
Napisao sam sinoć jednu malu klasu koja služi kao example routing sistem za moj blog jer nisam zadovoljan trenutnim rešenjem, pa me zanimaju kritike i analiza iskusnijih od mene. Pattern delovi - :m{NESTO}: - možda operator, string mora biti eskejpovan - :>1a: slova, više od jednog - :a: slova - :>1an: slova i brojevi, više od jednog - :an: slova i brojevi - :>1n: brojevi, više od jednog - :n: brojevi - |i (na kraju) - case-insensitive operator Primer koda Code (php): Taj primer će izbaciti Hello, [nešto] kada mu se pristupi sa adrese [putanja_do_web_roota]index.php/hello/[nešto]Class Example { public function hello($what) { echo "Hello, $what!"; } } $router = new Router; try { $router->bind('hello/:an::m{/}:', 'Example->hello'); // u slucaju pozivanja funkcije stavite naziv funkcije, a ako se funkcija nalazi u klasi stavite ImeKlase->ImeMetodeKlase. Metoda klase [b]mora biti[/b] public. } catch (Exception $e) { echo "<b>An error occurred!</b><br/><pre>$e</pre>"; } Važno: Na početku index.php fajla pre include-ovanja ili require-ovanja svih ostalih fajlova morate definisati __INDEX__ sa vrednošću __FILE__. Primer: const __INDEX__ = __FILE__;. Izvorni kod klase Code (php): <?php Class Router { private $request_uri; private $self; private $request_params; private $params; private $bundles; public function __construct() { $this->request_uri = $_SERVER['REQUEST_URI']; $this->self = basename(__INDEX__); $request_uri_array = explode($this->self, $this->request_uri); $this->request_params = end($request_uri_array); $this->request_params = rtrim(ltrim($this->request_params, '/'), '/'); } private function call_function($func, $args = array()) { if(!is_array($args)) { throw new Exception("call_function expects second parameter to be an array, ".gettype($args)." given"); } else { if(!preg_match('/\->/ism', $func)) { if(is_callable($func)) { call_user_func_array($func, $args); } else { throw new Exception("Can't call the function $func"); } } else { $func_data = explode('->', $func); $class_name = $func_data[0]; $function_in_class = $func_data[1]; if(class_exists($class_name)) { $class_instance = new $class_name; if(method_exists($class_instance, $function_in_class)) { call_user_func_array(array($class_instance, $function_in_class), $args); } else { throw new Exception("Can't call the method $function_in_class in class $class_name because the class' method doesn't exist."); } } else { throw new Exception("Can't call the method $function_in_class in class $class_name because the class doesn't exist."); } } } } private function pattern2regex($pattern) { //[0-9] |i $ins = false; // case insensitive if(preg_match('/|i/ism', $pattern)) { $ins = true; $pattern = str_replace('|i', '', $pattern); } $dictionary = array( '(' => '\(', '[' => '\[', ']' => '\]', '*' => '\*', '?' => '\?', ')' => '\)', '/' => '\/', '$' => '\$', '+' => '\+', '^' => '\^', '{' => '\{', '}' => '\}', '|' => '\|' ); $quick_syntax = array( ':>1an:' => '((?:[a-z][a-z0-9_\-]*))', // alphanumerical, more than one ':an:' => '((?:[a-z0-9_\-]*))', // alphanumerical ':n:' => '(\d+)', //numerical ':>1n:' => '(\\d+)', //numerical, more than one ':>1a:' => '((?:[a-z][a-z]+))', // alpha only, more than one ':a:' => '((?:[a-z]+))' // alpha only ); $pattern = str_replace(array_keys($dictionary), array_keys(array_flip($dictionary)), $pattern); $pattern = str_replace(array_keys($quick_syntax), array_keys(array_flip($quick_syntax)), $pattern); $pattern = preg_replace('/\:m\\\{([^\}]*?)\\\}:/ism', '([$1]?)', $pattern); // maybe block $pattern = '/'.$pattern.'/'.($ins?'i':'').'sm'; return $pattern; } private function pattern_match($pattern) { $pattern_regex = $this->pattern2regex($pattern); return @preg_match($pattern_regex, $this->request_params); } private function get_url_values($pattern) { $pattern_regex = $this->pattern2regex($pattern); $url_values = array(); if(preg_match_all($pattern_regex, $this->request_params, $values)) { foreach($values as $id => $value) { if($id !== 0) { $value1 = $value[0]; $url_values[] = $value1; } } } return $url_values; } public function bind($pattern, $function, $params = array()) { $pattern = rtrim(ltrim($pattern, '/'), '/'); extract($params, EXTR_PREFIX_SAME, "copy"); if($this->pattern_match($pattern)) { $this->call_function($function, $this->get_url_values($pattern)); } } } [Ovu poruku je menjao Milan Kragujevic dana 07.10.2013. u 22:03 GMT+1] [Ovu poruku je menjao Milan Kragujevic dana 07.10.2013. u 22:13 GMT+1] |