0

I have the following serialized array stored in a MySQL longblob data field:

a:1:{s:10:"attributes";a:1:{s:13:"Ticket Holder";a:1:{i:0;s:8:"Joe Blow";}}}

In PHP, when I query the field, unserialize it, and print it out, the following empty array is printed:

Array
(
)

This is the table create statement:

CREATE TABLE `order` (
  `state` varchar(255) CHARACTER SET ascii DEFAULT NULL,
  `data` longblob,
  `created` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
user320691
  • 185
  • 3
  • 11

3 Answers3

1

Your serialized data is invalid. You must never mainpulate serialized data manually.

Strings are serialized as:

s:<i>:"<s>";

where <i> is an integer representing the string length of <s>, and <s> is the string value.

So in this case valid data is :

a:1:{s:10:"attributes";a:1:{s:13:"Ticket Holder";a:1:{i:0;s:8:"Joe Blow";}}}

Joe Blow string length is 8 but in your serialized strings is defined 13.

See : Structure of a Serialized PHP string

0

Use base64_encode

The core problem comes from the binary encoding done by the database and the extra bytes it adds to the value stored. This "corrupts" the data that is being fetched from the database and causes unserialize to fail. To help mitigate this problem, you can use base64_encode and base64_decode which will allow you to insert and extract the data painlessly.

// data is encoded before insert
$dataToInsert = base64_encode(serialize($myArray));

// decode the data before unserializing it
$dataToRead = unserialize(base64_decode($longblob));
William Perron
  • 1,288
  • 13
  • 18
  • @bishop the problem comes from the encoding done by the `longblob` type, which makes the corrupts the data, which in turn causes `unserialize` to fail. Using `base64_encode` and `base64_decode` prevents this – William Perron Aug 24 '17 at 19:59
  • I tried this and it doesn't store anything but a:0:{}. When not using base64 encoding, it stores the serialized array correctly. I just haven't been able to retrieve it from a longblob field. Thanks William. – user320691 Aug 24 '17 at 20:05
  • 1
    If the OP is inserting data into his database without properly espcaping it, then base64 encoding the serialized PHP might fix the immediate problem but this is not applicable to all the data stored in a database - and implies that the code is vulnerable to SQL injection. Merely using a longblob does not corrupt data. – symcbean Aug 24 '17 at 20:21
0

Converting the column to UTF8 in the SELECT statement and then unserializing it.

CONVERT (data USING utf8)

I'm not sure why this is necessary. I'm guessing it has something to do with the utf8mb4_general_ci collation.

Thank you for all of your help guys!

user320691
  • 185
  • 3
  • 11