I'm working on (yet another!) sort order patch for the taxonomy module, and I want to store the sort order in a column created for this purpose in term_data.
The sort order is in an array, and I decided to store it in a VARCHAR column called sortorder.

The ouput from _taxonomy_prepare_update looks like this:

name = 'RSP', description = 'Tout sur les SA \"Refonte des Systèmes de Paiement\" et autres traces', weight = '0', sortorder = 'a:2:{i:0;s:3:\"crd\";i:1;s:3:\"cra\";}'

Yet when I look at the contents of the field in PHPMyAdmin, the curly brackets have been stripped out of the array, so of course when I unserialize it, the data is no longer recognised as an array.

Can anybody tell me why this is happening? Is Drupal stripping out the curly brackets?

Comments

fronbow’s picture

It looks like it's something to do with the function db_prefix_tables, which is called from within db_query.

db_prefix_tables goes thru' your $sql to look for anything within braces, then changes it so that whatever was within braces gets the database prefix.

If you do something like

$res = _db_query($sql);

but make sure you're using the actual table name (not enclosed in braces, as it won't work!), then you can save serialized arrays in the db.

(the _db_query function is in database.mysql.inc, and I'm using 4.6 - not sure whether it's like this in 4.7?)

HTH

fronbow’s picture

Use db_query in the following form (like printf or sprintf):

$sql = "UPDATE {mytable} SET serial_array='%s' WHERE uid = %d";
$res = db_query($sql, serialize($my_array), $user->uid);

Using it this way, the braces get replaced correctly!

Cheers

AlexisWilke’s picture

I ran in this problem today...

      'this_serialized_field' => array(
        'description' => 'We want an empty array as the default.',
        'type' => 'text',
        'not null' => TRUE,
        'default' => 'a:0:{}',
      ),

And in that case, I cannot run db_query() myself...

That looks like a Core bug.

Thank you.

pmunch’s picture

I would use 'serialize' => TRUE in shema field definition, should look like this in your example :

      'this_serialized_field' => array(
        'description' => 'We want an empty array as the default.',
        'type' => 'text',
        'not null' => TRUE,
        'serialize' => TRUE,
      ),

and then I just pass an empty (unserialized) array thru $data array sent to drupal_write_record() function :

		$data = array(
			...
			'this_serialized_field' => array(),
			...
		);
		drupal_write_record('my_table_name', $data);

Just tried something similiar a few days ago and it works like a charm.