5

Is it possible to export the query formatted by mysqli::prepare and ::bind_param?

Example:

<?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();
?>

I would like to export the QUERY functions performed by mysql::prepare and bind_param so (this is an imaginary example):

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

The function ::exportQuery would print like this:

SELECT `id`,`info` FROM `propertys` WHERE id>7290

is there any solution?

Thanks.

Protomen
  • 9,471
  • 9
  • 57
  • 124

3 Answers3

6

I know that this would be useful for debugging, but it is not the way prepared statements work. Parameters are not combined with a prepared statement on the client-side. PHP should never have access to the query string combined with its parameters.

The SQL statement is sent to the database server when you do prepare(), and the parameters are sent separately when you do execute(). MySQL's general query log does show the final SQL with values interpolated after you execute(). Below is an excerpt from my general query log. I ran the queries from the mysql CLI, not from PHP, but the principle is the same.

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

Re your comment:

@Baily is correct, MySQL has no client-side solution to return the full query with parameters interpolated. It's not the fault of PHP.

To enable the logging that I mention above, use this command, either in the MySQL client or submitted from PHP via an API:

SET GLOBAL general_log = ON;

You should turn off the log when you're done collecting information, because it does cost some overhead to be logging every query.

SET GLOBAL general_log = OFF;

PS: Changing the logging settings dynamically requires MySQL 5.1 or later. In earlier versions, you have to restart mysqld when you change logging.

Bill Karwin
  • 538,548
  • 86
  • 673
  • 828
  • Actually maybe something on the side of "mysql" is the solution (not exactly your answer), but still do not know how to do this practical way. – Protomen Jun 14 '13 at 21:15
  • I do not believe MySQL has anything like this built-in. You can always make your own prepare() function to do just this. – Anonymous Jun 15 '13 at 14:06
0

Prepared statements don't work like that, theres a reason you aren't able to see the statement, because its supposed to be able to be passed to database without manipulation.

So the only solution to this is to just attach your data to your string, and echo or save to variable.

EDIT to include the security concern you commented on..

//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();
  }
Kylie
  • 11,421
  • 11
  • 47
  • 78
  • This is not a solution. It does not work with "escape". Part of the idea of ​​using "bind_param" is for security. Please edit your answer. – Protomen Jun 14 '13 at 21:11
  • 1
    You'd better say: "is best not to use bind_param, use mysqli_query+mysql_real_escape_string". Do you agree? Thank you anyway for helping. – Protomen Jun 14 '13 at 21:23
  • Is this a trick question?? Are you asking for help? Or just testing people? – Kylie Jun 14 '13 at 21:27
  • No need to be rude, but you do not understand the purpose of the question. Is that it is closer to the correct answer: http://stackoverflow.com/questions/11508752/export-query-from-mysqli-prepare/17098261#17098261 Maybe it helps you understand the question. – Protomen Jun 14 '13 at 21:34
  • I wasn't trying to being rude, I genuinely wanted to know, if that was the purpose for the question :) – Kylie Jun 14 '13 at 21:36
  • Perhaps the answer of @BillKarwin will help you to understand. Good night and thanks for the help anyway. – Protomen Jun 14 '13 at 21:39
-1

You could just reiterate the query string on the echo line and place your variables in the string manually like such:

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;
    };
}

Much of the comments you posted indicate your question was actually:

How to show the last queries executed on MySQL?

Community
  • 1
  • 1
0x6563
  • 1,032
  • 10
  • 17
  • This is not a solution. It does not work with "escape". Part of the idea of ​​using "bind_param" is for security. Please edit your answer. – Protomen Jun 14 '13 at 21:13
  • 1
    To be fair your question displays you wanting to print out the query, you make no mention of what else you want the export to do. _"Part of the idea of ​​using "bind_param" is for security."_ You asked for the query to be exported from the prepared statement and print that out, I provided you with a suitable alternate to export that printed your query. If your project requires you do something other than that, then your question should reflect that, so you can receive the appropriate responses. None the, less I edited my solution and added a similar question you should have read. – 0x6563 Jun 15 '13 at 18:56
  • 1
    Thanks for trying to help. Read @BillKarwin's answer: http://stackoverflow.com/questions/11508752/export-query-from-mysqli-prepare/17098261#17098261 may help you understand the proposal of the question. – Protomen Jun 18 '13 at 14:28