Получение размера массива из сериализованных данных

Вопрос или проблема

У меня есть пользовательское поле в метаданных пользователя WordPress, которое хранит данные в сериализованном массиве. Я хочу получить количество массивов. Например: a:2:{blah blah}


введите описание изображения здесь
Скриншот моей таблицы


Я попробовал следующий код, но он не работает. Он должен выводить 2

$number = $wpdb->get_var("
    SELECT count(*)
    FROM wp_usermeta
    WHERE meta_key='bookmark_posts' AND meta_value LIKE '%".get_current_user_id()."%'
");
if ( $number !== '' ) {
    echo 'Всего закладок (' . $number . ')';
}

У меня есть журнал ошибок. (john_newsite – это имя базы данных)

Ошибка базы данных WordPress Таблица 'john_newsite.wp_usermeta' не существует для запроса SELECT count(*) FROM wp_usermeta WHERE meta_key='bookmark_posts'

правка:

Я только что попробовал следующий код. Он работает, но считает общее количество закладок для всех пользователей. Как мне ограничить результат текущим вошедшим пользователем?

$meta_key='bookmark_posts';
$number = $wpdb->get_var( $wpdb->prepare( 
    "SELECT sum(meta_value) 
    FROM $wpdb->postmeta 
    WHERE meta_key = %s", 
    $meta_key
) );
echo "{$number}";

Ваш запрос неправильный, потому что вы ищете user_id в столбце meta_value, а не в столбце user_id.
В этом случае я не вижу смысла создавать пользовательский запрос только для этого, вот как вы можете это сделать, используя встроенную функцию get_user_meta

$data = get_user_meta( get_current_user_id(), 'bookmark_posts' );
$number = count($data);
if( $number > 0 ){
    echo 'Всего закладок ('.$number.')';
}

Ну, ваш SQL выбирает что-то другое, чем вы хотите, я думаю. Он считает строки в вашей таблице, а вам нужно выбрать одну строку и вернуть её значение.

Вам нужно выбрать (с помощью вашего SQL) строку, которая вас интересует, чем-то подобным:

"SELECT count(*) FROM wp_usermeta WHERE meta_key='bookmark_posts' AND meta_value="". get_current_user_id.""

Затем вам нужно десериализовать этот массив и проверить количество его элементов.

PS. Я бы не использовал LIKE в этом запросе. Это медленнее. Другой причиной является то, что он вернёт неверные результаты (т.е. когда current_user_id равен 1, ваш запрос вернёт данные для пользователя 10, 11, 21 и так далее…)

Ответ или решение

При работе с сериализованными данными в пользовательских метах WordPress, одна из частых задач – извлечение размера массива. В вашем случае, вам нужно получить количество элементов в массиве, который хранится в пользовательском метаполе. Рассмотрим, как это сделать правильно и эффективно.

Шаг 1: Понимание структуры сериализованных данных

Сериализованные массивы в WordPress имеют формат, например, a:2:{...}, где a:2 указывает, что это массив из двух элементов. Это значит, что вам нужно извлечь значение из базы данных и потом десериализовать его.

Шаг 2: Получение данных из базы

Для извлечения данных вам не нужно выполнять полноценный SQL-запрос. Вместо этого можно использовать встроенную функцию get_user_meta, которая предназначена для работы с пользовательскими метами. Этот метод не только более безопасен, но и проще в использовании. Используем следующий код:

$user_id = get_current_user_id(); // Получаем ID текущего пользователя
$bookmarks = get_user_meta($user_id, 'bookmark_posts', true); // Извлекаем мета значение

// Десериализуем массив
if (!empty($bookmarks)) {
    $bookmarks_array = unserialize($bookmarks); // Десериализация данных
    $number = is_array($bookmarks_array) ? count($bookmarks_array) : 0; // Подсчитываем количество элементов в массиве
} else {
    $number = 0; // Если данные пустые, количество элементов 0
}

echo "Всего закладок ($number)";

Шаг 3: Обработка возможных ошибок

Обратите внимание на следующие моменты:

  1. Проверка на empty: Перед десериализацией данных важно убедиться, что значение не пустое. Это предотвратит ошибки, связанные с попыткой десериализации null или пустой строки.
  2. Проверка на массив: После десериализации обязательно проверьте, что результат действительно является массивом, прежде чем использовать функцию count().
  3. Отказ от прямых SQL-запросов: Использование абстрактного слоя базы данных WordPress предоставляет большую безопасность, особенно в плане SQL-инъекций.

Проблемы с предыдущими запросами

Если вы использовали прямые запросы к базе данных, такие как SELECT count(*) FROM wp_usermeta, это может вызвать множество проблем:

  • Неправильная логика: Вы могли пытаться найти user_id в meta_value, что некорректно. Вместо этого стоит использовать user_id для фильтрации записей.
  • Ошибки в названиях таблиц: Ошибка, о которой сообщается в вашем журнале, указывает на неправильное имя таблицы. Убедитесь, что вы используете правильные префиксы при обращении к таблицам.

Заключение

Проверка количества закладок пользователя – это задача, которая требует аккуратности в работе с данными. Вместо написания сложных SQL-запросов, лучше полагаться на встроенные функции WordPress, которые значительно упрощают код и повышают его безопасность. Воспользуйтесь кодом, приведённым выше, чтобы корректно извлечь данные и определить их количество.

Оцените материал
Добавить комментарий

Капча загружается...