从“mysqli->准备”导出“查询”
是否可以导出格式为mysqli::prepare
和::bind_param
的查询?从“mysqli->准备”导出“查询”
实施例:
<?php
$mysqli = new mysqli('host', 'user', 'pass', 'table');
if(mysqli_connect_errno()){
printf('Connect failed: %s\n', mysqli_connect_error());
exit;
}
$data=7290;
if ($stmt = $mysqli->prepare('SELECT `id`,`info` FROM `propertys` WHERE id>?')){
$stmt->bind_param('i',$data);
$stmt->execute();
$stmt->bind_result($id,$info);
while($q=$stmt->fetch()){
echo $id,': ',$info,'<br>';
}
$stmt->close();
}
$mysqli->close();
?>
我想通过mysql::prepare
和bind_param
导出进行QUERY
功能,以便(这是一个假想的示例):
if ($stmt = $mysqli->prepare('SELECT `id`,`info` FROM `propertys` WHERE id>?')){
$stmt->bind_param('i',$data);
$stmt->execute();
echo $stmt->exportQuery();//Function does not exist, just for example
功能::exportQuery
将打印这样:
SELECT `id`,`info` FROM `propertys` WHERE id>7290
有没有解决方法?
谢谢。
我知道这对调试很有用,但它不是准备语句的工作方式。参数不与客户端上的预备语句组合。 PHP永远不能访问与其参数结合的查询字符串。
执行prepare()时,将SQL语句发送到数据库服务器,并且在执行execute()时单独发送参数。 MySQL的通用查询日志在执行()后会显示最终的SQL,并插入值。以下是我的一般查询日志的摘录。我从mysql CLI运行查询,而不是从PHP运行,但原理相同。
081016 16:51:28 2 Query prepare s1 from 'select * from foo where i = ?'
2 Prepare [2] select * from foo where i = ?
081016 16:51:39 2 Query set @a =1
081016 16:51:47 2 Query execute s1 using @a
2 Execute [2] select * from foo where i = 1
回复您的评论:
@Baily是正确的,MySQL有没有客户端解决方案,以返回与插补参数的完整的查询。这不是PHP的错。
为了让我上面提到的日志,使用此命令,无论是在MySQL客户端,或通过API从PHP提交:
SET GLOBAL general_log = ON;
,您应该关闭日志大功告成收集信息时, ,因为记录每个查询的确需要一些开销。
SET GLOBAL general_log = OFF;
PS:动态更改日志记录设置需要MySQL 5.1或更高版本。在早期版本中,当您更改日志记录时,必须重新启动mysqld。
你可以只手动重申回声行的查询字符串,并将字符串中的变量像这样:
if ($stmt = $mysqli->prepare('SELECT `id`,`info` FROM `propertys` WHERE id>?')){
$stmt->bind_param('i',$data);
if($stmt->execute()){
echo 'SELECT `id`,`info` FROM `propertys` WHERE id>'.$data;
};
}
多,你发布的评论中指出你的问题其实是:
这不是一个解决方案。它不适用于“逃生”。部分使用“bind_param”的想法是为了安全。请编辑你的答案。 – 2013-06-14 21:13:22
为了公平起见,您的问题显示您希望打印出查询,但您没有提及您想要导出的内容。 _“使用”bind_param“的部分想法是为了安全。”_您要求从准备好的语句中导出查询并将其打印出来,我向您提供了一个合适的替代方案来导出打印您的查询。如果你的项目需要你做别的事情,那么你的问题应该反映出来,所以你可以收到适当的回应。没有,我编辑了我的解决方案,并添加了您应该阅读的类似问题。 – varubi 2013-06-15 18:56:35
感谢您的帮助。阅读@ BillKarwin的答案:http://stackoverflow.com/questions/11508752/export-query-from-mysqli-prepare/17098261#17098261可能会帮助你理解问题的建议。 – 2013-06-18 14:28:15
准备好的语句不会像那样工作,这是您无法看到语句的原因,因为它应该能够在没有操作的情况下传递到数据库。
所以唯一的解决办法就是将数据附加到你的字符串,并回显或保存到变量。
编辑,包括对你评论的安全问题..
//Assume you're using $_GET to get the id
$data = mysql_real_escape_string($_GET['yourID']);
$yourStatement = 'SELECT `id`,`info` FROM `propertys` WHERE id>';
$savedStatement = $yourStatement.$data;
echo $savedStatement;
//Will return 'SELECT `id`,`info` FROM `propertys` WHERE id>4'
if ($stmt = $mysqli->prepare($yourStatement.'?')){
$stmt->bind_param('i',$data);
$stmt->execute();
}
这不是一个解决方案。它不适用于“逃生”。部分使用“bind_param”的想法是为了安全。请编辑你的答案。 – 2013-06-14 21:11:26
只要在mysql_real_escape_string ....就像上面那样 – KyleK 2013-06-14 21:19:22
你最好说: “最好不要使用bind_param,使用mysqli_query + mysql_real_escape_string”。你同意吗?无论如何谢谢你的帮助。 – 2013-06-14 21:23:16
其实也许对“mysql的”侧面的东西是解决方案(不完全你的答案),但还是不知道如何做这个实用的方法。 – 2013-06-14 21:15:20
我不相信MySQL有这样的内置任何东西。你总是可以使自己的prepare()函数来做到这一点。 – Anonymous 2013-06-15 14:06:49