【问题标题】:Order of function calls for mysqli prepared statements?mysqli准备好的语句的函数调用顺序?
【发布时间】:2013-04-23 18:13:28
【问题描述】:

php 手册似乎对 mysqli 扩展有点轻描淡写,我没有发现任何与 Google 相关的信息。

当我创建一个mysqli准备好的语句时,调用顺序应该是

mysqli::prepare()
mysqli::stmt::bind_param()
mysqli::stmt::execute()
mysqli::stmt::store_result()
mysqli::stmt::bind_result()

mysqli::prepare()
mysqli::stmt::bind_param()
mysqli::stmt::execute()
mysqli::stmt::bind_result()
mysqli::stmt::store_result()

此外,如果我想更改参数并重新执行语句,我应该使用

mysqli::free_result()
mysqli::stmt::execute()
mysqli::stmt::store_result()
mysqli::bind_result()

或者我可以简单地再次使用execute(),然后在使用完语句后使用free_result()?

【问题讨论】:

  • 我已经尝试在两个命令中运行函数,毫不奇怪,在我的测试服务器上任何命令都有效,但在我的生产服务器上,一个命令有时有效,然后另一个命令有时有效,但是这会随着时间而改变。
  • 如果您对某些代码有一些问题,最好就该代码提出问题,同时提供问题。但是,我感觉这不是调用顺序,而是缺少错误报告的原因。

标签: php mysqli


【解决方案1】:

这不是 PHP 手册,而是 mysqli 扩展本身不清楚和模棱两可。

但是,为了消除您的困惑

  1. 您可以在 prepare() 和 fetch() 之间的任意位置调用 store_result()。其实bind_result()只是fetch()的补充功能。

  2. 在 PHP 中,您通常很少需要释放任何东西,尤其是在这种情况下,当结果将在下一次调用中被覆盖时。所以 - 是的,您可以再次调用execute()(首先调用bind_param())。

另请注意,某些安装将允许您调用get_result,这使得所有获取变量的过程至少是明智的。但并不总是可用

还要注意,bind_param()bind_result() 都不会让您轻松绑定任意个变量,这会使代码更加臃肿。

所以,看到所有这些混乱,我仍然建议您使用 PDO 或手动实现的占位符,就像 safeMysql 那样。

【讨论】:

  • 我实际上已经找到了一个简单的 bind_param() 和 bind_result() 解决方案,我一直在使用它。好吧,我猜它比你在 PDO 中使用的要长一行,但是嘿,它就是它。
【解决方案2】:

这是一个有效的例子:

$query="SELECT service_ip,service_port FROM users WHERE username=? and password=?";
$conn=connection();

$stmt = $conn->prepare($query);
$stmt->bind_param('ss', $user,$pass);
$ans=$stmt->execute();

$service_ip=false;
$service_port=false;
$stmt->bind_result($service_ip,$service_port);

$stmt->fetch();

mysqli_free_result($ans);
$stmt->close();
$conn -> close();

【讨论】:

  • 感谢您提供的工作代码,但是,手册指出您应该为所有返回结果的查询调用 store_result,我在您的代码中没有看到这个调用。
  • 我记得几个月前我学习了那个 api,我给你的代码是一个工作生产代码,我想你只是错过了 fetch
  • 我发布的代码是仅用于绑定的 sudo 代码。我也有工作生产代码,但我列出的调用顺序在我的生产服务器上存在一些问题。该手册对调用 store_result 非常清楚。此外,除非您调用 store_result,否则打开多个语句将不起作用。直接取自 php 手册:您必须为成功生成结果集(SELECT、SHOW、DESCRIBE、EXPLAIN)的每个查询调用 mysqli_stmt_store_result(),并且仅当您想缓冲客户端的完整结果集时...
【解决方案3】:

这是正确的代码:

$query="SELECT service_ip,service_port FROM users WHERE username=? and password=?";
$stmt = $conn->prepare($query);
$stmt->execute(array($user,$pass));
$data = $stmt->fetch()/fetchAll()/fetchColumn(); 
// whoops! that's all

// ...in case you want to execute again
$stmt->execute(array($user2,$pass2));
$data = $stmt->fetch()/fetchAll()/fetchColumn();

// and again...
$stmt->execute(array($user3,$pass3));
$data = $stmt->fetch()/fetchAll()/fetchColumn(); 

请注意,您已经拥有所有必需的数据。感受PDO的力量

【讨论】:

  • 我确信 PDO 很棒,但这段代码根本无法回答问题。您的代码完全无法绑定任何参数或任何结果。
  • 恐怕你错了。它实际上绑定了参数和结果。这就是使 PDO 确实很棒的原因。
  • 就像我说的,PDO shure 很棒,但使用它的答案丝毫不能回答问题。
  • 这完全取决于你。我刚刚更正了您关于缺乏约束力的错误说法。
  • 这就是为什么我赞成您的评论,因为您对此非常正确,并且 PDO 让事情变得更容易。
猜你喜欢
  • 1970-01-01
  • 2012-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-22
  • 2014-05-18
  • 2011-03-07
相关资源
最近更新 更多