2

データベースへの挿入、更新、削除などのアクションを持つコントローラーがありますが、ほとんどすべてのアクションに次の行が含まれています。

$em = $this->getDoctrine()->getEntityManager(); 
$friend = $em->getRepository('EMMyFriendsBundle:Friend')->find($id);
$user = $this->get('security.context')->getToken()->getUser();

これは問題ありませんか、それともコードの重複ですか? というプロパティを作成し、$em次のようなコンストラクターを作成しようとしました:

public function __construct()
{
    $this->em = $this->getDoctrine()->getEntityManager();
}

しかし、うまくいきませんでした。クエリ、特に$idパラメーターを使用するクエリについては、それらを 1 か所に分割する方法さえわからないため、各アクションでそれらを使用できるようにします。1 つの方法は関数ですが、このような関数に意味はありますか? はいの場合、何を返す必要がありますか?配列?

最適な方法を教えてください!

4

4 に答える 4

3

Symfony2の場合、コードの重複を避けるためにコントローラーで行うことは、Controller.php私がよく使用する関数を配置するというクラスを作成することです。

例えば ​​:

<?php

namespace YourProject\Bundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller as BaseController;

/**
 * Base Controller for xxBundle
 */
class Controller extends BaseController
{
    /**
     * Get repository
     *
     * @param string $class class
     *
     * @return Doctrine\ORM\EntityRepository
     */
    protected function getRepository($class)
    {
        return $this->getDoctrine()->getEntityManager()->getRepository($class);
    }

    /**
     * Set flash
     *
     * @param string $type type
     * @param string $text text
     */
    protected function setFlash($type, $text)
    {
        $this->get('session')->getFlashBag()->add($type, $text);
    }

    /**
     * Returns the pager
     *
     * @param integer        $page    Page
     * @param integer        $perPage Max per page
     * @param Doctrine_Query $query   Query
     *
     * @return \Pagination
     */
    public function getPager($page = 1, $perPage = 10, $query = null)
    {
        $paginator = $this->get('knp_paginator');

        $pagination = $paginator->paginate(
            $query,
            $this->get('request')->query->get('page', 1),
            $perPage
        );

        return $pagination;
    }

このコントローラーを作成したら、アプリコントローラーを作成したコントローラーにする必要がありますextends

そうすれば、一般的な方法のコードとエイリアスの重複を避けることができます。

于 2012-09-13T11:03:30.427 に答える
1

おそらくあなたが探しているのは、アクションパラメーターをオブジェクトに直接マップするパラメーターコンバーターです。

説明といくつかの例を次に示します。

http://symfony.com/doc/2.0/bundles/SensioFrameworkExtraBundle/annotations/converters.html

編集:

興味深い記事の詳細情報:

http://www.adayinthelifeof.nl/2012/08/04/multiparamconverter-for-symfony2/

于 2012-09-13T10:53:58.690 に答える
1

できるよ:

private $em;
private $friend;
private $user;

private function init($id==null) {
    $this->em = $this->getDoctrine()->getEntityManager(); 
    $this->friend = $id?$this->em->getRepository('EMMyFriendsBundle:Friend')->find($id):null;
    $this->user = $this->get('security.context')->getToken()->getUser();
}

次に、アクションを呼び出すことができます

$this->init($id);

また

$this->init();

そして、あなたは持っているでしょう

$this->em;
$this->friend;
$this->user;

利用可能。一部のアクションでは $id パラメーターが設定されていないと推測されるため、$id パラメーターを設定しないことを許可したことに注意してください。

この init 関数を別のコントローラーで使用できるようにする場合は、別の回答で提案されているように、ベース コントローラーを作成し、そこから拡張します。

于 2012-09-13T11:01:09.653 に答える
1

そのコードがいくつかのコントローラーにしかない場合は、そのコードを両方の保護されたメソッドにラップできます。

アプリケーションのより多くの部分でそのコードを再利用できると思われる場合は、バリデーターを作成する必要があるかどうか、サービスまたは別の種類の設計を使用する必要があるかどうかを検討する必要があります。

于 2012-09-13T11:01:22.383 に答える