PHP URLディスパッチ

WBOY
WBOYオリジナル
2016-06-23 14:34:13856ブラウズ

1、非リライトをサポートします。つまり、
http://localhost/index.php/blog/view/5456-asdf.html
も正しく解析できます。 。
-------------------------------------------------
2、追加: 絶対アドレスの生成には
rurl('myFirstRouter のみが必要です) ', array('id' => '33', 'name' => 'thename'), true);
末尾に追加の true を追加します。デフォルトは false (相対アドレス) です。
次のような絶対アドレスを生成します: ウェブサイトのルート ディレクトリ/fleaphp/test/blog/view/33-thename.html

ZendFramework の Router_Regexp クラスから変更。
それを整理するのに時間がかかりましたが、私のレベルには限界があります。専門知識のある人がそれを改善できることを願っています。

ルートの定義は DSN の定義と同じです:

return array( 'routers' =>array( 'myFirstRouter' => array( 'blog/view(?:/(d+)-(.+) ) .html', array( 'id' => '1', 'controller' => 'default', 'action' => 'index' ), array( 1 => 'id', 2 = > ; '名前' ), 'blog/view/%d-%s.html' ), 'mySecondRouter' => array( 'blog(?:/(d+)-(.+)).html', array( 'id' => '1'、'コントローラ' => 'デフォルト'、'アクション' => 'インデックス' )、array( 1 => 'id'、2 => '名前' )、 'blog/%d-%s.html' ), 'myThirdRouter' => array( '([a-z0-9]+)/([a-z0-9]+)', array(), array( 1 => 'コントローラー', 2 => 'アクション' ), 'blog/%d-%s.html' ) );

コードをコピーします これは 2 次元配列であり、それぞれの値がルーティング ルールです。
最初の項目は正規表現、2番目の項目はパラメータのデフォルト値(ここでコントローラ、アクション、その他のパラメータのデフォルト値を設定できます)です。
3番目の項目は次のとおりです:パラメータと最初のパラメータの対応関係item 正規表現内の一致する要素は相互に対応します。
4番目の項目は、リンクを生成するときに使用される形式に使用されます。理解できない場合は、ZF ルーターのセクションを読んでください。

先変更My_Dispatcher_Regexp类的代:

loadRouters();         if (! is_array($this->_routers)) は false を返します。         if (!$this->_pathInfo) $this->getPathInfo();                  foreach (array_reverse($this->_routers) as $router) { if (! is_array($router)) continue;          if ($router[0] == '' || !is_string($router[0])) 続行;          $regexp = '#^' 。 $ルーター[0]。 '$#i';    if (! isset($router[1])) $router[1] = array();          if (! isset($router[2])) $router[2] = array();          if ($args = $this->match($regexp, $this->_pathInfo, $router[1], $router[2])) { $this->_curRouter = $router;           $data['コントローラー'] = $args['コントローラー'];           $data['アクション'] = $args['アクション'];           $_GET = array_merge($_GET, $args);           壊す;          } } $this->_request = $data;     } /*** ルーティングデータ情報の読み込み * **/ functionloadRouters() { static $routerLoaded;      if ($routerLoaded) が戻る;      $routerLoaded = false;      $routerConfig = FLEA::getAppInf('routerConfig');         FLEA::loadAppInf($routerConfig);         $this->_routers = FLEA::getAppInf('routers');         $routerLoaded = true;     }    /*** * サーバー環境に応じてRequestUri情報を取得します * * * @returnunknown*/ function getRequestUri() { if ($this->_requestUri) return $this->_requestUri;         if (isset($_SERVER['HTTP_X_REWRITE_URL'])) { // IIS がキャッチするように最初にこれを確認してください $requestUri = $_SERVER['HTTP_X_REWRITE_URL'];         } elseif (isset($_SERVER['REQUEST_URI'])) { $requestUri = $_SERVER['REQUEST_URI'];         } elseif (isset($_SERVER['ORIG_PATH_INFO'])) { // IIS 5.0、CGI としての PHP $requestUri = $_SERVER['ORIG_PATH_INFO'];             if (!empty($_SERVER['QUERY_STRING'])) { $requestUri .= '?' 。 $_SERVER['QUERY_STRING'];             } } else { $requestUri = null;         } $this->_requestUri = $requestUri;         $requestUri を返します。     } function getBaseUrl() { if ($this->_baseUrl) return $this->_baseUrl;         $filename = ベース名($_SERVER['SCRIPT_FILENAME']);         if (basename($_SERVER['SCRIPT_NAME']) === $filename) { $baseUrl = $_SERVER['SCRIPT_NAME'];         elseif (basename($_SERVER['PHP_SELF']) === $filename) { $baseUrl = $_SERVER['PHP_SELF'];         elseif (isset($_SERVER['ORIG_SCRIPT_NAME']) &&basename($_SERVER['ORIG_SCRIPT_NAME']) === $filename) { $baseUrl = $_SERVER['ORIG_SCRIPT_NAME']; // 1and1 共​​有ホスティングの互換性 } else { // script_filename を遡って一致する部分を見つける // php_self $path = $_SERVER['PHP_SELF'];             $segs =explode('/', trim($_SERVER['SCRIPT_FILENAME'], '/'));             $segs = array_reverse($segs);             $index = 0;             $last = count($segs);             $baseUrl = '';             do { $seg = $segs[$index];                 $baseUrl = '/' 。 $seg . $baseUrl;                 ++$インデックス;             while (($last > $index) && (false !== ($pos = strpos($path, $baseUrl))) && (0 != $pos));         } //baseUrl には request_uri との共通点はありますか?         $requestUri = $this->getRequestUri();         if (0 === strpos($requestUri, $baseUrl)) { // 完全な $baseUrl は $this->_baseUrl = $baseUrl;             $this->_baseUrl を返す;         } if (0 === strpos($requestUri, dirname($baseUrl))) { // $baseUrl のディレクトリ部分は $baseUrl = rtrim(dirname($baseUrl), '/');             $this->_baseUrl = $baseUrl;             $this->_baseUrl を返します;         }        if (!strpos($requestUri,basename($baseUrl))) { // 一致するものはありません。空白に設定します $this->_baseUrl = '';             $this->_baseUrl を返します;         } // mod_rewrite または ISAPI_Rewrite を使用する場合は、baseUrl からスクリプト ファイル名 // を削除します。 $pos !== 0 は、PATH_INFO または QUERY_STRING の値 // if ((strlen($requestUri) >= strlen($baseUrl)) && ((false !== ($pos = strpos( $requestUri, $baseUrl))) && ($pos !== 0))) { $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));         } $baseUrl = rtrim($baseUrl, '/');         $this->_baseUrl = $baseUrl;         $this->_baseUrl を返します;         } function getPathInfo () { $baseUrl = $this->getBaseUrl();         if (null === ($requestUri = $this->getRequestUri())) { null を返します。         } // REQUEST_URI からクエリ文字列を削除します if ($pos = strpos($requestUri, '?')) { $requestUri = substr($requestUri, 0, $pos);         } if ((null !== $baseUrl) && (false === ($pathInfo = substr($requestUri, strlen($baseUrl))))) { // substr() が false を返した場合、PATH_INFO は空の文字列 $pathInfo = '';         elseif (null === $baseUrl) { $pathInfo = $requestUri;         } $this->_pathInfo = $pathInfo;         $pathInfo を返します。     } /**     * ユーザーが送信したパスを、以前に定義されたルートと照合します。      * 一致が成功した場合、デフォルトの配列を割り当てて返します。      * * @param string このルーティング マップとの照合に使用されるパス * @return array|false 割り当てられた値の配列、または不一致の場合は false      */ function match($regex, $path, $defaults, $map) { $path = トリム(urldecode($path), '/');         $res = preg_match($regex, $path, $values);         if ($res === 0) は false を返します。         foreach ($values as $i => $value) { if (!is_int($i) || $i === 0) { unset($values[$i]);             } } $values = $this->_getMappedValues($map, $values);         $defaults = $this->getMappedValues($map, $defaults, false, true);         $return = $values + $defaults;         $return を返す;     }    /**     * 数値インデックス付きの配列値を、対応する連想マップされた配列値にマップします。      * またはその逆。インデックス => で構成されるユーザー指定のマップ配列を使用します。 name * パラメータのマッピング。マップが見つからない場合は、元の配列を返します。      * * このメソッドは、ソース配列からキーの宛先タイプを取り除きます。つまり。ソース配列が数値的にインデックス付けされている場合、すべての連想キーが削除されます。逆の場合は、その逆 * が true に設定されています。      * * @param array マップする値のインデックス付きまたは連想配列 * @param boolean False は、インデックスを関連付けに変換することを意味します。 True は逆を意味します。      * @param boolean 間違ったタイプのキーを保存または削除する必要があります。      * @return array マップされた値の配列      */ function _getMappedValues($map, $values, $reversed = false, $preserve = false) { if (count($map) == 0) { return $values;         $return = array();         foreach ($values as $key => $value) { if (is_int($key) && !$reversed) { if (array_key_exists($key, $map)) { $index = $map[$key];                 } elseif (false === ($index = array_search($key, $map))) { $index = $key;                 } $return[$index] = $values[$key];             elseif ($reversed) { $index = (!is_int($key)) ? array_search($key, $map, true) : $key;                 if (false !== $index) { $return[$index] = $values[$key];                 } } elseif ($preserve) { $return[$key] = $value;             } } return $return;     } /**     * このルートによって定義された URL パスを組み立てます * * @param array パラメーターとして使用される名前 (またはインデックス) と値のペアの配列 * @return string ユーザーが送信したパラメーターを含むルート パス      */ function Assembly($defaults, $map = array(), $reverse, $data = array()) { if ($reverse === null) { return '构建网址失败!路由パラメータ错误!';            } $data = $this->_getMappedValues($map, $data, true, false);         $data += $this->getMappedValues($map, $defaults, true, false);         //$data += $this->_values;         ksort($data);         $return = @vsprintf($reverse, $data);         if ($return === false) { return '构建网址失败!'; ルーター名])) $curRouter = $this->_router[$routerName]; elseif (isset($this->_curRouter)) $curRouter = $this->_curRouter if (is_array($curRouter); count( $curRouter) == 4 && is_string($curRouter[3])) { $defaults = $curRouter[1]; $reverse = $curRouter[3]; 「URL の構築に失敗しました!」ルーティングパラメータエラー! '; } if (is_array($map) && is_string($reverse)) if (!$absolute) return $this->assemble($defaults, $map, $reverse, $urlOptions); this->_baseUrl) $this->getBaseUrl(); return $this->_baseUrl .$this->assemble($defaults, $map, $reverse, $urlOptions); }

コードをコピー カスタム クラスとファイルの配置に関するより適切な命名規則を次に示します。
FLEA の下に My ディレクトリを作成し、そこに独自のクラスを配置します。たとえば、My_Dispatcher_Regexp は次の場所に配置されます:
My/Dispatcher/Regexp.php

同時に、便宜上、生成された URL アシスタントを作成します:
My_Helper_Router
My/Helper/Router.php
コードは次のとおりです:

url( $routerName, $urlOptions, $absolute); }

コードをコピーします 使用法:
/* デフォルトの Dispatcher をカスタム Dispatcher クラスに変更します*/
FLEA::setAppInf('dispatcher','My_Dispatcher_Regexp');

/ * ルーティング構成情報のファイルの場所を設定*/
FLEA::setAppInf('routerConfig', './APP/config/router.php');

その他のコードは通常の例と同じです。

コントローラー内のコードは次のとおりです。

コードをコピー

ビューで次のコードを使用します:

'33', 'name' =>) ; 'thename') );

コードをコピーすると、$_GET が正しいパラメータを取得していることがわかります。rurl も、次の URL を生成します:
blog/view/33-thename.html

絶対 URL 生成メソッドは次のとおりです:

rurl('myFirstRouter ', array('id' => '33', 'name' => 'thename'),true); //次の URL が生成されます: /other/ fleaphp/test/blog/view/33-thename .html Apache の mod_rewrite 機能を使用しない場合、生成される URL は次のとおりです: /fleaphp/test/index.php/blog/view/33-thename.html

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
前の記事:PHP ksort() 関数次の記事:PHP ksort() 関数