2014年7月13日 星期日

yii2 URL %2F and /

安裝 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,找到發生的原因,因為是程式在執行。

沒有留言:

張貼留言