2016-03-28 8 views
0

現在のところ、既存のアプリケーションをSymfony2に移行しており、各コントローラに約8個のアクションを持つ約100個のコントローラがあります。現在のアクションはすべて、次のように指定されています:Symfonyメソッドの使い方「アクション」の単語を除外するアクション

public function index(){} 

ただし、Symfonyのデフォルトの命名規則はindexAction()です。 現在のすべてのアクションを維持し、メソッド名の後ろに "Action"という単語を付けずにSymfonyをそのまま使用することはできますか? ありがとうございます。

答えて

2

はい、可能です。ルートを通常のように定義できるはずですが、カーネルがコントローラを見つける方法を変更する必要があります。これを行う最良の方法は、 'controller_name_converter'サービスを置き換える/装飾する/拡張することです。これはプライベートサービスで、 'controller_resolver'サービスに注入されます。

置き換えたいクラスのソースコードは、 'Symfony \ Bundle \ FrameworkBundle \ Controller \ ControllerNameParser'にあります。

基本的に、このコードは次のように動作します。ルートを作成するときに指定した 'bundle:controller:action'はキャッシュに保存されます。ルートが一致すると、その文字列がカーネルに戻され、カーネルは 'controller_resolver'を呼び出して 'controller_name_resolver'を呼び出します。このクラスは、文字列を "namespace :: method"表記に変換します。

decorating servicesをご覧になり、その方法を知ってください。ここで

はあなたのようなオリジナルのサービスを

class ActionlessNameParser 
{ 
    protected $parser; 

    public function __construct(ControllerNameParser $parser) 
    { 
     $this->parser = $parser; 
    } 

    public function parse($controller) 
    { 
     if (3 === count($parts = explode(':', $controller))) { 
      list($bundle, $controller, $action) = $parts; 
      $controller = str_replace('/', '\\', $controller); 

      try { 
       // this throws an exception if there is no such bundle 
       $allBundles = $this->kernel->getBundle($bundle, false); 
      } catch (\InvalidArgumentException $e) { 
       return $this->parser->parse($controller); 
      } 

      foreach ($allBundles as $b) { 
       $try = $b->getNamespace().'\\Controller\\'.$controller.'Controller'; 
       if (class_exists($try)) { 
        // You can also try testing if the action method exists. 
        return $try.'::'.$action; 
       } 
      } 
     } 

     return $this->parser->parse($controller); 
    } 

    public function build($controller) 
    { 
     return $this->parser->build($controller); 
    } 
} 

と協力し、置き換えることができますテストされていないクラスである:

actionless_name_parser: 
    public: false 
    class: My\Namespace\ActionlessNameParser 
    decorates: controller_name_converter 
    arguments: ["@actionless_name_parser.inner"] 
+0

Twifty私はあなたのアプローチがはるかに良いと思う。しかし、symfonyは新しいクラスを使うことを知っています。どこに登録しますか? – user1960170

+0

@ user1960170、サービス定義を置き換える必要があります。答えのリンクを見てください。 symfonyがキャッシュを温めても、常に新しいクラスが使用されます。 – Twifty

+1

おかげでTwifty、あなたのソリューションは金色です.... – user1960170

0

明らかに、アクション接尾辞は、内部メソッドとルートにマップされているメソッドを区別するために使用します。 (これによればquestionによる)。

確かに知っている最善の方法は試してみることです。

// src/AppBundle/Controller/HelloController.php 
namespace AppBundle\Controller; 

use Symfony\Component\HttpFoundation\Response; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 

class HelloController 
{ 
    /** 
    * @Route("/hello/{name}", name="hello") 
    */ 
    public function indexAction($name) 
    { 
     return new Response('<html><body>Hello '.$name.'!</body></html>'); 
    } 
} 

アクションをメソッド名から削除して、何が起こるかを確認してください。

+0

この間違った方法を取ってはいけないが、私は答えの価値を疑問視され失敗することがよく知られているものを試すことを示唆している。 Symfony 2を使用していないかのようにほとんど。 – Cerad

+1

いいえ私はSymfonyを使用しましたが、ドキュメントで述べたように接尾辞アクションを使用しました。私はそれが他のポストの受け入れられた答えだったのでそれを言った。 – dooms

関連する問題