【发布时间】:2013-12-20 12:01:21
【问题描述】:
我将如何在 PDO 准备语句中使用 MySQL 的 NOW(),或者我将如何使用它来解决问题,同时牢记 Apache 服务器和数据库服务器可能有轻微的当前时间不匹配(几秒),或者在在极少数情况下可能是时区不同?
我的代码中有以下函数:
try {
$dbh->insert("users", array(
"email" => $email,
"password" => $password,
"salt" => $salt,
"ingame" => $ingame,
"kiosk" => $kiosk
));
} catch (PDOException $ex) {
error($ex);
}
调用者:
/**
* Inserts data into a table. Data must be given in key-value pairs.
*
* Example: $dbh->insert("table", array(
* "data1" => $data1,
* "data2" => $data2
* );
*
* @param type $table The table to insert to
* @param type $keyvaluepairs The key-value pairs.
* @return type The statement that this query produced.
*/
public function insert($table, $keyvaluepairs) {
$sql = "INSERT INTO `{$table}` (";
$values_sql = ") VALUES(";
$values = array();
foreach ($keyvaluepairs as $key => $value) {
$sql .= "`${key}`, ";
$values_sql .= "?, ";
$values[] = $value;
}
$query = substr($sql, 0, -2).substr($values_sql, 0, -2).")";
return $this->query($query, $values);
}
调用者:
//TODO update documentation to show it also handles associative arrays with bindvalue
/**
* Can be called to create a query. Use either unnamed or named placeholders for the prepared statements.
*
* Example: $dbh->query("INSERT INTO table (data1, data2) VALUES(?, ?)", array($data1, $data2));
*
* @param type $query The input query, including unnamed or named placeholders
* @param type $values The input values. If it's not an array, then it will be an one-element array
* @return type The statement constructed by this query
*/
public function query($query, $values = array()) {
if (!is_array($values)) {
$values = array($values);
}
$statement = $this->dbh->prepare($query);
$statement->setFetchMode(PDO::FETCH_OBJ);
$i = 1;
if (is_assoc($values)) {
foreach ($values as $key => $value) {
$statement->bindValue($key, $value);
}
}
else {
foreach ($values as $value) {
$statement->bindValue($i++, $value);
}
}
$statement->execute();
return $statement;
}
我有这个功能的地方:
function is_assoc($array) {
return (bool)count(array_filter(array_keys($array), 'is_string'));
}
所以这里的交易是我不能对插入使用自定义 MySQL 查询,因为为了方便起见我已经封装了这些查询,但我仍然希望能够插入 NOW() em> 利用TIMESTAMP / CURRENT_TIMESTAMP()。
我希望您理解这个问题需要一个解释性的答案,因为我已经阅读了“正常”的答案并表明它们不能满足我的需求。
更新:我已将const SQL_NOW = 1; 添加到我的DBH 课程中,但是现在我想将insert 修改为如下内容:
public function insert($table, $keyvaluepairs) {
$sql = "INSERT INTO `{$table}` (";
$values_sql = ") VALUES(";
$values = array();
foreach ($keyvaluepairs as $key => $value) {
if ($value == SELF::SQL_NOW) {
$sql .= "NOW(), ";
}
else {
$sql .= "`${key}`, ";
$values_sql .= "?, ";
$values[] = $value;
}
}
$query = substr($sql, 0, -2).substr($values_sql, 0, -2).")";
return $this->query($query, $values);
}
这可能是一个合适的解决方案,但是我不能将1 用作SQL_NOW 值,因为如果我想插入一个整数1,它会失败。如果我采用这个解决方案,那么SQL_NOW 会有什么价值?甚至可以给它没有价值吗?
【问题讨论】:
-
@Downvoter:需要解释一下吗?