如何通过Doctrine将文字参数发送到数据库?

时间:2009-08-04 18:26:33

标签: php doctrine

如果我想做这样的事情(请注意过期行):

$duration=24; //in hours

$reset=new PasswordReset();
$reset->code=md5(uniqid());
$reset->expires="now() + interval $duration hours";
$reset->User=$user;
$reset->save();

如何让Doctrine在发送到postgresql之前不引用它?我知道我可以用PHP做到这一点,但我想知道以备将来参考。

1 个答案:

答案 0 :(得分:1)

您可能需要查看Using Expression Values

给定的示例如下所示(引用文档)

$user = new User();
$user->username = 'jwage';
$user->updated_at = new Doctrine_Expression('NOW()');
$user->save();

并生成此SQL查询:

INSERT INTO user (username, updated_at_) VALUES ('jwage', NOW())

我假设它会这样做,在你的情况下?
(我这里没有启用Doctrine的项目,因此无法为您测试)


作为旁注:我没有要测试的PostGreSQL服务器;但你提出的建议并不适用于MySQL:你似乎必须使用“now() + interval 2 hour”,而不是“now() + interval 2 hours” - 仍然,我不知道PG < / p>


在评论后编辑

呃,你是对的,这不是一个正确的解决方案;它不起作用: - (

嗯......有趣的问题,所以我挖了一点,然后去了Doctrine的源代码;我想我可能找到了一些有趣的东西。

如果您查看Doctrine_Query_Where::parseValue来源的来源,您会注意到这部分代码:

// If custom sql for custom subquery
// You can specify SQL: followed by any valid sql expression
// FROM User u WHERE u.id = SQL:(select id from user where id = 1)
} elseif (substr($trimmed, 0, 4) == 'SQL:') {
    $rightExpr = '(' . substr($trimmed, 4) . ')';
// simple in expression found

我绝对没有尝试过,但这可能很有趣......

也许你可以这样做:

$reset->expires="SQL:(now() + interval $duration hours)";

如果你这样做,我很想知道它是否有效!
可能会有用,有朝一日; - )

顺便说一下,它似乎也用在Doctrine_Search中;看着这个,也许没有圆括号就可以了,就像这样:

$reset->expires="SQL:now() + interval $duration hours";

嗯...我希望,这一次,它有所帮助...因为我没有看到很多其他方式来做你想要的事情(谷歌也没有帮助我^^ )


在第二次(第三次,如果计算我的)评论后编辑。
我会让这个工作......否则我将无法入睡^^

好吧,我可能找到了一种方式(而且,这一次,我测试了它^^);并不像人们想的那么好,但是,无论如何,它似乎都在起作用......

假设我有一个以这种方式创建的表:

CREATE TABLE  `test1`.`test` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(32) NOT NULL,
  `value` varchar(128) NOT NULL,
  `date_field` datetime NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

相应的模型类如下所示:
可能不完美:这是我为别的东西写的一个测试班,我已经变异以适应这一个^^

class Test extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->setTableName('test');
        $this->hasColumn('id', 'integer', 4, array(
             'type' => 'integer',
             'length' => 4,
             'unsigned' => 0,
             'primary' => true,
             'autoincrement' => true,
             ));
        $this->hasColumn('name', 'string', 32, array(
             'type' => 'string',
             'length' => 32,
             'fixed' => false,
             'notnull' => true,
             ));
        $this->hasColumn('value', 'string', 128, array(
             'type' => 'string',
             'length' => 128,
             'fixed' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             ));
        $this->hasColumn('date_field', 'integer', 4, array(
             'type' => 'timestamp',
             'notnull' => true,
             ));
    }
}

我会在此表中插入两行:

$test = new Test();
$test->name = 'Test 1';
$test->value = 'My Value 1';
$test->date_field = "2009-01-30 08:30:00";
$test->save();

$test = new Test();
$test->name = 'Test 2';
$test->value = 'My Value 2';
$test->date_field = "2009-02-05 08:30:00";
$test->save();

从SQL中获取此数据:
顺便说一句:我没有pg服务器,所以我会用MySQL测试一切 - 也应该在pg上工作,还是......

mysql> select * from test;
+----+--------+------------+---------------------+
| id | name   | value      | date_field          |
+----+--------+------------+---------------------+
|  1 | Test 1 | My Value 1 | 2009-01-30 08:30:00 |
|  2 | Test 2 | My Value 2 | 2009-02-05 08:30:00 |
+----+--------+------------+---------------------+
2 rows in set (0.00 sec)

所以,两行,过去很久以前的日期。


现在,可以肯定的是,我们只需获取第1行:

$testBefore = Doctrine::getTable('Test')->find(1);
var_dump($testBefore->toArray());

我得到了这种输出:

array
  'id' => string '1' (length=1)
  'name' => string 'Test 1' (length=6)
  'value' => string 'My Value 1' (length=10)
  'date_field' => string '2009-01-30 08:30:00' (length=19)


而且,现在,有趣的部分:让我们使用您提供的表达式来更新该行,以设置date_field值:

$query = new Doctrine_Query();

$query->update('test')
    ->set('date_field', 'NOW() - interval 2 hour')
    ->where('id = ?', 1)
    ->execute();

var_dump($query->getSql());

我得到的SQL就是这个:

string 'UPDATE test SET date_field = NOW() - interval 2 hour WHERE id = ?' (length=65)

如果我没有弄错的话,哪种看起来像你想要的那样; - )


而且,只是为了确定,让我们再次获取我们的一行:

$testAfter = Doctrine::getTable('Test')->find(1);
var_dump($testAfter->toArray());

我得到了这个结果:

array
  'id' => string '1' (length=1)
  'name' => string 'Test 1' (length=6)
  'value' => string 'My Value 1' (length=10)
  'date_field' => string '2009-08-04 21:26:30' (length=19)

考虑到日期和时间,这看起来很有效 - hoorray!

而且,可以肯定的是,让我们直接从数据库中查询数据:

mysql> select * from test;
+----+--------+------------+---------------------+
| id | name   | value      | date_field          |
+----+--------+------------+---------------------+
|  1 | Test 1 | My Value 1 | 2009-08-04 21:26:30 |
|  2 | Test 2 | My Value 2 | 2009-02-05 08:30:00 |
+----+--------+------------+---------------------+
2 rows in set (0.00 sec)

而且...... Yeeeepe!


嗯,现在,不太好的部分:为了能够使用该语法,我必须“手动”创建查询,使用set()方法,而不是与模型类“很好”地做和save()方法: - (

现在由你来看你可以融入你的模特课......玩得开心; - )

如果你找到一种方法,有一天,在查询的其他部分使用这样的表达式,或者做一个更清洁的方式,我真的很感激你是否可以发表评论让我知道<强>; - )


而且,这个,时间,我真诚地希望我找到了^^

的方式