2014-09-06 27 views
12

如果當你說以下控制器結構Yii2佈線使用首字母大寫的動作名

<?php 
namespace app\controllers; 

use Yii; 
use yii\web\Controller; 
/** 
* Test controller 
*/ 
class TestController extends Controller 
{ 
    public function actionMyaction(){ 
     ... 
     //action logic 
    } 

    public function actionMyAction(){ 
     ... 
     //action logic 
    } 
} 

第一條路線可以使用路徑example.com/test/myaction

每Yii的1.x的邏輯第二條路線應該是訪問從Yii2.x路由路徑example.com/test/myAction 訪問使用連字符連接的結構,只能從example.com/test/my-action

訪問反正是有使使用駝峯路由Yii2中的結構最好不用路由類進行擴展?

這很重要,因爲它打破了所有鏈接(當然這些鏈接都是通過互聯網)向後兼容,因此Yii1.x應用程序永遠不會遷移到Yii2.x,即使代碼被完全重寫。這個改變的原因是什麼?

回答

13

我也對這個改變略有介紹,但最終我發現它使URL更易於閱讀。我不確定在Yii1中有沒有區分大小寫的路線,Yii2中我沒有這個問題(或者是問題的印象)。

我不確定確切的原因,但我可以告訴你,對於搜索引擎優化,最好是 - 分開單詞而不是有一個大字。

當我在yii2中重寫了一個應用程序時,我在url管理器中放入了所有我需要維護的舊路由。

 'urlManager' => [ 
      'class' => 'yii\web\UrlManager', 
      'enablePrettyUrl' => true, 
      'showScriptName' => false, 
      'rules' => [ 
................................................. 
       'site/registerInterest' => 'site/register-interest', 
................................................. 

      ], 
     ], 

所以我的舊鏈接現在工作得很好。你也可以在.htaccess中添加301重定向,如果你想從舊路由到新路由來保留SEO汁。

+1

感謝Mikhai,SEO是有道理的有數以百計的行動在舊的項目,手動重新每單一的似乎cubersome基於正則表達式的解決方案也許是可能的? – Manquer 2014-09-15 15:04:01

+0

你可能會寫1自定義URL管理器http://www.yiiframework.com/doc-2.0/guide-runtime-url-handling.html#creating-your-own-rule-classes,可以統治他們都:)。由於我的項目很容易處理,我個人沒有寫出一個,公衆部分不是那麼大,管理員我不關心搜索引擎優化。 – 2014-09-16 02:27:09

3

你可以讓你自己Basecontroller並覆蓋createAction 帶有圖案允許大寫像

preg_match('/^[a-zA-Z0-9\\-_]

public function createAction($id) 
{ 
    if ($id === '') { 
     $id = $this->defaultAction; 
    } 

    $actionMap = $this->actions(); 
    if (isset($actionMap[$id])) { 
     return Yii::createObject($actionMap[$id], [$id, $this]); 
    } elseif (preg_match('/^[a-zA-Z0-9\\-_]+$/', $id) && strpos($id, '--') === false && trim($id, '-') === $id) { 
     $methodName = 'action' . str_replace(' ', '', ucwords(implode(' ', explode('-', $id)))); 
     if (method_exists($this, $methodName)) { 
      $method = new \ReflectionMethod($this, $methodName); 
      if ($method->isPublic() && $method->getName() === $methodName) { 
       return new InlineAction($id, $this, $methodName); 
      } 
     } 
    } 

    return null; 
}