2

For mysql I use format:

$sql = "select * from table where area_id = ? and item_id = ?";

Then prepare and bind the parameters etc. If the query fails and I log the $sql variable then I get exactly the string above which isn't that useful. What I want is the sql string with the bound values in. As I understand it there is no easy way to do this so I am thinking I can do something like:

sql_log(str_replace('?', array($area_id, $item_id), $sql));

To get something like this in my log:

"select * from table where area_id = West and item_id = West" (spot the error!)

So I know what my error is. But it doesn't work. I get this:

"select * from table where area_id = Array and item_id = Array"
4
  • Are you using mysqli or PDO to prepare your statements? Commented Oct 16, 2018 at 20:14
  • I am using mysqli Commented Oct 16, 2018 at 20:16
  • 1
    Solution here is preg_replace_callback as your items are always ? Commented Oct 16, 2018 at 20:22
  • Possible duplicate of MySQLi prepared statements error reporting Commented Oct 16, 2018 at 20:24

4 Answers 4

3

Use preg_replace_callback function

$sql = "select * from table where area_id = ? and item_id = ?";
$replace = array('area_id', 'item_id');
echo preg_replace_callback('/\?/', function($x) use(&$replace) { return array_shift($replace);}, $sql);
// select * from table where area_id = area_id and item_id = item_id
Sign up to request clarification or add additional context in comments.

Comments

2

Unfortunately, mysqli does not have a good way to get just the query. You could use a method to do the replacement of your parameters:

function populateSql ( string $sql, array $params ) : string {
    foreach($params as $value)
        $sql = preg_replace ( '[\?]' , "'" . $value . "'" , $sql, 1 );
    return $sql;
}

Comments

1

try with this:

sprintf('select * from table where area_id = %s and item_id = %s', $area_id, $item_id);

or

sprintf('select * from table where area_id = "%s" and item_id = "%s"', $area_id, $item_id);

if your fields in the database are integers the %s you have to replace it with %d and do not use quotes

2 Comments

That won't bind properly!
@funnyfish this question isn't about constructing a viable sql query. This is about replacing the placeholders with the bound values for the sake of storing in an error log.
0

Laravel has a beautiful helper for just that.

/**
  * Replace a given value in the string sequentially with an array.
  *
  * @param  string  $search
  * @param  array   $replace
  * @param  string  $subject
  * @return string
  */
function replaceArray($search, array $replace, $subject)
{
    $segments = explode($search, $subject);

    $result = array_shift($segments);

    foreach ($segments as $segment) {
        $result .= (array_shift($replace) ?? $search).$segment;
    }

    return $result;
}

$sql = 'SELECT * FROM tbl_name WHERE col_b = ? AND col_b = ?';

$bindings = [
  'col_a' => 'value_a',
  'col_b' => 'value_b',
];

echo replaceArray('?', $bindings, $sql);

// SELECT * FROM tbl_name WHERE col_b = value_a AND col_b = value_b

Source: Str::replaceArray()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.