2016-04-16 5 views
0

私はPDO :: FETCH_CLASSに必要なモデルオブジェクトを生成するために使用しているDB抽象バンドルの下にカスタムコマンドクラスを持っています。 Doctrineモデルとよく似ています。私が直面している問題は、生成されたクラスで再利用できるように、PDOインスタンスのサービスを取得する必要があることです。 symfonyのスコープから何かを注入してサービスパラメータを取得する方法はありますか?カスタム生成クラスのsymfonyコンテナパラメータにアクセスする方法

私はコマンドphp bin/console pdo:generate:model <NameOfBundle>を実行して、モデルと呼ばれるディレクトリ内のバンドルのルートにBase/Peerモデル(Propelに似ています)を置きます。

以下

生成されたDBピアモデルの一つの例です:symfonyの構造の自分の無知を許し、

namespace Ode\AppBundle\Model; 

use Ode\AppBundle\Model\HflogsBase; 
use Symfony\Component\DependencyInjection\ContainerAwareInterface; 
use Symfony\Component\DependencyInjection\ContainerInterface; 

class Hflogs extends HflogsBase implements \JsonSerializable, ContainerAwareInterface { 
    private $container; 

    public function __construct() { 
     parent::__construct(); 
    } 

    public function setContainer(ContainerInterface $container = null) { 
     $this->container = $container; 
    } 

    public function frequency() { 
     return number_format($this->frequency, 2, '.', ''); 
    } 

    /** 
    * @todo Run another query on the database to acquire a relational element 
    */ 

    public function getPdoInstance() { 
     $pdo = $this->container->get('ode_pdo.db'); 
    } 
} 

してください、私が言ったを継承するために自分自身のクラスを取得する方法についての完全な損失で午前構造のプロパティ。要求ごと

UPDATE 1

ここではベースモデルクラスです:

namespace Ode\AppBundle\Model; 

class HflogsBase { 
    const TABLE_NAME = 'hflogs'; 
    const MODEL_NAME = 'Ode\AppBundle\Model\Hflogs'; 

    public $id; 
    public $frequency; 
    public $mode; 
    public $description; 
    public $time_on; 
    public $time_off; 
    public $lat; 
    public $lng; 
    public $user_id; 
    public $submitted; 

    const COLUMNS = 'a.id,a.frequency,a.mode,a.description,a.time_on,a.time_off,a.lat,a.lng,a.user_id,a.submitted'; 

    public function __construct() {} 
} 

UPDATE 2

の代わりに別のユーザー以下のコメントを爆破は私がインスタンス化方法を尋ねましたピアモデルクラス。私は基本的に\ PDO:FETCH_CLASSのPDOのクラスタイプとしてコントローラでそれを使用します。 PDOでは、オブジェクトのインスタンス化が行われ、問合せのすべての行の値が移入されるため、DBからの結果を強く型付けします(疎結合の標準クラスまたは連想配列の結果をデバッグするのに必要な時間が短縮されます)。

したがって、たとえば、ここで私は、コントローラに何をすべきかのインスタンスである:

class DefaultController extends Controller 
{ 

    /** 
    * @Route("/test", name="testpage") 
    */ 
    public function testAction() { 
     $logs = $this->get('ode_pdo.db')->query(" 
      SELECT " . HflogsBase::COLUMNS . " 
      FROM " . HflogsBase::TABLE_NAME . " AS a 
      WHERE a.id NOT IN (
       SELECT id 
       FROM " . HflogMetaBase::TABLE_NAME . " 
       WHERE meta_key != 'is_inactive' 
       AND meta_value = 1 
      ) 
     ")->fetchAll(\PDO::FETCH_CLASS, HflogsBase::MODEL_NAME); 


     return new Response(''); 
    } 
} 

HflogsBaseからMODEL_NAME定数は、ピアクラス名を参照:あなたがしている場合

const MODEL_NAME = 'Ode\AppBundle\Model\Hflogs'; 
+0

私たちはHflogsBaseのソースをご覧くださいできますか? –

+0

@OlivierHenry最新の記事を見る! – cj5

+1

私は、HfLogBaseでcontainerAwareを拡張してcontainerAwareInterfaceを実装する必要があると思います。 Controllerクラスとその親を見ることができます。 –

答えて

1

コンテナを使用してode_pdoサービスを取得するだけです。あなたのクラスをサービスにすることでそれを渡すのはなぜですか?

services.yml:あなたのクラスで

app.hflogs: 
    class: Ode\AppBundle\Model\Hflogs 
    arguments: ["@ode_pdo.db"] 

そして:

public function __construct($pdo) { 
    parent::__construct(); 
    $this->pdo = $pdo; 
} 
+0

これは、生成されたすべてのクラスでこれを行うと言っていますか?私のコンソールコマンドは、これらのクラスをデータベーステーブルから生成しました。このプロジェクトでは、 'Hflogs'以外に67のテーブルがあります。 – cj5

+1

これらのモデルオブジェクトを生成するカスタムコマンドクラスを更新しますか?または、ベースクラスでこれを行うと、拡張するとそのクラスにアクセスできますか? – siguy85

+0

これは良い解決策ですが、Yamlの手動設定からクラスの生成を切り離すことを望んでいました。モデルクラスの初期作成時にジェネレータコマンドが何かをサービスコンフィグレーションに書き込めるかどうかを確認します。 – cj5

1

あなたはそれをしようとすることができますか?

namespace Ode\AppBundle\Model; 

use Ode\AppBundle\Model\HflogsBase; 


class Hflogs extends HflogsBase { 


/** 
* 
* @var \PDO 
*/ 
private $pdo; 


public function __construct(Array $ctor_args) { 
    parent::__construct(); 
    if(count($ctor_args)){ 
     $this->pdo = $ctor_args[0]; 
    } 

} 

public function frequency() { 
    return number_format($this->frequency, 2, '.', ''); 
} 

/** 
* @todo Run another query on the database to acquire a relational element 
*/ 

public function getPdoInstance() { 
    return $this->pdo; 
} 

} 

とあなたのコントローラで

$logs = $this->get('ode_pdo.db')->query(" 
     SELECT " . HflogsBase::COLUMNS . " 
     FROM " . HflogsBase::TABLE_NAME . " AS a 
     WHERE a.id NOT IN (
      SELECT id 
      FROM " . HflogMetaBase::TABLE_NAME . " 
      WHERE meta_key != 'is_inactive' 
      AND meta_value = 1 
     ) 
    ")->fetchAll(\PDO::FETCH_CLASS, HflogsBase::MODEL_NAME, array($this->get('ode_pdo.db'))); 
+0

この提案をありがとう。私はそれを考慮しましたが、コードベースのすべてのクエリにそれらのパラメータを追加することは、私のワークフローにとっては繰り返しすぎて面倒です。私は本当にあなたの助けに感謝します。^1 – cj5

1

おかげで、助けたが、壁に頭を叩いてから数日後、私は解決策を考え出したことすべてに。

ベースモデルクラスでは、保護されたプロパティ$pdoを追加しました。そのクラスの構成では、PDOServiceクラスの静的メソッドを使用してクラスを開始します。

namespace Ode\PDOBundle\Services; 

class PDOService extends \PDO 
{ 
    private static $instance = null; 

    public function __construct($host, $dbname, $user, $passwd) 
    { 
     parent::__construct(
      'mysql:host=' . $host . ';dbname=' . $dbname, 
      $user, 
      $passwd 
     ); 

     self::$instance = $this; 
    } 

    public static function getInstance() { 
     return self::$instance; 
    } 
} 

コンソールコマンドジェネレータは、次のようになりますベースモデルクラスを生成します。

namespace Ode\AppBundle\Model; 

use Ode\PDOBundle\Services\PDOService; 

class HflogsBase { 
    protected $pdo; 

    const TABLE_NAME = 'hflogs'; 
    const MODEL_NAME = 'Ode\AppBundle\Model\Hflogs'; 

    public $id; 
    public $frequency; 
    public $mode; 
    public $description; 
    public $time_on; 
    public $time_off; 
    public $lat; 
    public $lng; 
    public $user_id; 
    public $submitted; 

    const COLUMNS = 'a.id,a.frequency,a.mode,a.description,a.time_on,a.time_off,a.lat,a.lng,a.user_id,a.submitted'; 

    public function __construct() { 
     $this->pdo = PDOService::getInstance(); 
    } 
} 

それは私が求めていた正確に解決策はありませんが、少なくとも、それが余分なステップを追加することなく動作しますDBAL。

関連する問題