2011-07-16 79 views
4

我一直在搜索,並沒有真正發現很多有用的信息。我正在尋找使用symfony2路由組件(也包括yaml組件)和我自己的個人框架,但沒有找到任何有關基本設置的文檔。關於symfony site的文檔在解釋如何使用該組件方面做得很好,但在獨立設置方面沒有太多。使用symfony2路由組件(symfony2之外)

任何人都可以推薦一個好的地方開始,可以解釋如何設置個人symfony2組件?

+0

很好的問題!我目前在想,完全一樣! – Raffael

回答

-3

我結束了在看的symfony site的文件,以及在GitHub上的源代碼(Route.phpRouteCollection.phpRouteCompiler.php)和我自己的基本的路由器上來。我可以將4個參數傳遞給路由類 - > 1)模式,2)默認控制器/動作,3)模式中每個變量的正則表達式要求,以及4)任何選項 - 我還沒有編碼,因爲它不符合我的要求。

我的主/前端控制器(index.php)只與可訪問lib \ route命名空間中其他路由類的靜態路由器類通信。

Router :: Map基本上編譯了一個正則表達式字符串(以及默認的控制器/動作和變量名稱),該字符串被傳遞給用於Router :: _ Process中的compiledRouteCollection以匹配httpRequest。從那裏,如果在處理方法中有匹配,那麼我會根據匹配的compiledRoute默認控制器/操作的值來設置controller/action/args。如果沒有preg_match,那麼我使用請求對象的默認controller/action/args。剩下的就是蛋糕...

我希望有人發現這個有用,它能夠節省他們我今天花在這上面的時間。乾杯!

的index.php

require_once 'config/config.php'; 
require_once 'lib/autoload.php'; 
lib\Router::Map(
    'users_username_id', 
    'users/{username}/{id}', 
    array('controller' => 'testController', 'action' => 'users') 
); 
lib\Router::Route(new lib\Request()); 

router.php

namespace lib; 

class Router { 
protected static $_controller; 
protected static $_action; 
protected static $_args; 
protected static $_compiledRouteCollection; 
private static $_instance; 

private function __construct() { 
    self::$_compiledRouteCollection = new \lib\route\CompiledRouteCollection(); 
} 

public static function Singleton() { 
    if(!isset(self::$_instance)) { 
     $className = __CLASS__; 
     self::$_instance = new $className; 
    } 
    return self::$_instance; 
} 

public static function Route(Request $request, $resetProperties = false) { 
    self::Singleton(); 

    self::_Process($request,$resetProperties); 

    $className = '\\app\\controllers\\' . self::$_controller; 
    if(class_exists($className, true)) { 
     self::$_controller = new $className; 

     if(is_callable(array(self::$_controller, self::$_action))) { 
      if(!empty(self::$_args)) { 
       call_user_func_array(array(self::$_controller, self::$_action), self::$_args); 
      } else { 
       call_user_func(array(self::$_controller, self::$_action)); 
      } 
      return; 
     } 
    } 
    self::Route(new \lib\Request('error'),true); 
} 

public static function Map($name, $pattern, array $defaults, array $requirements = array(), array $options = array()) { 
    self::Singleton(); 
    $route = new \lib\route\Route($pattern,$defaults,$requirements,$options); 
    $compiledRoute = $route->Compile(); 
    self::$_compiledRouteCollection->Add($name,$compiledRoute); 
} 

private static function _Process(Request $request, $resetProperties = false) { 
    $routes = array(); 
    $routes = self::$_compiledRouteCollection->routes; 
    foreach($routes as $route) { 
     preg_match($route[0]['regex'], $request->GetRequest(), $matches); 
     if(count($matches)) { 
      array_shift($matches); 
      $args = array(); 
      foreach($route[0]['variables'] as $variable) { 
       $args[$variable] = array_shift($matches); 
      } 
      self::$_controller = (!isset(self::$_controller) || $resetProperties) ? $route[0]['defaults']['controller'] : self::$_controller; 
      self::$_action = (!isset(self::$_action) || $resetProperties) ? $route[0]['defaults']['action'] : self::$_action; 
      self::$_args = (!isset(self::$_args) || $resetProperties) ? $args : self::$_args; 

      return; 
     } 
    } 
    self::$_controller = (!isset(self::$_controller) || $resetProperties) ? $request->GetController() : self::$_controller; 
    self::$_action = (!isset(self::$_action) || $resetProperties) ? $request->GetAction() : self::$_action; 
    self::$_args = (!isset(self::$_args) || $resetProperties) ? $request->GetArgs() : self::$_args; 
} 
} 

request.php

namespace lib; 

class Request { 
protected $_controller; 
protected $_action; 
protected $_args; 
protected $_request; 

public function __construct($urlPath = null) { 
    $this->_request = $urlPath !== null ? $urlPath : $_SERVER['REQUEST_URI']; 

    $parts = explode('/', $urlPath !== null ? $urlPath : $_SERVER['REQUEST_URI']); 
    $parts = array_filter($parts); 

    $this->_controller = (($c = array_shift($parts)) ? $c : 'index').'Controller'; 
    $this->_action = ($c = array_shift($parts)) ? $c : 'index'; 
    $this->_args = (isset($parts[0])) ? $parts : array(); 
} 

public function GetRequest() { 
    return $this->_request; 
} 

public function GetController() { 
    return $this->_controller; 
} 

public function GetAction() { 
    return $this->_action; 
} 

public function GetArgs() { 
    return $this->_args; 
} 
} 

route.php

namespace lib\route; 

class Route { 
private $_pattern; 
private $_defaults; 
private $_requirements; 
public $_options; 

public function __construct($pattern, array $defaults = array(), array $requirements = array(), array $options = array()) { 
    $this->SetPattern($pattern); 
    $this->SetDefaults($defaults); 
    $this->SetRequirements($requirements); 
    $this->SetOptions($options); 
} 

public function SetPattern($pattern) { 
    $this->_pattern = trim($pattern); 

    if($this->_pattern[0] !== '/' || empty($this->_pattern)) { 
     $this->_pattern = '/'.$this->_pattern; 
    } 
} 

public function GetPattern() { 
    return $this->_pattern; 
} 

public function SetDefaults(array $defaults) { 
    $this->_defaults = $defaults; 
} 

public function GetDefaults() { 
    return $this->_defaults; 
} 

public function SetRequirements(array $requirements) { 
    $this->_requirements = array(); 
    foreach($requirements as $key => $value) { 
     $this->_requirements[$key] = $this->_SanitizeRequirement($key,$value); 
    } 
} 

public function GetRequirements() { 
    return $this->_requirements; 
} 

public function SetOptions(array $options) { 
    $this->_options = array_merge(
     array('compiler_class' => 'lib\\route\\RouteCompiler'), 
     $options 
    ); 
} 

public function GetOptions() { 
    return $this->_options; 
} 

public function GetOption($name) { 
    return isset($this->_options[$name]) ? $this->_options[$name] : null; 
} 

private function _SanitizeRequirement($key, $regex) { 
    if($regex[0] == '^') { 
     $regex = substr($regex, 1); 
    } 

    if(substr($regex, -1) == '$') { 
     $regex = substr($regex,0,-1); 
    } 

    return $regex; 
} 

public function Compile() { 
    $className = $this->GetOption('compiler_class'); 
    $routeCompiler = new $className; 

    $compiledRoute = array(); 
    $compiledRoute = $routeCompiler->Compile($this); 
    return $compiledRoute; 
} 
} 

routeCompiler.php

namespace lib\route; 

class RouteCompiler { 

//'#\/tellme\/users\/[\w\d_]+\/[\w\d_]+#' 
public function Compile(Route $route) { 
    $pattern = $route->GetPattern(); 
    $requirements = $route->GetRequirements(); 
    $options = $route->GetOptions(); 
    $defaults = $route->GetDefaults(); 
    $len = strlen($pattern); 
    $tokens = array(); 
    $variables = array(); 
    $pos = 0; 
    $regex = '#'; 

    preg_match_all('#.\{([\w\d_]+)\}#', $pattern, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); 
    if(count($matches)) { 
     foreach($matches as $match) { 
      if($text = substr($pattern, $pos, $match[0][1] - $pos)) { 
       $regex .= str_replace('/', '\/', $text).'\/'; 
      } 
      if($var = $match[1][0]) { 
       if(isset($requirements[$var])) { 
        $regex .= '('.$requirements[$var].')\/'; 
       } else { 
        $regex .= '([\w\d_]+)\/'; 
       } 
       $variables[] = $match[1][0]; 
      } 
      $pos = $match[0][1] + strlen($match[0][0]); 

     } 
     $regex = rtrim($regex,'\/').'#'; 
    } else { 
     $regex .= str_replace('/', '\/', $pattern).'#'; 
    } 

    $tokens[] = array(
     'regex' => $regex, 
     'variables' => $variables, 
     'defaults' => $defaults 
    ); 
    return $tokens; 
} 
} 

compiledRouteCollection.php

namespace lib\route; 

class CompiledRouteCollection { 
public $routes; 

public function __construct() { 
    $this->routes = array(); 
} 

public function Add($name, array $route) { 
    $this->routes[$name] = $route; 
} 
} 
+0

你不使用symfony2組件。你只需編寫你自己的前端控制器。大。但這不是問題所在!? – Raffael

+0

@ Raffael1984我使用symfony 2路由組件作爲我的路由基礎。當我沒有得到答案時,我決定簡化symfony路由器以適應我的需求。看起來像這是答案,如果你仔細看看源代碼,這將很好地解釋它是如何工作的,以及如何在你理解它的時候將它併入你的框架。 – bflemi3

+1

簡單的朋友...我感覺與你...目前的具體組件的文件尚未平等。順便說一下,我發現你在他們的IRC頻道上獲得了非常有效的關於sf2素材的反饋......看看那裏。 – Raffael