Как использовать $wpdb->prepare в SQL-запросах, содержащих IN()

В большом гайде по написанию SQL-запросов при помощи $wpdb мы уже говорили о необходимости использовать $wpdb->prepare() во имя безопасности. Всегда, когда это нужно, ребят, а то понимаете, бывают ситуации со сложными запросами, например содержащими IN(), и в моменте может показаться, что в $wpdb->prepare() нет большой необходимости, к примеру, когда вы не получаете данные непосредственно от пользователя через $_GET или $_POST. Так вот, это предположение конечно же ошибочно, и нам нужно обязательно очищать SQL-запрос. И в этом уроке я на примере научу вас, как.

А вот так выглядит наш пример:

global $wpdb;
 
$post_types = get_post_types( array( 'public' => true ) );
 
// получение общего количества опубликованных постов всех публичных типов записей
$count = $wpdb->get_var(
	"
	SELECT COUNT(*)
	FROM {$wpdb->posts}
	WHERE post_status = 'publish'
	AND post_type IN ( '" . join( "', '", $post_types ) . "' )
	"
);					"

Так как get_post_types() – это вроде бы как стандартная функция WodPress и может возникнуть соблазн ей довериться – не нужно. Очищаем данные как обычно.

Вот так это делается, ребят:

// получение общего количества опубликованных постов всех публичных типов записей
$sql = call_user_func_array(
	array( $wpdb, 'prepare' ),
	array_merge(
		array(
			"
			SELECT COUNT(*)
			FROM {$wpdb->posts}
			WHERE post_status = 'publish'
			AND post_type IN ( " . join( ', ', array_fill( 0, count( $post_types ), '%s' ) ) . " )
			"
		),
		$post_types
	)
);
$count = $wpdb->get_var( $sql );

Объясняю:

  • call_user_func_array() – это PHP функция, которая позволяет запустить функцию или метод объекта (первый параметр), у нас это метод $wpdb->prepare(), поэтому array( $wpdb, 'prepare' ). Дальше функция принимает массив с неизвестным количеством параметров и передаёт их $wpdb->prepare() (а ведь мы не знаем, сколько типов постов у нас в данный момент на сайте). И по сути мы объединяем параметр запроса с массивом типов записей функцией array_merge(). Выглядит немного запутанно, но на самом деле всё очень легко. В результате получаем SQL-запрос. Вы кстати можете на него взглянуть при помощи echo $sql;, если захотите.
  • Ну и по итогу используем $wpdb->get_var(), потому что нам надо получить единственное значение.

Миша

Впервые познакомился с WordPress в 2009 году. Организатор и спикер на конференциях WordCamp. Преподаватель в школе Нетология.

Пишите, если нужна помощь с сайтом или разработка с нуля.

Чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или войдите.

Миша Рудрастых и WordPress

Полезности из мира WordPress и жизни студии.

Мой телеграм-канал