Prepared statements used incorrectly in ACF?

I’m pretty sure that you ARE incorrect.

Let’s taka a closer look at this code you mentioned in your question.

In first line it sets $where variable:

$where="WHERE ID IN (" . substr(str_repeat('%d,', count($my_options['acf_posts'])), 0, -1) . ')';

So what this line really does is:

  • get the number of some options (let’s call it ‘N’)
  • repeats %d placeholder N times
  • append it to string WHERE ID IN ('.

So $where variable contains a string like this:

WHERE ID IN (%d, %d, %d, ...)

… and as you can see, this string CONTAINS placeholders.

Just after this line comes real query, which is build using this $where variable, and the option values ARE inserted using these placeholders.

There isn’t anything bad in using variables, when you build query string, if these variables contains safe strings (i. e. don’t contain values comming from user).


PS. Take a look at this code:

$sql = "SELECT * FROM {$wpdb->posts} WHERE ID=%d";
$results = $wpdb->get_results( $wpdb->prepare( $sql, 10 ) );

Do you think this is also a vulneribility?