我的预准备语句被定义为通用 mysql 类的方法。 使用此方法插入到不同表中的插入工作正常。插入到特定表中会将我的所有插值替换为整数。预准备语句和查询看起来不错。看起来插入的整数是从"category_id"字段中插值的。
报表准备:
$sql = "INSERT INTO post_data (`headline`, `body`,`online`,`category_id`,`post_date`)
VALUES (:headline, :body, :online, :categoryId, NOW())";
$bindValues = array('headline' => (string) $headline
, 'body' => (string) $body
, 'online' => (int) $online
, 'categoryId' => (int) $categoryId);
$mysql->insert($sql, $bindValues);
$mysql->insert 方法(适用于另一个表,但不适用于上述查询:
public function insert($sql, array $bindValues) {
$stmt = $this->pdoConn->prepare($sql);
foreach ($bindValues as $name => $value) {
$type = PDOBindings::getType($value);
//see below for PDOBindings::getType()
$stmt->bindParam($name, $value, $type);
}
try {
$this->pdoConn->beginTransaction();
$stmt->execute();
$this->lastInserted = $this->pdoConn->lastInsertId();
$this->pdoConn->commit();
} catch(Execption $e) {
$this->pdoConn->rollback();
return $e->getMessage();
}
return ($this->lastInserted > 0) ? $this->lastInserted : null;
PDOBindings::getType() 静态方法相当简单:
public static function getType($bindValue) {
$itsType = gettype($bindValue);
switch ($itsType) {
case "string":
return PDO::PARAM_STR;
break;
case "integer":
return PDO::PARAM_INT;
break;
case "boolean":
return PDO::PARAM_BOOL;
break;
default :
return PDO::PARAM_STR;
}
}
插入:
INSERT INTO post_data (`headline`, `body`,`online`,`category_id`,`post_date`)
VALUES (:headline, :body, :online, :categoryId, NOW())
与以下内容:
$bindValues = array('headline' => (string) "This is the headline"
, 'body' => (string) "This is the body field to be inserted"
, 'online' => (int) 0
, 'categoryId' => (int) 2);
插入以下行:
ID标题正文在线category_id post_date7 2 2 2 2 2013-11-03 08:34:49
请注意,类别 ID 的值为 2。
使用 Xdebug 单步执行查询并不表示数据设置不正确的任何问题。
这很难调试,因为我无法进入PDO库本身来确定它在哪里覆盖插值。
关于架构的快速说明。 标题是 varchar,正文是文本,在线是 tinyint,category_id 是中等 int。
另外,请记住,此插入适用于另一个表。
以下是不起作用的内容:
重新排列插入项和绑定数组的顺序。
删除日期时间字段。(引发异常。
有效的方法是直接插入行,或使用老式的 mysql 查询构建。
此外,理想情况下,这应该是一个不同的问题,但PDO似乎也没有识别异常处理程序:
$this->pdoConn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
不会在上面的 try 块中引发异常。 执行只是失败。
原因是bindParam
通过引用绑定参数。您将所有参数绑定到同一个变量$value
。因此,当您执行预准备语句时,它将对所有参数使用此变量的最后一个值。这就是为什么它在每一列中插入2
。
使用bindValue
而不是bindParam
,我认为它应该可以解决您的问题。或者完全摆脱调用bindParam
的循环,只需$bindValues
传递给execute()
。
无需自行进入PDO库(尽管您可以,因为它是开源的) - 它不会覆盖插值。
这是你的代码这样做的。因此,您必须继续调试。