Django-подобная маршрутизация URL для PHP - PullRequest
5 голосов
/ 09 февраля 2011

Я ищу способ обеспечить URL-маршрутизацию, аналогичную той, которая есть в Django. Я просмотрел много ресурсов в сети, и мне понравилось cobweb , но проблема в том, что я не хочу использовать всю инфраструктуру, я просто хочу использовать логику / код перенаправления URL. Есть ли хороший ресурс только для Django-подобной логики маршрутизации URL?

Ответы [ 5 ]

7 голосов
/ 09 февраля 2011

То, что вы ищете, это микрофрейм. В основном это просто слой маршрутизации фреймворка. Есть несколько из них доступных. Это выглядело интересно для меня:

Однако меня поразил Silex , основанный на Symfony2 и требующий PHP 5.3.

3 голосов
/ 09 апреля 2011

Я смотрел на маршрутизацию 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-маршрутизацию, то этого достаточно.

Ссылки

  1. Код Лимонады здесь: - https://github.com/sofadesign/limonade/blob/master/lib/limonade.php

  2. Код паутины здесь: - http://code.google.com/p/cobweb/source/browse/trunk/dispatch/url_resolver.class.php

  3. Мой код здесь: - https://code.google.com/p/webgloo/source/browse/trunk/php/lib/Gloo/Core/Router.php
  4. Старая версия моего кода: - то, что я редактировал здесь - было основано на лимонаде, и это было довольно повреждено мозгом. Не стесняйтесь смотреть на ссылку 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

1 голос
/ 09 февраля 2011

Я не думаю, что это то же самое, но Zend Framework имеет довольно неплохую функциональность маршрутизации, на которую вы, возможно, захотите взглянуть. Zend Framework - это своего рода компонентная структура, которая не заставляет вас использовать все это. Но я думаю, что если вы используете функциональность маршрутизации, вам также может понадобиться использовать механизм их контроллера, так как маршрутизатор построен сверху.

0 голосов
/ 06 июля 2015

Я разработал подобный фреймворк с ресурсами codeigniter и django, http://williamborba.github.io/willer/quick_start/

Это все еще бета, но я постепенно внедряю и улучшаю файл URL.php, очень похожий на URLS.py django.

Другим важным моментом являются модели и ORM, очень похожие на django, но с чем-то похожим на активную запись codeigniter.

0 голосов
/ 09 февраля 2011

Вы можете посмотреть на CakePHP . Я не знаю, насколько легко было бы вывести логику маршрутизации URL из остальной части фреймворка.

...