Como você prepara adequadamente uma instrução% LIKE% SQL?

34

Eu gostaria de usar uma instrução LIKE% text% enquanto ainda estiver usando a classe WordPress $ wpdb para higienizar e preparar a entrada.

SELECT column_1 from `prefix_my_table` WHERE column_2 LIKE '%something%';

Eu tentei algo como isto sem sucesso:

$wpdb->prepare( "SELECT column_1 from `{$wpdb->base_prefix}my_table` WHERE column_2 LIKE %s;", like_escape($number_to_put_in_like));

Como você prepara adequadamente uma instrução% LIKE% SQL usando a classe de banco de dados WordPress?

editor
fonte

Respostas:

49

A $wpdb->esc_likefunção existe no WordPress porque o escape regular do banco de dados não escapa %e _caracteres. Isso significa que você pode adicioná-los em seus argumentos wpdb::prepare()sem problemas. Isso também é o que vejo no código principal do WordPress :

$wpdb->prepare(" AND $wpdb->usermeta.meta_key = '{$wpdb->prefix}capabilities' AND $wpdb->usermeta.meta_value LIKE %s", '%' . $this->role . '%');

Portanto, seu código seria semelhante a:

$wpdb->prepare(
    "SELECT
        column_1
    FROM
        `{$wpdb->base_prefix}my_table`
    WHERE
        column_2 LIKE %s;",
    '%' . $wpdb->esc_like($number_to_put_in_like) . '%'
);

Você também pode adicionar %%sua consulta para obter um literal %( wpdb::prepare()usos vsprintf()em segundo plano, que tem essa sintaxe ), mas lembre-se de que sua string não será citada ; você deve adicionar as aspas você mesmo (o que geralmente não é o que você costuma fazer em wpdb::prepare().

Jan Fabry
fonte
para que servem {}?
Francisco Corrales Morales
@FranciscoCorralesMorales: para indicar que tudo o que está dentro dele deve ser considerado uma expressão variável , caso contrário, ele apenas veria $wpdbe ignoraria o que ->prefixestava depois.
Jan Fabry
11
@JanFabry Close. Corrigiria o comentário para dizer: "... caso contrário, ele veria tudo $wpdb->base_prefixmy_tablee tentaria procurar base_prefixmy_tablepropriedades em vez de apenas base_prefix."
Flimm
3

Você precisa dobrar por cento para que eles não sejam tratados como marcadores de fragmentos da seguinte maneira wpdb->prepare():

$wpdb->prepare( "SELECT column_1 from `{$wpdb->base_prefix}my_table` WHERE column_2 LIKE %%%s%%;", $wpdb->esc_like( $number_to_put_in_like));

PS não tenho certeza se essa é a melhor / única maneira de fazer isso.

Rarst
fonte
4
Lembre-se de que você deve adicionar as aspas à volta da string , porque wpdb::preparesomente as adicionará para uma %sque não seja precedida por uma% . A parte final da sua consulta deve ser WHERE column_2 LIKE '%%%s%%'.
Jan Fabry
2

Esta é uma maneira de fazer isso que eu verifiquei e funciona:

$search_text = "%" . $_GET['some_text'] . "%";

$user_count = $wpdb->get_var( 
    $wpdb->prepare( 
        "SELECT COUNT(*) FROM mix_library WHERE ml_setting_name LIKE %s", 
        $search_text 
    ) 
);

Substitua variáveis ​​para atender às suas necessidades.

Calvin
fonte
5
Você deve escapar de %caracteres (usando like_escape(). Veja: codex.wordpress.org/Class_Reference/…
Stephen Harris