【问题标题】:How to fill a Symfony choice widget dynamically with the result of a DB query如何用数据库查询的结果动态填充 Symfony 选择小部件
【发布时间】:2012-06-28 14:50:36
【问题描述】:

在我的一个表单中,我希望有一个下拉菜单 (sfWidgetFormChoice),其中选项是通过对数据库执行查询来动态生成的。

为了更准确一点,我将列出我在表格中拥有的所有版本。查询看起来像这样:

select distinct version from mytable order by version desc

到目前为止我有什么但不起作用:

class myForm extends sfForm

$query = "select distinct version from mytable order by version desc";

$versions = Doctrine_Manager::getInstance()->getCurrentConnection()->fetchAssoc($query);

public function configure()

$this->setWidgets(array('version' => new sfWidgetFormChoice(array('choices' => self::$versions))));

编辑:

谢谢大家的回答!非常感谢!

无论如何,您的解决方案都基于拥有桌子的模型。我宁愿直接使用 PDO,因为它更快。

Symfony Documentation 中,我在“使用原始 SQL 查询”下找到了我要查找的内容。

所以我扩展了我的表单以结束:

class myForm extends sfForm
{
  public function getVersions()
  {
    $connection = Doctrine_Manager::connection();
    $query      = "select distinct version from mytable order by version desc";
    $statement  = $connection->prepare($query);
    $statement->execute();
    $resultset = $statement->fetchAll(PDO::FETCH_COLUMN, 0);

    return $resultset;
  }

  public function configure()
  {
    $this->setWidgets(array('version' => new sfWidgetFormChoice(array('choices' => self::getVersions()))));
  }
}

因此,我的下拉列表会正确填充我的表格中的内容,耶!但我也收到警告:

警告:在第 196 行的 lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/database/sfDoctrineConnectionProfiler.class.php 中为 foreach() 提供的参数无效

警告:join() [function.join]:第 141 行的 lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/database/sfDoctrineConnectionProfiler.class.php 中传递的参数无效

警告:在第 196 行的 lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/database/sfDoctrineConnectionProfiler.class.php 中为 foreach() 提供的参数无效

警告:在第 117 行的 lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/debug/sfDoctrineConnectionProfiler.class.php 中为 foreach() 提供的参数无效

知道我在这里做错了什么吗???奇怪的是,下拉菜单看起来不错。

【问题讨论】:

    标签: drop-down-menu symfony1 symfony-1.4


    【解决方案1】:

    像这样使用sfWidgetFormDoctrineChoicetable_method 选项:

    在你的表单类中这样做:

    $this->setWidgets(array('version' => new sfWidgetDoctrineChoice(array('model' => 'Version', 'table_method' => 'getData')));
    

    然后在versionTable.class.php 文件中创建一个返回对象集合的getData()(你可以调用任何东西)函数:

    public function getData() {
        $this->getInstance()->createQuery()
              ->orderBy('version desc')
              ->execute();
    }
    

    【讨论】:

    • 您需要从 .. 'table_method' => 'getData()' 中删除 "()"。它必须是'table_method' => 'getData'
    【解决方案2】:

    您可以使用 sfWidgetFormDoctrineChoice

    public function configure(){
    
    $this->widgetSchema['version'] = new sfWidgetFormDoctrineChoice(array('model' => 'YourModel', 'query' => Doctrine::getTable('YurModel')->getYourDataQuery(), 'add_empty' => true));
    
    }
    

    在你的 modelTable.class.php

     public function getYourDataQuery()
        {
              //Your query
    
                $q = $this->createQuery('a');         
    
            return $q;
         }
    

    【讨论】:

      【解决方案3】:

      我终于找到了我自己正在寻找的解决方案。这现在直接访问数据库。我不再使用 FETCH_COLUMN 的原因是,这将创建一个数组,其中键是从 0 开始的 Id,值是查询本身返回的值。相反,我想让键和值成为查询提供的任何内容。这就是为什么查询现在提供两个相同的列,然后 FETCH_KEY_PAIR 完成其余的工作。

      如果其他人对我如何解决这个问题感兴趣,这是我的代码,它可以正确填写下拉列表并且不会导致错误。

      class myForm extends sfForm
      {
        public function getVersions()
        {
          $connection = Doctrine_Manager::getInstance()->getCurrentConnection()->getDBh();
          $query      = "select distinct version as key, version as value from mytable order by version desc";
          $statement  = $connection->prepare($query);
          $statement->execute();
          $resultset = $statement->fetchAll(PDO::FETCH_KEY_PAIR);
      
          return $resultset;
        }
      
        public function configure()
        {
          $this->setWidgets(array('version' => new sfWidgetFormChoice(array('choices' => self::getVersions()))));
        }
      }
      

      【讨论】:

      • 这是对表单和小部件的非常糟糕的使用,它根本不是 MVC。 sfWidgetFormDoctrineChoice 带有自定义查询绝对是要走的路。
      【解决方案4】:

      谢谢您,先生,我非常感谢您的解决方案。 你拯救了我的一天!

      以防万一遇到类似问题的人。 我在使用该解决方案时遇到了 PDO not found 问题。 (FatalErrorException: 错误: Class '.......\Controller\PDO' not found in) 原因是: https://groups.google.com/forum/#!topic/symfony2/mR22XXKPQrk “您在滥用 PHP 命名空间。当您在命名空间代码中时, 使用 PDO 表示相对于当前命名空间的类名。你有 解决问题的 2 个解决方案:使用完全限定的类名,例如 \PDO 或添加 use 语句来导入当前命名空间中的类。”

      所以在PDO::前面加上'\'后,解决方案就完美了。

      谢谢!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-12
        • 2021-04-26
        • 2015-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多