安裝 yii2 時,
若 --stability 設成 dev,產生的 project 在 URL,/ 會被換成 %2F
若
--stability 設成 beta,產生的 project 在 URL,/ 可以正常顯示
(安裝過程 from
安裝 composer : https://getcomposer.org/doc/00-intro.md#installation-nix
產生 project : https://github.com/yiisoft/yii2/tree/master/apps/basic )
step1 安裝 composer.phar:
curl -sS https://getcomposer.org/installer | php
step2 產生 project:
當 --stability=dev
php composer.phar create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic basic
當 --stability=beta
php composer.phar create-project --prefer-dist --stability=beta yiisoft/yii2-app-basic basic
如果已經安裝了,且 stability 為 dev,可以到 composer.json 做調整:
把 composer.json 裡的 "minimum-stability" : "dev" 改成 "minimum-stability" : "beta"
修改完後,執行:php composer.phar update --prefer-dist
它會把 dev-master 相關檔案移除,並安裝 beta 相關檔案
安裝完後,即變成 beta=> %2F -> /
原因:
trace code from dev :
安裝完 yii2 後,進入產生的 project,點擊最上面 bar 的 items
進到頁面後,會發現 URL 的 / (slash) 變成 %2F
打開 views/layouts/main.php,發現上面的 bar 是用 Nav 做的
接下來要去找 Nav 的 source code (如果不知道放在哪裡,可以用 locate Nav 找)
打開 vendor/yiisoft/yii2-bootstrap/Nav.php,找到 function renderItem,
最下面 return Html::tag('li', Html::a($label, $url, $linkOptions) . $items,
$options);
這邊會產生 <a href="..."></a> 的 Html tag
從這邊可以得知,用 yii2 安裝時,提供的 Html 裡的 function a
(可以用 locate Html 找跟 Html 相關的檔案,在一個一個去檢查看是不是)
打開 vendor/yiisoft/yii2/helpers/BaseHtml.php,找 function a,
會呼叫 Url::to($url) 把 URL 產生出來。
接下來要去找 Url 裡面的 function to,
打開 vendor/yiisoft/yii2/helpers/BaseUrl.php,
用 Url 的 toRoute 處理 URL
找到 function toRoute,
用 return Yii::$app->getUrlManager()->createUrl($route); 把產生的網址回傳
打開 vendor/yiisoft/yii2/web/UrlManager.php,
找到 function createUrl,在 else 的部分,$url 在這邊產生好
處理 URL 時,會進到判斷式的 else,
從上圖的 $url = "$baseUrl?{$this->routeParam}=" . urlencode($route);
可以看到 urlencode,會把非大、小寫的英文字母、
-、_、. 以外的字元轉換成 Html code,
(可以參考:http://php.net/manual/en/function.urlencode.php)
這裡是 / (slash) 變成 %2F 的原因。
如果把 urlencode 刪掉,/ (slash) 可以正常顯示 (下圖)
trace beta 的 code 後,
打開 vendor/yiisoft/yii2/web/UrlManager.php,
找到 function createUrl,在 else 的部分,
發現 $url = "$baseUrl?{$this->routeParam}=$route";
$route 沒有用 urlencode,所以 URL 的 / (slash) 不會有 %2F。
結論:
版本不同,程式碼不同,所以 dev 版會有 / (slash) 變成 %2F 的問題,而 beta 版不會。
trace code 感想:
當發現有奇怪的東西產生時,一步一步 trace code,找到發生的原因,因為是程式在執行。