Подтвердить что ты не робот

Unserialize через запрос на уровне базы данных

У меня есть значение столбца, хранящееся в базе данных, как:

а: 2: {я: 0; s: 2: "США"; I: 1, S: 2: "19";}

Я хочу неэтериализовать его во время запроса mysql, а не использовать функцию php unserialize после извлечения данных. Я хочу сделать это таким образом, чтобы я мог присоединиться к другой таблице с сериализованным значением. Это позволит избежать выполнения отдельного запроса после его неэтериализации с помощью php, только для объединенных данных.

4b9b3361

Ответ 1

MySQL не знает, что такое сериализация PHP. Вы не можете этого сделать.

Ответ 2

Вы можете использовать SUBSTRING_INDEX

Например, если у вас есть запись вроде этого:

a:5:{s:9:"invoiceid";s:1:"8";s:8:"balance";i:5;s:14:"broughtforward";i:3;s:6:"userid";s:5:"13908";s:10:"customerid";s:1:"3";}

Вы можете использовать следующую инструкцию SELECT:

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',1),':',-1) AS fieldname1,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',2),':',-1) AS fieldvalue1,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',3),':',-1) AS fieldname2,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',4),':',-1) AS fieldvalue2,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',5),':',-1) AS fieldname3,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',6),':',-1) AS fieldvalue3,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',7),':',-1) AS fieldname4,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',8),':',-1) AS fieldvalue4,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',9),':',-1) AS fieldname5,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',10),':',-1) AS fieldvalue5
FROM table;

Отметьте это для справки: Как нециализировать данные с помощью mysql без использования php

Ответ 3

Как насчет этого? Это пользовательская функция MySQL с встроенным php:

CREATE FUNCTION unserialize_php RETURNS STRING SONAME 'unserialize_php.so';

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

SELECT unserialize_php('O:8:"stdClass":2:{s:1:"a";s:4:"aaaa";s:1:"b";s:4:"bbbb";}', "$obj->a") 
AS 'unserialized';
+--------------+
| unserialized |
+--------------+
| aaaa         |
+--------------+
1 row in set (0.00 sec)
drop function unserialize_php;

Источник: https://github.com/junamai2000/mysql_unserialize_php

Вы можете создать пользовательскую функцию MySQL и вызвать zend_eval_string внутри функции, чтобы вы могли вернуть PHP-переменные в результат MySQL. Я реализовал образец программы. Вы можете попробовать.

Ответ 4

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

Наилучшим подходом является нормализованная структура таблицы (разные поля или таблицы).

Следующий подход заключается в сохранении данных в виде строки с разделителями (например: 0,US,1,19). Затем вы можете использовать MySQL SUBSTRING() или использовать стандартные механизмы сериализации, такие как кодирование JSON.

Ответ 6

Как упоминалось в kchteam, для этой цели удобна библиотека MySQLToolBox с использованием пользовательской функции MySQL getPhpSerializedArrayValueByKey, доступной здесь https://github.com/KredytyChwilowki/MySQLToolBox/blob/master/getPhpSerializedArrayValueByKey.sql.

После добавления этой функции вы можете получить любое значение в сериализованном массиве, используя следующий синтаксис,

SELECT getPhpSerializedArrayValueByKey(column_name, 'array_key') AS deseializedArrayValue FROM table_name

Данный массив может быть неэтериализован как

SELECT getPhpSerializedArrayValueByKey('a:2:{i:0;s:2:"US";i:1;s:2:"19";}
', 'key_to_retrieve') AS key_to_retrieve

Ответ 7

Для сериализованных массивов Вы можете использовать функцию getPhpSerializedArrayValueByKey из здесь