2015-05-07 96 views
2

我在http://doctrine-dbal.readthedocs.org/en/latest/reference/data-retrieval-and-manipulation.html#insertMySQL NOW()在Doctrine DBAL插入?

盯着我很想能夠做到像

$db->insert('mytable', [ 
    'foo' => 'bar', 
    'created_on' => new MagicThatMakesNowWork() 
]); 

這是不可能的?我見過的最好的解決方案是使用PHP在設置時區時獲取日期時間,這並不理想。出於某種原因,似乎只有ORM或查詢構建器才能處理表達式。我知道在Zend中,我可以做類似new Zend_Db_Expr('NOW()')的東西,它知道對象類型不會在構建的查詢中引用NOW()。不需要查詢構建器或ORM。

不確定是否不可能或沒有記錄得很好。 Doctrine DBAL: Updating timestamp field with 'NOW()' value上的第二個答案在類型數組中顯示了一個隨機字符串datetime,這看起來很奇怪/不好。

+0

如果你把'CURRENT_TIMESTAMP()'放在那裏呢? – zerkms

+0

你應該嘗試Doctrine TimeStampable ... https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/timestampable.md – Jean

+0

@zerkms我也嘗試過也沒有運氣。我看到有幾個地方認爲這會起作用。 –

回答

0

insert是沒有太多的選項。因此,Expression mysql NOW() in Doctrine QueryBuilder的答案顯示了手動知道該變量的內容。

這需要最近發佈的DBAL> = 2.5。 2014年你會不走運。請注意,datetime是一個有效的字符串,但似乎沒有常數http://php.net/manual/en/pdo.constants.php

public function insert($params) { 

    if (!isset($params[static::CREATED_ON])) { 
    $params[] = [static::CREATED_ON, new \Datetime('now'), 'datetime']; 
    } 

    if (!isset($params[static::MODIFIED_ON])) { 
    $params[] = [static::MODIFIED_ON, new \Datetime('now'), 'datetime']; 
    } 

    $conn = $this->_dbs['write']; 
    $query_builder = $conn->createQueryBuilder(); 

    $query_builder->insert(static::TABLE); 

    foreach ($params as $location => $data) { 

    $field = $data[0]; 
    $value = $data[1]; 
    $type = (isset($data[2])) ? $data[2] : \PDO::PARAM_STR; 
    $prep = (isset($data[3])) ? $data[3] : '?'; 

    $query_builder 
     ->setValue($field, $prep) 
     ->setParameter($location, $value, $type); 

    } 

    $return = $query_builder->execute(); 

    if (!$return) { 
    throw new \Exception("Failed to execute statement"); 
    } 

    return $conn->lastInsertId(); 

} 

public function update($params, $where) { 

    $conn = $this->_dbs['write']; 
    $query_builder = $conn->createQueryBuilder(); 

    $query_builder->update(static::TABLE); 

    foreach ($params as $location => $data) { 
    // can do arbitrary expressions via ['field', null, null, 'ANY EXPRESSION YOU WANT'] 
    // ie ['votes', null, null,'votes=votes+25'] 
    // or ['votes', '1', \PDO::PARAM_INT, 'votes + ?'] 
    $field = $data[0]; 
    $value = $data[1]; 
    $type = (isset($data[2])) ? $data[2] : \PDO::PARAM_STR; 
    $prep = (isset($data[3])) ? $data[3] : '?'; 

    $query_builder 
     ->set($field, $prep) 
     ->setParameter($location, $value, $type); 

    } 

    $query_builder->where($where); 

    return $query_builder->execute(); 

} 
1

看來你要完成什麼TIMESTAMP列類型自動完成。這樣做的時間比2014年長。使用它,並停止嘗試手動管理您的created_onupdated_on字段。 https://dev.mysql.com/doc/refman/5.1/en/datetime.html

+0

公平的答案,但對錶達式更加好奇 - 這是NOW()的情況。另一方面,我不知道使用DBAL來做COLUMN_NAME + 1的答案......現在我要看看我能否做到這一點。 Like votes = votes + 1 –

+0

btw'setValue('vote','vote +?')'是訣竅 –

1

一個遲到的答案,但我發現要做到這一點的最簡單方法是首先運行查詢來獲取NOW()的值,然後插入該字符串。

一個例子:

$now = $db->fetchColumn("SELECT NOW()"); 
$db->insert('table', array(
    'field1' => $field1 
    ,'created' => $now 
)); 

稍微不太理想的替代方案是,如果你能確保你的PHP/MySQL的時間是同步的,你總是可以在PHP創建DateTime對象,並將其格式化爲一個爲MySQL準備的字符串:

$created = new \Datetime('now', new \DateTimeZone('Europe/Paris')); 
$created->format('Y-m-d H:i:s')