WPDB::PREPARE() Метод безопасного выполнения SQL-запросов

# WPDB::PREPARE() │ ОБЩЕЕ │ WP 2.3.0

Метод WPDB::PREPARE() подготавливает SQL-запрос для безопасного выполнения.

## Синтаксис

Использует синтаксис, похожий на sprintf(). В строке запроса могут быть следующие заполняемые места:

- **%d** (целое число)
- **%f** (число с плавающей точкой)
- **%s** (строка)
- **%i** (идентификатор, например, названия таблиц или полей)

**Важно**: Все заполняемые места должны быть указаны без кавычек в строке запроса. Для каждого заполнителя должен быть передан соответствующий аргумент.

### Примечание
Есть одно исключение: для совместимости со старыми версиями, нумерованные или отформатированные заполнители (например, %1$s, %5s) не будут обрамляться кавычками этой функцией. Поэтому их следует передавать в соответствующих кавычках.

Литеральные проценты (%) в строке запроса должны записываться как %%.

Процентные подстановки (например, для использования в LIKE выражениях) должны передаваться через аргумент подстановки, содержащий полную строку LIKE. Эти подстановки не могут быть вставлены напрямую в строку запроса.

Также см. функцию wpdb::esc_like().

## Аргументы
Аргументы могут передаваться либо как отдельные параметры в метод, либо как единственный массив, содержащий все аргументы. Комбинация обоих способов не поддерживается.

## Примеры использования

```php
$sql = $wpdb->prepare(
    "SELECT * FROM table WHERE column = %s AND field = %d OR other_field LIKE %s",
    array( 'foo', 1337, '%bar' )
);
$sql = $wpdb->prepare(
    "SELECT DATE_FORMAT(field, '%%c') FROM table WHERE column = %s",
    'foo'
);

Возвращаемое значение

Строка или null. Возвращает подготовленную и очищенную строку запроса, если она существует.

Использование

global $wpdb;
$wpdb->prepare( $query, ...$args );
  • $query (строка) (обязательный) - Строка запроса с заполнителями в стиле sprintf().
  • ...$args (разные типы) (обязательный) - Переменные, которые должны быть подставлены в заполнители запроса, если они передаются как отдельные аргументы.

Примеры

Пример 1: Демонстрация очистки SQL-запроса

$sql = $wpdb->prepare(
    "SELECT * FROM table WHERE column = %s AND field = %d OR other_field LIKE %s",
    [ 'foo', 1337, '%bar' ]
);
$wpdb->get_results( $sql );

Пример 2: Добавление пользовательского поля к посту

В этом примере нет необходимости заботиться о экранировании кавычек и других символов, которые могут повредить запрос.

$metakey = "'crash' database";
$metavalue = "WordPress может 'сломать' базу данных, если запрос не экранирован.";

$wpdb->query( $wpdb->prepare(
    "INSERT INTO $wpdb->postmeta ( post_id, meta_key, meta_value ) VALUES ( %d, %s, %s )",
    10, $metakey, $metavalue
));

Пример 3: Передача параметров в виде массива

Этот пример аналогичен предыдущему, но здесь все переменные передаются во втором параметре в виде массива. Это может быть полезно, если мы не знаем заранее количество аргументов для передачи.

$wpdb->prepare( 
    "SELECT id FROM $wpdb->posts WHERE id > %d AND post_status = %s", 
    array( $min_id, $status )
);

Пример 4: Нельзя повторно использовать один и тот же аргумент

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

$post_date = 'post_date';
$search_string = 'search_string';

echo $wpdb->prepare(
    'SELECT * FROM table_name WHERE post_date > %1$s AND post_title LIKE %2$s OR post_content LIKE %2$s',
    $post_date,
    $search_string
);

Вместо этого вам нужно передать каждый аргумент отдельно:

echo $wpdb->prepare(
    'SELECT * FROM table_name WHERE post_date > %1$s AND post_title LIKE %2$s OR post_content LIKE %3$s',
    $post_date,
    $search_string,
    $search_string
);

Пример 5: Доступные заполнители

  • %s – строка (значение экранируется и обрамляется кавычками)
  • %d – целое число
  • %f – число с плавающей точкой
  • %% – знак процента

Для LIKE выражений используйте функцию esc_like() и указывайте заполнитель % в значении аргумента, а не внутри запроса.

$my_domain = 'example.com';

$sql = $wpdb->prepare(
    "SELECT * FROM $wpdb->options WHERE option_value LIKE %s;",
    '%' . $wpdb->esc_like( $my_domain ) . '%'
);

Пример 6: Очистка значений для условий IN

Это полезно, когда у вас есть массив значений, которые нужно передать в условии IN запроса. Количество элементов в массиве может быть разным, поэтому нужно динамически создавать заполнители:

$in_values = [ 'one', 'two' ];
$in_pholders = implode(',', array_fill(0, count($in_values), '%s'));

$sql = $wpdb->prepare( 
    "SELECT $wpdb->posts WHERE post_type = %s AND post_name IN ( $in_pholders )",
    [ 'page', ...$in_values ]
);

echo $sql;  

// SELECT wp_posts WHERE post_type = 'page' AND post_name IN ( 'one','two' )

Изменения

С версии 2.3.0 — Введен метод. С версии 5.3.0 — Формализован параметр ...$args в сигнатуре функции, второй параметр изменен с $args на ...$args. С версии 6.2.0 — Добавлен %i для идентификаторов, например, названий таблиц или полей.

public function prepare( $query, ...$args ) {
    // Код метода...
}

Это делает использование функции WPDB::PREPARE() более удобным и безопасным для разработчиков на WordPress.

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *