I’m working on a WordPress plugin and keep getting a PHPCS warning that I can’t seem to resolve. The warning is:
WARNING WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
Incorrect number of replacements passed to $wpdb->prepare(). Found 3 replacement parameters, expected 2.
Here’s my code snippet:
// Check for image URL or filename in postmeta
if ($attachment_url) {
$attachment_basename = basename($attachment_url);
// Prepare the status placeholders
$placeholders = implode(',', array_fill(0, count($statuses), '%s'));
$meta_url_usage = $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT(*)
FROM $wpdb->postmeta pm
JOIN $wpdb->posts p ON p.ID = pm.post_id
WHERE (pm.meta_value LIKE %s OR pm.meta_value LIKE %s)
AND p.post_status IN ($placeholders)",
'%' . $wpdb->esc_like($attachment_url) . '%',
'%' . $wpdb->esc_like($attachment_basename) . '%',
...$statuses
)
);
if ($meta_url_usage > 0) {
return true;
}
What I’ve tried:
- Verified that $statuses is a non-empty array
- Confirmed the generated SQL looks correct when printed
- The query actually works in execution
- Tried different placeholder approaches for the IN clause
Problem is PHPCS thinks I should only have 2 replacements (for the LIKE clauses). But I need to pass the status values for the IN clause. The spread operator (…$statuses) is adding additional parameters.
My Question: Is this a false positive in PHPCS or am I doing something wrong? What’s the proper way to handle dynamic IN clauses with $wpdb->prepare()? Or, should I suppress the Warning?
The code works as expected, but I want to make sure I’m following WordPress coding standards properly. Any insights would be greatly appreciated!