web-dev-qa-db-ja.com

CamelCaseアクション名を使用する場合の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ロジックごとの2番目のルートは、Yii2.xルーティングのパスexample.com/test/myActionからアクセスできる必要があります。ハイフン構造を使用しており、example.com/test/my-actionからのみアクセスできます。

とにかく、Yii2のキャメルケース構造を使用してルーティングを有効にする方法はありますか?できればルーティングクラスで拡張する必要はありませんか?

これは、すべてのリンク(もちろんインターネット全体)の下位互換性を損なうため重要です。したがって、コードが完全に書き直されたとしても、Yii1.xアプリをYii2.xに移行することはできません。この変更の理由は何でしたか?

13
Manquer

私もこの変更について少し投げられましたが、最終的にはURLが読みやすくなることがわかりました。 Yii1で大文字と小文字を区別するルートがあるかどうかはわかりませんでしたが、Yii2ではこの問題(または問題の印象)はもうありません。

正確な理由はわかりませんが、SEOの場合は、大きな単語を1つ持つのではなく、単語を区切る方がよいと言えます。

Yii2でアプリケーションを書き直したとき、維持する必要のあるすべての古いルートをURLマネージャーに配置しました。

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

            ],
        ],

だから私の古いリンクは今はうまく機能します。古いルートから新しいルートにSEOジュースを保持したい場合は、.htaccessに301リダイレクトを配置することもできます。

13
Mihai P.

独自のベースコントローラーを作成し、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;
}
3
Jörg Peters