我正在使用PDO将数据插入表中。问题是,有很多列,这意味着查询很长。
这是我目前的代码:
$stmt = $con->prepare("INSERT INTO table (crips, biscuits, chocolate, cakes, smarties, yogurts, apples, oranges) VALUES (:crisps, :biscuits, :chocolate, :cakes, :smarties, :yogurts, :apples, :oranges)");
$stmt->bindParam(':crisps', $crisps);
$stmt->bindParam(':biscuits', $biscuits);
$stmt->bindParam(':chocolate', $chocolate);
$stmt->bindParam(':cakes', $cakes);
$stmt->bindParam(':smarties', $smarties);
$stmt->bindParam(':yogurts', $yogurts);
$stmt->bindParam(':apples', $apples);
$stmt->bindParam(':oranges', $oranges);
$stmt->execute();
是否有更简单的方法,而不是为每个值设置不同的代码行?
这样的事情可能吗?
foreach(value) {
$stmt->bindParam(':value', $value);
}
答案 0 :(得分:3)
您可以使用?
标识符并按顺序提供值:
$stmt = $con->prepare("
INSERT INTO table
(crips, biscuits, chocolate, cakes, smarties, yogurts, apples, oranges)
VALUES
(?, ?, ?, ?, ?, ?, ?, ?)
");
$stmt->execute([$crisps, $biscuits, $chocolate, $cakes, $smarties, $yogurts, $apples, $oranges]);
它已经保存了相当多的代码,:named
参数有其用途,但您无法将它们与?
结合使用。
您可以使用循环,但这需要预定义的数组首先循环。
对于命名参数,创建一个如下数组:
$list = [
':crisps' => $crisps,
':biscuits' => $biscuits,
# etc
];
foreach($list as $k => $v){
$stmt->bindValue($k, $v);
}
$stmt->execute();
这适用于?
索引参数:
$list = [
$crisps,
$biscuits,
#etc
]
foreach($list as $k => $v){
$stmt->bindValue($k+1, $v);
}
$stmt->execute();
请注意,我已将方法从bindParam()
更改为bindValue()
,就像您的代码示例一样,使用该方法没有任何好处。
然后存在使用bindValue()
的问题,因为该方法只有aditional功能是它能够使用3th
参数将某个值转换为特定类型。不管怎样。
因此,从本质上讲,您可以直接在foreach
方法中提供$list
来避免execute()
循环:
$stmt->execute($list);
如果你真的想使用bindParam()
,那么只需在变量名称之前添加引用符号:
$list = [
':cakes' => &$cakes
];
答案 1 :(得分:1)
你的foreach可以使用,但你需要构建那个仍然需要代码行的数组 - 马克贝克。
这是真的。
注意:请read here关于我使用
BindValue
而不是BindParam
的原因。感谢Xorifelse的提醒。
Codesee,如果你真的非常关心代码行,那么我建议你自己构建一个数据库交互类,你可以用它来做这些事情。一旦编写了类,它将为您节省代码布局重复。
关于使用foreach
的想法并不遥远,可以用来节省一些重复,例如你可以构造一个数组(其中引用var名称是关键)来紧密关联每个变量它各自的SQL占位符。
这样:
$save['crisps'] = $crisps;
$save['biscuits'] = $buiscuits;
...
这将使用变量的集合(数组)替换您的独立变量($crisps
等),其中数组键是引用名称。
然后
foreach($save as $key=>$value){
$stmt->bindValue(":".$key, $value);
}
unset($key,$value);
注意:我没有在这里进行任何安全清理或检查程序,因为这有点超出范围,但我建议这样做(preg_replace
或类似)以确保无效字符事先从关键值中删除。
示例:
$key = preg_replace("/[^a-z]/i","",$key);
你确定我需要一个预定义的数组吗?它可以再简化了,因为$ v总是和$ k一样,前面有一个$(如果你理解我的意思)? - Codesee
这个问题是因为你的变量没有收集到数组或对象中,代码如何知道要添加到INSERT
SQL的变量?你仍然需要一行代码。
答案 2 :(得分:0)
Xorifelse已经清楚地说明了这个话题,所以我只能做一个非常小的补充。在PHP中,你总能找到一个奇怪的功能,可以帮助你做一些奢侈的事情。
因此,如果您更喜欢使用命名占位符,则可以使用它们,但仍然使用带有execute()的快捷方式:
$stmt = $con->prepare("INSERT INTO table (crips, biscuits, chocolate, cakes, smarties, yogurts, apples, oranges) VALUES (:crisps, :biscuits, :chocolate, :cakes, :smarties, :yogurts, :apples, :oranges)");
$stmt->execute(compact('crisps', 'biscuits', 'chocolate', 'cakes', 'smarties', 'yogurts', 'apples', 'oranges'));
但我个人更喜欢位置占位符。