2

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

$duration=24; //in hours

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

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

4

1 回答 1

1

您可能想看看使用表达式值

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

$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


评论后编辑

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

嗯...有趣的问题,所以我又挖了一点,然后去了 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)

考虑到日期和时间,这似乎奏效了——万岁!

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

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)

还有……耶!


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

现在由您决定是否可以将其集成到您的模型类中...玩得开心;-)

如果有一天你找到了一种方法,可以在查询的其他部分使用这样的表达式,或者以更简洁的方式使用,如果你能发表评论让我知道,我将不胜感激;-)


而且,这次,我真诚地希望我找到了方法^^

于 2009-08-04T18:41:44.250 回答