How to Use Wildcards in $wpdb Queries Using $wpdb->get_results & $wpdb->prepare?

All we need is an easy explanation of the problem, so here it is.

I am attempting to make a custom search for BuddyPress groups.

Here is my method:

public function search_groups($string){
    global $wpdb;
    $results = $wpdb->get_results($wpdb->prepare(
        "
        SELECT * 
        FROM {$wpdb->prefix}bp_groups 
        WHERE `name` LIKE '%%s%'
        AND `description` LIKE '%%s%' 
        AND `status` = 'public'
        ORDER BY `name` ASC
        ",
        $string,
        $string
    ));
    if(!empty($results)){
        $return = $results;
    } else{
        $return = false;    
    }
    return $return;
}

However, I am receiving a WordPress database error. I’m pretty sure it’s due to the fact that I’m using $wpdb->prepare();, since it uses % signs for replacing variables.

Let’s take a look at this portion of my query:

WHERE `name` LIKE '%%s%'
AND `description` LIKE '%%s%'

That just looks like trouble. Is there any way that I can accomplish something along the lines of…

WHERE `name` LIKE '%{$string}%'
AND `description` LIKE '%{$string}%'

and still use the $wpdb->prepare(); method?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

I figured out a solution to my question.

First of all, in my original query, I should have specified OR instead of AND for searching between group names and group descriptions. (It was skewing the results.)

And I needed to double escape my ‘%’s in the LIKE statements.

Here is the updated query which works correctly:

SELECT * 
FROM {$wpdb->prefix}bp_groups 
WHERE `name` LIKE '%%%s%%'
OR `description` LIKE '%%%s%%' 
AND `status` = 'public'
ORDER BY `name` ASC

Example using $wpdb->query and $wpdb->prepare:

global $wpdb;
$wpdb->query( $wpdb->prepare(
    'DELETE FROM %s WHERE `option_name` LIKE %s',
    $wpdb->options,
    $wpdb->esc_like(PLUGIN_SLUG . '%%')
) );

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply