如何使用bindParam编写更少的代码?

时间:2017-02-05 10:25:59

标签: php pdo bindparam

我正在使用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);
}

3 个答案:

答案 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'));

但我个人更喜欢位置占位符。