php - foreach() 中的 bind_param 未正确传递
Posted
技术标签:
【中文标题】php - foreach() 中的 bind_param 未正确传递【英文标题】:php - bind_param inside foreach() not correctly passing 【发布时间】:2013-03-24 10:35:14 【问题描述】:我确定这是重复的,但我在此处的网站上尝试了几种不同的方法,但没有一种方法适合我。我在 php 中调用我的函数,发送 $mysqli 连接、$clientID 和要上传的 $tagFields 数组。
它正在“工作”,但值始终为空。我已将 echo "$tagName" 放入 foreach 中,它正在读取它,但没有将其发送到数据库。但是,$clientID 正在传递信息。所以基本上它所做的就是将一致的空白行上传到我的数据库中。我在这里做错了什么?
function tagRefresh($mysqli,$clientID,$tagFields)
$stmt = $mysqli->stmt_init();
$query = "INSERT INTO client_tags (client_id,tag_category) VALUES (?,?) ";
$stmt->prepare($query);
foreach($tagFields as $tagName)
$stmt->bind_param('is',$clientID,$tagName);
$stmt->execute();
$tagFields 的一些示例值:
$tagFields[0] = "Regional";$tagFields[1] = "Automotive";$tagFields[2] = "Maintenance";
【问题讨论】:
我相信bind_param
只绑定到变量的引用。因此,由于您的 foreach
在每次迭代时都会重置 $tagName
,因此绑定失败。不幸的是,我在 mysqli 中找不到 bindValue
(PDO) 等效项。此外,在您的foreach
完成后,您只需要execute
一次。
检查这个例子; php.net/manual/en/mysqli.prepare.php#107200
你的代码对我有用。
@MiroslavStopka,你运行的是什么版本的 php/mysql/apache?
@MDWar PHP 版本 5.3.8, MySQL: 5.5.16 , Apache 版本 Apache/2.2.21 (Win32) mod_ssl/2.2.21 OpenSSL/1.0.0e PHP/5.3.8 mod_perl/2.0 .4 Perl/v5.10.1。顺便检查一下你的表 client_tags (列属性...)
【参考方案1】:
注意mysqli_stmt::bind_param绑定变量的引用。 试试下面的:
function tagRefresh($mysqli,$clientID,$tagFields)
$stmt = $mysqli->stmt_init();
$query = "INSERT INTO client_tags (client_id,tag_category) VALUES (?,?) ";
$stmt->prepare($query);
$stmt->bind_param('is', $clientID, $tagName);
foreach($tagFields as $tagName)
$stmt->execute();
【讨论】:
【参考方案2】:execute() 不应位于 foreach 内。
【讨论】:
但这也无妨;) 除非意图是多次执行 为什么?您如何建议在没有循环的情况下多次执行此操作? 那么,不要使用准备好的语句吗?这似乎是个坏主意。 为什么必须只调用一次?按照您的建议动态构建查询会阻止使用准备好的语句,这意味着它可能效率较低且安全性较低。重复执行语句正是我们的意图;这就是准备好的语句可以表现出更高效率的地方。这样做本身并没有错。相反,在适当的情况下,它可能是可取的。如果数据都是内部数据并且不包括用户输入,那么按照您的建议构建它可能没问题。如果涉及到用户输入,那么我肯定会使用准备好的语句。【参考方案3】:在与数据库相关的无数问题中(包括 client_id 作为主键),我重新构建了这样的公式:
function tagRefresh($mysqli,$clientID,$tagFields)
$query = "DELETE FROM client_tags WHERE client_id = '" . $clientID . "'"; //we have to delete the old ones every time
if(!$mysqli->query($query))
echo $mysqli->error;
if($tagFields != '') //see if data was sent
$tags = array();
foreach($tagFields as $tag)
$tags[] = "('" . (int) $clientID . "', '" . $tag ."')"; //build an array
$query = "INSERT INTO client_tags (client_id,tag) VALUES " . implode(',', $tags) . " ON DUPLICATE KEY UPDATE client_id = " . $clientID;
if(!$mysqli->query($query))
echo $mysqli->error; //drop errors, will attach this later
这个格式是这样的:
INSERT INTO client_tags (client_id,tag) VALUES ('1234','mechanical'),('1234','regional'),('1234','service') ON DUPLICATE KEY UPDATE client_id = '1234';
ON DUPLICATE 部分很重要,因为出于某种原因,client_id 被设置为主键。我将不得不与应用程序人员交谈,看看这对他们是否重要。
不幸的是,bind_param 没有被使用,但这是一个仅适用于公司员工的管理面板访问权限,现在它正在工作,我正在给他们自动完成框以引用现有值。
【讨论】:
以上是关于php - foreach() 中的 bind_param 未正确传递的主要内容,如果未能解决你的问题,请参考以下文章