web-dev-qa-db-fra.com

Je ne comprends pas $ wpdb-> préparer correctement

J'ai une requête qui fonctionne bien en raw PHP mais je ne peux pas l'exécuter avec $ wpdb. Il semble que quelque chose manque dans les conseils donnés à Comment préparer correctement une instruction% LIKE% SQL?

Mon code est

global $wpdb;
// Create a SQL statement with placeholders for the string input.
$sql3 = "SELECT id, post_date, post_title, guid FROM $wpdb->posts where post_type='attachment' and post_mime_type like %s;";
// Prepare the SQL statement so the string input gets escaped for security.
$sql3 = $wpdb->prepare( $sql3, $wpdb->esc_like('image').'%' );
echo $sql3;
$result3 = $wpdb->get_results( $sql3, OBJECT );
$wpdb->print_error();
echo "<script>var NumImages=".$result3->num_rows."</script>\n"; //pass global variable

$sql2 = "SELECT id, post_date, post_title, guid FROM wp_posts where post_type='attachment' and post_mime_type like 'image/%' ";
$result2 = $mx_conn->query($sql2);
echo "<script>var NumImages2=".$result2->num_rows."</script>\n"; //pass global variable 

et les résultats sont

SELECT id, post_date, post_title, guid FROM wp_posts where post_type='attachment' and post_mime_type like 'image{eba84c0d1eba4e4059d0be4f26c5b63f33813b7eb78af4b6237419122fccde3f}'; 
<script>var NumImages=</script>
<script>var NumImages2=917</script>

J'ai essayé de ré-échapper le signe de pourcentage '\%' en vain.

1
Geoff Ebbs

Ok, il y a donc un problème majeur avec votre code et il n’a rien à voir avec l’échappement des instructions LIKE en SQL. Mais laissez-moi partir de ça ...

Il n'y a rien de mal à vous échapper. Vous devriez le faire exactement comme ça:

global $wpdb;
// Create a SQL statement with placeholders for the string input.
$sql3 = "SELECT id, post_date, post_title, guid FROM $wpdb->posts where 
post_type='attachment' and post_mime_type like %s;";
// Prepare the SQL statement so the string input gets escaped for security.
$sql3 = $wpdb->prepare( $sql3, $wpdb->esc_like('image').'%' );
echo $sql3;
$result3 = $wpdb->get_results( $sql3, OBJECT );

Bien qu’il ne soit pas utile de s’échapper cette fois-ci, vous savez exactement quelle chaîne est transmise et est sécurisée.

Alors pourquoi $ wpdb génère un SQL si étrange?

C'est un correctif pour cette vulnérabilité: https://blog.ircmaxell.com/2017/10/disclosure-wordpress-wpdb-sql-injection-technical.html

Ce comportement a été introduit dans WP 4.8.3 et permet de "préparer en double" SQL-safe-injection-safe ...

Alors, pourquoi votre code ne fonctionne pas correctement?

$wpdb->get_results( $sql3, OBJECT );

renvoie un tableau d'objets (un pour chaque ligne sélectionnée). C'est un tableau, vous ne pouvez donc pas appeler ->num_rows dessus ...

Si vous voulez compter les lignes, vous pouvez utiliser:

count( $result3 );

ou

$wpdb->num_rows;
0
Krzysiek Dróżdż