Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 准备语句,使用int表字段进行插入_Php_Pdo_Insert_Prepared Statement - Fatal编程技术网

Php 准备语句,使用int表字段进行插入

Php 准备语句,使用int表字段进行插入,php,pdo,insert,prepared-statement,Php,Pdo,Insert,Prepared Statement,我正在做一个学习OOP的个人项目。我创建这个通用方法是为了对表进行插入,但我不能$dbAttributes是表中没有id的字段列表。我传递一个对象实例,例如,设置了属性的产品,如类别id、产品名称、价格。当我尝试使用foreach循环绑定值时,问题就出现了 我发现错误: SQLSTATE[HY000]:一般错误:1366不正确的整数值 从占位符中删除单引号后,我得到: SQLSTATE[42000]:语法错误或访问冲突:1064 公共静态函数创建($obj){ 全球$db; $db->setAt

我正在做一个学习OOP的个人项目。我创建这个通用方法是为了对表进行插入,但我不能
$dbAttributes
是表中没有id的字段列表。我传递一个对象实例,例如,设置了属性的产品,如类别id、产品名称、价格。当我尝试使用foreach循环绑定值时,问题就出现了

我发现错误:

SQLSTATE[HY000]:一般错误:1366不正确的整数值

从占位符中删除单引号后,我得到:

SQLSTATE[42000]:语法错误或访问冲突:1064

公共静态函数创建($obj){
全球$db;
$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_异常);
$dbAttributes=$obj->db_字段;
$colonValues=array();
对于($i=0;$iprepare($sql);
foreach($k=>$value的冒号值){
$rs=$obj->$dbAttributes[$k];
//如果($k!=0){
$stmt->bindParam($value,$rs);
echo gettype($rs)。“.$rs.”
“;//} } 变量转储($sql); $numrowsimpacted=$db->exec($sql); }捕获(例外$ex){ echo$ex->getMessage(); } }

正如您所看到的,我正在尝试动态创建SQL并动态绑定值。我尝试了所有方法,还阅读了关于使用表名的反勾号的论坛,但没有解决问题。

您准备了语句,但没有执行准备好的语句。您
exec($SQL)
作为未准备好的语句。此方法不支持查询参数,它逐字执行SQL。因此,当MySQL需要整数文本并找到
:columnname
时,它会抱怨,这并不奇怪

$numRowsAffected = $db->exec($sql);
这应该是:

$stmt->execute();
$numRowsAffected = $stmt->rowCount();
参数占位符不能放在SQL中的引号内

此外,您不必使用bindValue(),只需传递一个数组以执行()

下面是编写函数的一种更简单的方法:

public static function create($obj) {
    global $db;

    $db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    $dbAttributes = $obj->db_fields;
    $columns = array_map(function ($col) { return "`" . $col . "`"; },
        array_values($dbAttributes));
    $paramPlaceholders = array_map(function ($col) { return ":" . $col; },
        array_values($dbAttributes));
    $paramValues = array_intersect_key(get_object_vars($obj), array_flip($dbAttributes));

    $sql ="INSERT INTO `".$obj::$tableName."` (".implode(",",$columns).")"
        . " VALUES (".implode(",",$paramPlaceholders).")";

    try {
        $stmt = $db->prepare($sql);
        $stmt->execute($paramValues);
        $numRowsAffected = $stmt->rowCount();
    } catch (Exception $ex) {
        echo $ex->getMessage();
    }

}

我试着用你的建议来修复我的代码,效果很好。作为对任何人的提醒,当我用上面的代码执行bindParam时,它会将所有内容都更改为字符串,所以我使用了bindValue,并按照你的建议使用了execute()。你的方法简短明了。我在一篇教程exec()中读到了一个问题当我们插入、更新或删除时非常理想,因为它返回受影响的行数。从您的回答中,我应该只对准备好的语句使用execute()而不是exec()。您是这么说的吗?您还添加了backtick;是因为Placeholder名称与列名匹配吗?exec()不支持预处理语句,因此如果使用exec(),则不能有参数。我在表名和列名周围添加了回标记,以防它们与SQL保留字匹配。
public static function create($obj) {
    global $db;

    $db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    $dbAttributes = $obj->db_fields;
    $columns = array_map(function ($col) { return "`" . $col . "`"; },
        array_values($dbAttributes));
    $paramPlaceholders = array_map(function ($col) { return ":" . $col; },
        array_values($dbAttributes));
    $paramValues = array_intersect_key(get_object_vars($obj), array_flip($dbAttributes));

    $sql ="INSERT INTO `".$obj::$tableName."` (".implode(",",$columns).")"
        . " VALUES (".implode(",",$paramPlaceholders).")";

    try {
        $stmt = $db->prepare($sql);
        $stmt->execute($paramValues);
        $numRowsAffected = $stmt->rowCount();
    } catch (Exception $ex) {
        echo $ex->getMessage();
    }

}