0

For a few years, I have been happily using PDO debugger and recommend it highly.

I haven'f found anything better to help me debug my PDO SQL statements with bound parameters. It will show me the SQL statement which will be generated after bound parameters are substituted, which is A Good Thing.

I post the code below. My problem is that when I introduce a SELECT query using LIKE %gail.com, where $agencyEmailDomain == "gmail.com" and $expandedSqlCommand = PdoDebugger::show($sqlText, $parameters);

expanded to

SELECT count(*) AS count FROM recruiters WHERE recruiter_email LIKE "%'Gmail.com'"

Notice those single quotes around the domain name?

Is there something that I can do, like escaping the % sign?

My code is

$sqlText = 'SELECT count(*) AS count FROM recruiters 
            WHERE recruiter_email LIKE "%:agencyEmailDomain"';

$sqlParameters =  array('agencyEmailDomain' => $agencyEmailDomain);

and PDO-debugger's code is

/**
 * Class PdoDebugger
 *
 * Emulates the PDO SQL statement in an extremely simple kind of way
 */
class PdoDebugger
{
    /**
     * Returns the emulated SQL string
     *
     * @param $raw_sql
     * @param $parameters
     * @return mixed
     */
    static public function show($raw_sql, $parameters)
    {
        $keys = array();
        $values = array();

        /*
         * Get longest keys first, so that the regex replacement doesn't
         * cut markers (ex : replace ":username" with "'joe'name"
         * if we have a param name :user )
         */
        $isNamedMarkers = false;

        if (count($parameters) && is_string(key($parameters))) 
        {
            uksort($parameters, function($k1, $k2) 
            {
                return strlen($k2) - strlen($k1);
            });

            $isNamedMarkers = true;
        }

        foreach ($parameters as $key => $value) 
        {

            // check if named parameters (':param') or anonymous parameters ('?') are used
            if (is_string($key)) 
            {
                $keys[] = '/:'.ltrim($key, ':').'/';
            } 
            else 
            {
                $keys[] = '/[?]/';
            }

            // bring parameter into human-readable format
            if (is_string($value)) 
            {
                $values[] = "'" . addslashes($value) . "'";
            } 
            elseif(is_int($value)) 
            {
                $values[] = strval($value);
            } 
            elseif (is_float($value)) 
            {
                $values[] = strval($value);
            } 
            elseif (is_array($value)) 
            {
                $values[] = implode(',', $value);
            } 
            elseif (is_null($value)) 
            {
                $values[] = 'NULL';
            }
        }

        if ($isNamedMarkers) 
        {
            return preg_replace($keys, $values, $raw_sql);
        } 
        else 
        {
            return preg_replace($keys, $values, $raw_sql, 1, $count);
        }
    }
} 

How can I change to correctly handle that LIKE "%:agencyEmailDomain"?

Mawg says reinstate Monica
  • 38,334
  • 103
  • 306
  • 551
  • 1
    [Using LIKE in bindParam for a MySQL PDO Query](https://stackoverflow.com/q/11068230/1415724) – Funk Forty Niner Nov 09 '17 at 12:30
  • your PDO code is wrong. Fix it first and this error will go as well – Your Common Sense Nov 09 '17 at 12:30
  • 2
    Your debugger is wrong. That placeholder won't be read as a placeholder because it is quoted. You should get an error about number of placeholders to bound values, because `%:agencyEmailDomain` would just be a string in the query. One way to write it would be `WHERE recruiter_email LIKE concat('%', :agencyEmailDomain)` – chris85 Nov 09 '17 at 12:37
  • Feel free to post that as an answer and I will accept it. Much more helpful than "your PDO code is wrong. Fix it first and this error will go as well" – Mawg says reinstate Monica Nov 09 '17 at 14:05

0 Answers0