1

我准备好的语句被定义为通用 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_date

7 2 2 2 2 2013-11-03 08:34:49

请注意,categoryId 的值为 2。

使用 Xdebug 单步执行查询并不表示数据设置不正确有任何问题。

调试起来很困难,因为我无法自己进入 PDO 库来确定它在哪里覆盖了插值。

关于模式的快速说明。标题是 varchar,正文是文本,在线是 tinyint,category_id 是中等 int。

另外,请记住,此插入对另一个表也适用。

这是没有用的:

重新排列插入项的顺序,并绑定数组。

删除日期时间字段。(抛出异常。)

有效的方法是直接插入行,或使用老式的 mysql 查询构建。

此外,理想情况下,这应该是一个不同的问题,但 PDO 似乎也没有识别异常处理程序:

$this->pdoConn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

不会在上面的 try 块中抛出异常。执行失败。

4

2 回答 2

3

原因是bindParam通过引用绑定参数。您将所有参数绑定到同一个变量$value。因此,当您执行准备好的语句时,它将使用此变量的最后一个值作为所有参数。这就是为什么它2在每一列中插入。

使用bindValue代替,bindParam我认为它应该可以解决您的问题。或者摆脱bindParam完全调用的循环,然后传递$bindValuesexecute().

于 2013-11-03T17:23:47.527 回答
0

无需自行进入 PDO 库(尽管您可以,因为它是开源的) - 它不会覆盖插值。

这是你的代码做的。所以,你必须继续调试。

于 2013-11-03T17:17:29.613 回答