如何在自定义生成的类中访问Symfony容器参数

时间:2016-04-16 00:03:22

标签: php symfony pdo model

我在DB抽象包下有一个自定义命令类,用于生成PDO :: FETCH_CLASS所需的模型对象。与Doctrine模型非常相似。我面临的问题是我需要获取PDO实例的服务,以便我可以在生成的类上重用它。有没有办法从Symfony范围注入一些东西来获取服务参数?

我运行的命令php bin/console pdo:generate:model <NameOfBundle>,将一个Base / Peer模型(类似于Propel)放在一个名为Model的目录中的bundle的根目录中。

以下是生成的DB Peer模型之一的示例:

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');
    }
}

请原谅我对Symfony结构的无知,但我完全失去了如何让我自己的课程继承所述结构的属性。

更新1

此处的每个请求是Base模型类:

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() {}
}

更新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('');
    }
}

来自MODEL_NAME的{​​{1}}常量引用对等类名称:

HflogsBase

3 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:1)

你可以尝试这样做吗?

        List<char> guessWord = new List<char>(25);
        int i = textBox1.TextLength;
        for (int j = 0; j < i; j++)
        {
            if (input == passWord[j])
            {
                guessWord.Insert(j, passWord[j]); //set j index of an array or list to the corresponding character
            }
            else
            {
                guessWord.Insert(j,' ');  // or you can use an underscore _ to indicate that there should have been a letter there.  You could also add a line here to create a list or array containing wrong guesses and display those
            }
        }
        label1.Text = ""; //clear prior guesses

        foreach(char c in guessWord)
        {
            label1.Text += c;
        }

并在您的控制器中:

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;
}

}

答案 2 :(得分: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添加额外步骤的情况下运行。