Я смотрел на маршрутизацию URL фреймворка Limonade micro PHP и опубликовал ответ, используя кодовую базу limonade. Однако я вернулся и посмотрел на код паутины, и это довольно мило и приятно. Поэтому я просто взял URL-маршрутизацию Cobweb и реорганизовал ее в ООП PHP5.x для использования в моем собственном коде.
для сравнения см .: - http://docs.djangoproject.com/en/dev/topics/http/urls/ против http://www.limonade -php.net / README.htm
Обычные правовые оговорки на месте
1) Я не много тестировал!
2) Возможно, он не обладает всеми возможностями маршрутизации URL в Django
<?php
/**
*
* @author rajeev jha (jha dot rajeev at gmail)
* Django style URL routing.
* Pattern matching logic of this code is copied from cobweb framework
* @see http://code.google.com/p/cobweb/source/browse/trunk/dispatch/url_resolver.class.php
*
*/
class Gloo_Core_Router {
private $table ;
function __construct() {
//initialize routing table
$this->table = new Gloo_Core_RoutingTable();
}
function getRoute($path,$domain=NULL){
if(empty($path)) {
$message = sprintf("Please supply a valid path to match :: got [%s] ", $path);
trigger_error($message,E_USER_ERROR);
}
//all rules for this domain
$rules = $this->table->getRules($domain);
$route = NULL ;
if($path == '/')
$route = $this->matchHome($rules);
else
$route = $this->match($rules,$path);
return $route ;
}
private function matchHome($rules) {
$route = NULL ;
foreach($rules as $rule) {
if($rule["pattern"] == '/') {
$route = $this->createRoute($rule,array());
}
}
return $route ;
}
private function match($rules,$path) {
$path = ltrim($path, '/');
$matches = array();
$route = NULL ;
foreach($rules as $rule) {
if(preg_match($this->patternize($rule["pattern"]),$path,$matches) != 0 ) {
//match happened
$matches = $this->sanitizeMatches($matches);
$route = $this->createRoute($rule,$matches);
}
}
return $route ;
}
private function createRoute($rule,$matches) {
$route = $rule ;
//add parameters
$route["params"] = $matches ;
return $route ;
}
private function sanitizeMatches($matches){
//discard the first one
if (count($matches) >= 1)
$matches = array_splice($matches,1);
$unset_next = false;
//group name match will create a string key as well as int key
// like match["token"] = soemthing and match[1] = something
// remove int key when string key is present for same value
foreach ($matches as $key => $value) {
if (is_string($key)){
$unset_next = true;
} else if (is_int($key) && $unset_next) {
unset($matches[$key]);
$unset_next = false;
}
}
return array_merge($matches);
}
private function patternize($pattern) {
//http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php
//treat pattern as UTF-8
return '{'.$pattern.'}u' ;
}
}
?>
<?php
/**
*
* @author rajeev jha (jha dot rajeev at gmail)
* Django style URL routing.
* URL routing table
*
*/
class Gloo_Core_RoutingTable {
private $rules ;
private $splrules ;
const ANY_DOMAIN = '__ANY__' ;
function __construct() {
$this->rules = array();
$this->splrules = array();
//@todo inject from outside
$this->createRule(self::ANY_DOMAIN, '/', 'Gloo_Controller_Home');
//match alphanumeric + dashes
//a pcre word (\w) does not contain dashes
$this->createRule(self::ANY_DOMAIN, '^(?P<token>[-\w]+)$','Gloo_Controller_Post');
$this->createRule(self::ANY_DOMAIN, '^page/(?P<pagenum>\d+)$','Gloo_Controller_Home');
$this->createRule(self::ANY_DOMAIN, '^(?P<token>\w+)/page/(?P<pagenum>\d+)$','Gloo_Controller_Post');
$this->createRule(self::ANY_DOMAIN, '^category/(?P<name>\w+)$','Gloo_Controller_Category');
$this->createRule(self::ANY_DOMAIN, '^category/(?P<name>\w+)/page/(?P<pagenum>\d+)$','Gloo_Controller_Category');
//special rules
$this->createRule('www.test1.com','^(?P<token>\w+)$','Gloo_Controller_File', array("template" => "post.php"));
}
function createRule($domain,$pattern,$action,$options=NULL) {
if(empty($domain)) {
trigger_error("No domain supplied for rule" ,E_USER_ERROR);
}
$rule = array();
$rule["pattern"] = $pattern;
$rule["action"] = $action ;
//Add options
if(is_null($options))
$rule["options"] = array();
else
$rule["options"] = $options ;
$rule["domain"] = $domain ;
//add to generic or domain specific rules
if($domain == self::ANY_DOMAIN)
$this->rules[] = $rule ;
else
$this->splrules[$domain][] = $rule ;
}
function getRules($domain) {
if(empty($domain))
return $this->rules ;
//valid domain - rules as well
// add to existing rules
if(array_key_exists($domain,$this->splrules)) {
$splrules = $this->splrules[$domain];
$rules = array_merge($this->rules,$splrules);
return $rules ;
} else {
return $this->rules ;
}
}
}
?>
Теперь вы можете добавить любые правила для инициализации таблицы маршрутизации. в зависимости от того, какой домен + «путь» вы указываете маршрутизатору, вы получите строку «controller» вместе с параметрами «named group» и другими соответствующими параметрами. Я не включаю логику создания класса для строк контроллера, потому что
1) это было бы сложно
2) Если вы намереваетесь просто получить Django-подобную URL-маршрутизацию, то этого достаточно.
Ссылки
Код Лимонады здесь: -
https://github.com/sofadesign/limonade/blob/master/lib/limonade.php
Код паутины здесь: - http://code.google.com/p/cobweb/source/browse/trunk/dispatch/url_resolver.class.php
- Мой код здесь: - https://code.google.com/p/webgloo/source/browse/trunk/php/lib/Gloo/Core/Router.php
- Старая версия моего кода: - то, что я редактировал здесь - было основано на лимонаде, и это было довольно повреждено мозгом. Не стесняйтесь смотреть на ссылку Limonade выше. Я удаляю это.
Использование
$ router = new Gloo_Core_Router ();
$path = 'category/news/page/3' ;
printf("Now matching path [%s]" , $path);
$route = $router->getRoute($path);
print_r($route);
$path = '/category/Health/page' ;
printf("Now matching path [%s]" , $path);
$route = $router->getRoute($path);
print_r($route);
Вы должны изменить имена классов и включить зависимости, но, эй, вы программист; D