FastRoute Test Demo

FastRoute Test Demo With PHP

Website:Fast request router for PHPphp

PregRoute.class

`git

<?php

class PregRoute
{
    const NOT_FOUND = 404;
    const FOUND     = 200;

    /**  ~^/user/([^/]+)/(\d+)$~
     *   ~^/user/(\d+)$~
     *   ~^/user/([^/]+)$~
     * @var string  單個正則
     */
    protected $single_regex = '~^/user/([^/]+)/(\d+)$~';

    /** 基於位置匹配
     * @var string 多個路由匹配規則
     */
    protected $combined_position_regex = "
                ~^(?:
                    /user/([^/]+)/(\d+)
                  | /user/(\d+)
                  | /user/([^/]+)
                )$~x";

    /** 位置匹配數據
     * @var array
     */
    protected $route_data_position = [
        1 => ['handler0', ['name', 'id']], # /user/tom/1   regex=>  /user/([^/]+)/(\d+)
        3 => ['handler1', ['id']],         # /user/1       regex=>  /user/(\d+)
        4 => ['handler2', ['name']],       # /user/tom     regex=>  /user/([^/]+)
    ];

    /** 基於計數匹配
     * @var string 多個路由匹配規則
     */
    protected $combined_count_regex = "
                ~^(?|
                    /user/([^/]+)/(\d+)
                  | /user/(\d+)()()
                  | /user/([^/]+)()()()
                )$~x";

    /** 基於計數匹配,只修改 ?:
     * @result 將 ?: 換成 ?| 能夠組號重置,但
     *          | /user/(\d+)
     *          | /user/([^/]+) 的count都相同,採用()進行個數填充,也可使用其它方式,如
     *          <result1>/user/(\d+)
     *          <result2>/user/([^/]+)
     * @var string
     */
    protected $combined_count_regex2 = "
                ~^(?|
                    /user/([^/]+)/(\d+)
                  | /user/(\d+)
                  | /user/([^/]+)
                )$~x";

    /** 計數匹配數據
     * @var array
     */
    protected $route_data_count = [
        3 => ['handler0', ['name', 'id']], # /user/tom/1   regex=>  /user/([^/]+)/(\d+)
        4 => ['handler1', ['id']],         # /user/1       regex=>  /user/(\d+)
        5 => ['handler2', ['name']],       # /user/tom     regex=>  /user/([^/]+)
    ];

    /** 塊正則表達式
     * @var array
     */
    protected $combined_count_regexes = [];

    /** 塊正則表達式數據
     * @var array
     */
    protected $route_data_counts = [];

    /** 基於位置調度路由
     * @param $url
     * @way 基於組位置的非分塊
     * @result 單個佔位符的狀況下提供了至關好的性能
     *          佔位符過多,在最壞的狀況下(最後一條路線匹配),性能降低到比普通方法慢兩倍以上的程度
     * @return array
     */
    public function dispatchPosition($url)
    {
        if(!preg_match($this->combined_position_regex,$url,$matches)) {
            return [self::NOT_FOUND];
        }
        //$i找到第一個非空偏移量並查找了相關數據後
        //能夠經過繼續遍歷$matches數組並將值與變量名配對來填充佔位符變量。
        for($i = 1; '' === $matches[$i]; ++$i);
        list($handler, $varNames) = $this->route_data_position[$i];
        $vars = [];
        foreach ($varNames as $varName) {
            $vars[$varName] = $matches[$i++];
        }
        return [self::FOUND, $handler, $vars];
    }

    //++++++++++++++++++++++++++++++++++++++++
    // 組號重置:
    //  PCRE regex 語法:
    //  (?| ... )是非捕獲組類型。
    //  (?:和之間的區別在於 ,(?|後者將重置其包含的每一個分支中的組號
    //++++++++++++++++++++++++++++++++++++++++

    /** 基於計數調度路由
     * @param $url
     * @return array
     */
    public function dispatchCount($url)
    {
        if(!preg_match($this->combined_count_regex,$url,$matches)) {
            return [self::NOT_FOUND];
        }
        list($handler, $varNames) = $this->route_data_count[count($matches)];
        $vars = [];
        $i = 0;
        foreach ($varNames as $varName) {
            $vars[$varName] = $matches[++$i];
        }
        return [self::FOUND, $handler, $vars];
    }

    /** 基於計數調度路由,非()佔位
     * @param $url
     * @return array
     */
    public function dispatchCount2($url)
    {
        if(!preg_match($this->combined_count_regex2,$url,$matches)) {
            return [self::NOT_FOUND];
        }
        var_dump($matches);
    }

    /** 塊正則表達式調度
     * @param $url
     * @return array
     */
    public function dispatchBlock($url)
    {
        foreach ($this->combined_count_regexes as $i => $regex) {
            if (!preg_match($regex, $url, $matches)) {
                continue;
            }

            list($handler, $varNames) = $this->route_data_counts[$i][count($matches)];

            $vars = [];
            $i = 0;
            foreach ($varNames as $varName) {
                $vars[$varName] = $matches[++$i];
            }
            return [self::FOUND, $handler, $vars];
        }
    }

    //+++++++++++++++++++++++++++++++++++++++++
    //組合的正則表達式方法對於少許的正則表達式很是有效,
    //可是若是涉及許多正則表達式則不是最佳選擇,而若是每一個規則有多個捕獲組則則是災難性的。
    //經過僅組合大約十個表達式的塊能夠提升性能。
    //這不只能夠整體上提升性能,並且能夠解決多組狀況下性能特別差的問題。
    //一旦開始使用分塊,基於組計數的替代方法就不會有太大的區別。
    //捕獲組較少時,狀況稍差一些,而許多組則稍好一些。特別是對於路由,一般每條路由涉及多個佔位符,基於組計數的方法彷佛更可取。
    //另外一方面,對於詞法分析,每一個標記一般僅使用一個捕獲組,所以基於位置的方法將獲勝。
    //+++++++++++++++++++++++++++++++++++++++++
}

$testClass = new PregRoute();
$url = '/user/tom'; #/user/1 | /user/tom/1
$dispatchPosition   = $testClass->dispatchPosition($url);
$dispatchCount      = $testClass->dispatchCount($url);
var_dump($dispatchPosition);
var_dump($dispatchCount);

`github

相關文章
相關標籤/搜索