使用symfony2路由组件(在symfony2之外) [英] Using symfony2 routing component (outside of symfony2)

查看:99
本文介绍了使用symfony2路由组件(在symfony2之外)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在搜索,并没有真正找到有用的信息。我希望在我自己的个人框架中使用symfony2路由组件(以及yaml组件),但没有找到有关基本设置的任何文档。 symfony网站上的文档很好地解释了如何使用该组件但是独立安装的方式不多。

I've been searching and haven't really found much useful information. I'm looking to use the symfony2 routing component (and also yaml component) with my own personal framework but haven't found any documentation on basic setup. The documentation on the symfony site does a good job of explaining how to use the component but not much in the way of standalone setup.

有人可以推荐一个不错的起点来解释如何设置单个symfony2组件吗?

Can anyone recommend a good place to start that could explain how to setup individual symfony2 components?

推荐答案

我最终查看了 symfony网站以及github上的源代码( Route.php RouteCollection .php RouteCompiler.php ),并提出了我自己的基本路由器。

I ended up looking at the documentation on the symfony site, as well as the source code on github (Route.php, RouteCollection.php, RouteCompiler.php) and came up with my own basic router.

就像symfony一样,我允许将4个参数传递给路由类-> 1)模式,2)默认控制器/动作,3)regex要求模式中的每个变量,以及4)任何选项-由于尚未满足我的要求,因此我尚未对此进行编码。

Just like symfony, I allow 4 arguments to be passed to the route class -> 1) the pattern, 2) the default controller/action, 3) regex requirements for each variable in the pattern, and 4) any options - I haven't coded for this yet as it's not in my requirements.

我的主/前端控制器(索引。 php)仅与静态Router类进行对话,该类可以访问lib\route名称空间中的其他路由类。

My main/front controller (index.php) only talks to the static Router class which has access to the other route classes in the lib\route namespace.

Router :: Map基本上会编译一个正则表达式字符串(以及默认的控制器/动作和变量名称),该字符串会传递给在Router :: _ Process中使用的namedRouteCollection与httpRequest相匹配。从那里开始,如果处理方法中存在匹配项,那么我将根据匹配的compedRoute默认控制器/操作的值设置控制器/操作/参数。如果没有preg_match,则使用请求对象中的默认控制器/动作/参数。剩下的就是蛋糕了……

Router::Map basically compiles a regex string (along with default controller/action and variable names) that gets passed to the compiledRouteCollection which is used in Router::_Process to match the httpRequest against. From there, if there is a match in the process method then i set the controller/action/args based on the values of the matched compiledRoute default controller/action. If there is not a preg_match then i use the default controller/action/args from the request object. The rest is cake...

我希望有人觉得这很有用,并且可以节省他们我今天在此上花费的时间。加油!

I hope someone finds this useful and it's able to save them the time I spent today working on this. Cheers!

index.php

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

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

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

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

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

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;
}
}

这篇关于使用symfony2路由组件(在symfony2之外)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆