成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Just for fun——PHP框架之簡單的路由器(2)

tomato / 3515人閱讀

改進(jìn)

緊接上一篇文章Just for fun——PHP框架之簡單的路由器(1)。
代碼下載

效率不高原因

對于以下合并的正則

~^(?:
    /user/([^/]+)/(d+)
    | /user/(d+)
    | /user/([^/]+)
)$~x

最終匹配的是分組中的某一個(gè),我們需要的子匹配也是那個(gè)分組中的,然而從結(jié)果看

preg_match($regex, "/user/nikic", $matches);
=> [
    "/user/nikic",   # 完全匹配
    "", "",          # 第一個(gè)(空)
    "",              # 第二個(gè)(空)
    "nikic",         # 第三個(gè)(被使用)
]

這里是最后一個(gè)路由被匹配了,但是其他分組的子匹配也被填充了,這是多余的。

解決思路

PCRE正則里?|也是非捕獲分組,那么?|?:有什么區(qū)別呢??
區(qū)別在于?|組號重置,看以下幾個(gè)例子就懂了

preg_match("~(?:(Sat)ur|(Sun))day~", "Saturday", $matches)
=> ["Saturday", "Sat", ""]   # 最后一個(gè)""其實(shí)是不存在的,寫在這里是為了闡釋概念

preg_match("~(?:(Sat)ur|(Sun))day~", "Sunday", $matches)
=> ["Sunday", "", "Sun"]

preg_match("~(?|(Sat)ur|(Sun))day~", "Saturday", $matches)
=> ["Saturday", "Sat"]

preg_match("~(?|(Sat)ur|(Sun))day~", "Sunday", $matches)
=> ["Sunday", "Sun"]

所有我們可以用?|來代替?:來減少多余的子匹配填充,但是這樣一來的話,如何判斷哪個(gè)分組被匹配了呢??(因?yàn)橹暗呐袛嗉记删褪Я耍?br>我們可以這樣,添加一些多余子匹配

~^(?|
    /user/([^/]+)/(d+)
  | /user/(d+)()()
  | /user/([^/]+)()()()
)$~x
實(shí)現(xiàn) dispatcher.php
 1) {
                preg_match_all("~{([a-zA-Z0-9_]+?)}~", $route, $matchesVariables);
                return [
                    preg_replace("~{[a-zA-Z0-9_]+?}~", "([a-zA-Z0-9_]+)", $route),
                    $matchesVariables[1],
                ];
            } else {
                return [
                    $route,
                    [],
                ];
            }
        }
        throw new LogicException("register route failed, pattern is illegal");
    }

    /**
     * 注冊路由
     * @param $httpMethod string | string[]
     * @param $route
     * @param $handler
     */
    public function addRoute($httpMethod, $route, $handler) {
        $routeData = $this->parse($route);
        foreach ((array) $httpMethod as $method) {
            if ($this->isStaticRoute($routeData)) {
                $this->addStaticRoute($method, $routeData, $handler);
            } else {
                $this->addVariableRoute($method, $routeData, $handler);
            }
        }
    }


    private function isStaticRoute($routeData) {
        return count($routeData[1]) === 0;
    }

    private function addStaticRoute($httpMethod, $routeData, $handler) {
        $routeStr = $routeData[0];

        if (isset($this->staticRoutes[$httpMethod][$routeStr])) {
            throw new LogicException(sprintf(
                "Cannot register two routes matching "%s" for method "%s"",
                $routeStr, $httpMethod
            ));
        }

        if (isset($this->methodToRegexToRoutesMap[$httpMethod])) {
            foreach ($this->methodToRegexToRoutesMap[$httpMethod] as $route) {
                if ($route->matches($routeStr)) {
                    throw new LogicException(sprintf(
                        "Static route "%s" is shadowed by previously defined variable route "%s" for method "%s"",
                        $routeStr, $route->regex, $httpMethod
                    ));
                }
            }
        }

        $this->staticRoutes[$httpMethod][$routeStr] = $handler;
    }


    private function addVariableRoute($httpMethod, $routeData, $handler) {
        list($regex, $variables) = $routeData;

        if (isset($this->methodToRegexToRoutesMap[$httpMethod][$regex])) {
            throw new LogicException(sprintf(
                "Cannot register two routes matching "%s" for method "%s"",
                $regex, $httpMethod
            ));
        }

        $this->methodToRegexToRoutesMap[$httpMethod][$regex] = new Route(
            $httpMethod, $handler, $regex, $variables
        );
    }


    public function get($route, $handler) {
        $this->addRoute("GET", $route, $handler);
    }

    public function post($route, $handler) {
        $this->addRoute("POST", $route, $handler);
    }

    public function put($route, $handler) {
        $this->addRoute("PUT", $route, $handler);
    }

    public function delete($route, $handler) {
        $this->addRoute("DELETE", $route, $handler);
    }

    public function patch($route, $handler) {
        $this->addRoute("PATCH", $route, $handler);
    }

    public function head($route, $handler) {
        $this->addRoute("HEAD", $route, $handler);
    }

    /**
     * 分發(fā)
     * @param $httpMethod
     * @param $uri
     */
    public function dispatch($httpMethod, $uri) {
        $staticRoutes = array_keys($this->staticRoutes[$httpMethod]);
        foreach ($staticRoutes as $staticRoute) {
            if($staticRoute === $uri) {
                return [self::FOUND, $this->staticRoutes[$httpMethod][$staticRoute], []];
            }
        }

        $routeLookup = [];
        $regexes = [];
        foreach ($this->methodToRegexToRoutesMap[$httpMethod] as $regex => $route) {
            $index = count($route->variables);
            if(array_key_exists($index, $routeLookup)) {
                $indexNear = $this->getArrNearEmptyEntry($routeLookup, $index);
                array_push($regexes, $regex . str_repeat("()", $indexNear - $index));
                $routeLookup[$indexNear] = [
                    $this->methodToRegexToRoutesMap[$httpMethod][$regex]->handler,
                    $this->methodToRegexToRoutesMap[$httpMethod][$regex]->variables,
                ];
            } else {
                $routeLookup[$index] = [
                    $this->methodToRegexToRoutesMap[$httpMethod][$regex]->handler,
                    $this->methodToRegexToRoutesMap[$httpMethod][$regex]->variables,
                ];
                array_push($regexes, $regex);
            }
        }
        $regexCombined = "~^(?|" . implode("|", $regexes) . ")$~";
        if(!preg_match($regexCombined, $uri, $matches)) {
            return [self::NOT_FOUND];
        }
        list($handler, $varNames) = $routeLookup[count($matches) - 1];
        $vars = [];
        $i = 0;
        foreach ($varNames as $varName) {
            $vars[$varName] = $matches[++$i];
        }
        return [self::FOUND, $handler, $vars];
    }

    private function getArrNearEmptyEntry(&$arr, $index) {
        while (array_key_exists(++$index, $arr));
        return $index;
    }
}

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/26125.html

相關(guān)文章

  • Just for fun——PHP框架簡單由器(1)

    摘要:路由路由的功能就是分發(fā)請求到不同的控制器,基于的原理就是正則匹配。 路由 路由的功能就是分發(fā)請求到不同的控制器,基于的原理就是正則匹配。接下來呢,我們實(shí)現(xiàn)一個(gè)簡單的路由器,實(shí)現(xiàn)的能力是 對于靜態(tài)的路由(沒占位符的),正確調(diào)用callback 對于有占位符的路由,正確調(diào)用callback時(shí)傳入占位符參數(shù),譬如對于路由:/user/{id},當(dāng)請求為/user/23時(shí),傳入?yún)?shù)$args...

    smallStone 評論0 收藏0
  • Just for fun——基于Swoole做個(gè)小框架

    摘要:使開發(fā)人員可以編寫高性能的異步并發(fā),服務(wù)。使用作為網(wǎng)絡(luò)通信框架,可以使企業(yè)研發(fā)團(tuán)隊(duì)的效率大大提升,更加專注于開發(fā)創(chuàng)新產(chǎn)品??傊@個(gè)庫讓可以常駐內(nèi)存,并提供了,等功能。 swoole 使 PHP 開發(fā)人員可以編寫高性能的異步并發(fā) TCP、UDP、Unix Socket、HTTP,WebSocket 服務(wù)。Swoole 可以廣泛應(yīng)用于互聯(lián)網(wǎng)、移動通信、企業(yè)軟件、云計(jì)算、網(wǎng)絡(luò)游戲、物聯(lián)網(wǎng)(...

    CoreDump 評論0 收藏0
  • Just for fun——基于Swoole做個(gè)小框架

    摘要:使開發(fā)人員可以編寫高性能的異步并發(fā),服務(wù)。使用作為網(wǎng)絡(luò)通信框架,可以使企業(yè)研發(fā)團(tuán)隊(duì)的效率大大提升,更加專注于開發(fā)創(chuàng)新產(chǎn)品。總之,這個(gè)庫讓可以常駐內(nèi)存,并提供了,等功能。 swoole 使 PHP 開發(fā)人員可以編寫高性能的異步并發(fā) TCP、UDP、Unix Socket、HTTP,WebSocket 服務(wù)。Swoole 可以廣泛應(yīng)用于互聯(lián)網(wǎng)、移動通信、企業(yè)軟件、云計(jì)算、網(wǎng)絡(luò)游戲、物聯(lián)網(wǎng)(...

    fevin 評論0 收藏0
  • Just for fun——PHP框架簡單模板引擎

    摘要:原理使用模板引擎的好處是數(shù)據(jù)和視圖分離。對于循環(huán)語句怎么辦呢這個(gè)的話,請看流程控制的替代語法 原理 使用模板引擎的好處是數(shù)據(jù)和視圖分離。一個(gè)簡單的PHP模板引擎原理是 extract數(shù)組($data),使key對應(yīng)的變量可以在此作用域起效 打開輸出控制緩沖(ob_start) include模板文件,include遇到html的內(nèi)容會輸出,但是因?yàn)榇蜷_了緩沖,內(nèi)容輸出到了緩沖中 ob...

    X1nFLY 評論0 收藏0
  • Just for fun——Slim借力Swoole

    摘要:的話,是一個(gè)遵循規(guī)范微型的框架,作者這樣說大致意思的核心工作分發(fā)了請求,然后調(diào)用回調(diào)函數(shù),返回一個(gè)對象。執(zhí)行的方法時(shí),我們從中取出的依賴,這時(shí)候,注冊的回調(diào)函數(shù)被調(diào)用,返回實(shí)例。 Slim Slim的話,是一個(gè)遵循PSR (PSR-7)規(guī)范微型的框架,作者這樣說: Slim is a PHP micro framework that helps you quickly write si...

    leejan97 評論0 收藏0

發(fā)表評論

0條評論

tomato

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<