moneera
moneera

Reputation: 65

Notice: unserialize() [function.unserialize] in Drupal

I have this error appearing above the pages of my Drupal site:

Notice: unserialize() [function.unserialize]: Error at offset 0 of 32 bytes in C:\xampp\htdocs\irbid\includes\bootstrap.inc on line 559

What does this error mean and how can I fix it ?

Upvotes: 2

Views: 5369

Answers (5)

Vaibhav Gidde
Vaibhav Gidde

Reputation: 760

To find out the potential variables that might be causing the issue, find the one that is broken, and delete it from the database.

    SELECT name, LENGTH( value ) , value FROM variable WHERE LENGTH( value ) = "32";

    DELETE FROM variable WHERE name = "broken_variable_name";

Upvotes: 1

slevino
slevino

Reputation: 1

I received this error after (during?) a core update of drupal.
Notice: unserialize(): Error at offset 11 of 35 bytes in variable_initialize() (line936 of /var/www/vhosts/3/101684/webspace/siteapps/Drupal-12836/htdocs/includes/bootstrap.inc). I installed the variable check module (http://drupal.org/project/variablecheck) which identified the bad value:
update_notify_emails a:1:{i:0;s:26:"[email protected]";} But this is indicating that the function is expecting an array, not just a string so I couldn't just set a new value with
set_variable('the_name_of_the_malformed_variable','the_value_you_think_it_should_be'); When I checked the value table in the mysql db but the data value was a blob and I couldn't edit it. Not knowing what module set that value and what might break if I simply deleted it I decided to try "re-setting" the array to clear it out.

Google told me that "update_notify_emails" is called in the update module into modules, clicked congfigure for Update Manager and edited the value for "E-mail addresses to notify when updates are available" (mine was blank). Since the error indicated it was expecting both an int and a string I also flipped the setting on "Only security updates" so that value was passed in as well. Clicked save and error went away.

Upvotes: 0

Coomie
Coomie

Reputation: 4868

Why this error is thrown

This error is caused when an entry in Drupal's variables tables isn't in the right format. It often occurs if your host automatically installs your Drupal installation and doesn't do it right, (Like my host likes to do) or if variables haven't been created properly.


Identify the malformed variable

I made a module but you could just write this into a PHP filter input field, like a node or block (obviously, you'd need the core module "PHP Filter" turned on).

This code will output the content of the variables table, so don't do this on a production site:

drupal_set_message(db_query('SELECT name, value FROM {variable}')->fetchAllKeyed() );

Then you can just go through the list and find the one that is malformed.


How do I know which variable is malformed

Each row is in one of these formats. Each has 2 parameters separated by colons. The 2nd and 3rd fields are values and vary depending on the variable name, as long as they're in approximately one of these formats, they should be ok:

s:16:"this is a string"

s is for String. 16 is the number of characters long the string is. The third parameter is the value in double quotes.

i:10

i is for Integer. 10 is the value of the integer.

b:0

b is for booleen. 0 is the value

a:0:{}

a is for array. 0 is the number of elements and the third parameter is the array. The array may contain any of the above data types (even another array).

The variable that isn't in one of the above formats is malformed.


Fixing the malformed variable

You should be able to isolate the problem and if it's a variable like "site_name" or "site_mail" you can fix this by updating the configuration page where that variable is set (eg.Site Information). If the malformed variable isn't one you recognise:

Put a line of code like this into a module or PHP filter input.

set_variable('the_name_of_the_malformed_variable','the_value_you_think_it_should_be');

Run it once and then remove, your error should be fixed.

Follow the above at your own risk. If you have problems, leave a comment below.

Upvotes: 0

Mudassar Ali Sahil
Mudassar Ali Sahil

Reputation: 554

My issue was related to UTF-8. String shorter - character-wise (because contained UTF-8) but unserialized expecting longer one.

Solution:

/**
 * serialize utf8 values
 *
 * @param $serial_str
 *   input sting  serialize.
 * 
 * @return (array) $out 
 * serialize values
 * 
 * @author Mudassar Ali <[email protected]>
 */
function mb_unserialize($serial_str) {
    $return = '';
    $out = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $serial_str);
    $return = unserialize($out);
    if ($return === FALSE) {
        watchdog('unserialize', $out);
    } else {
        return $return;
    }
}

and

$module->info = mb_unserialize($module->info);

instead of

$module->info = unserialize($module->info);

Make sure your default character set on the server to be UTF8, and default collation to be utf8_general_ci. This is a setting in mysql.ini. Here's the nuclear option.

[mysqld]
default-character-set = utf8
character-set-server = utf8
collation-server = utf8_unicode_ci
init-connect = 'SET NAMES utf8'
[client]
default-character-set = utf8
[mysql]
default-character-set = utf8
[mysqldump]
default-character-set = utf8

and also make sure your DB is also

ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_general_ci;
ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

Upvotes: 2

roychri
roychri

Reputation: 2936

This is caused by a corrupt entry in the variables table. The value of this table is a serialized php value.

See those for more information on what a serialize value is:

Basically, if one of the value was changed by hand, it can cause something like this.

For example, the default value of the Anonymous variable is:

+-----------+------------------+
| name      | value            |
+-----------+------------------+
| anonymous | s:9:"Anonymous"; |
+-----------+------------------+

If you change the value to s:9:"Some other value"; then this will cause a problem. The first character is the type of value. The value s means STRING. Then the colon followed by a number indicate a length. In this case, the word Anonymous is exactly 9 characters. But there is more than 9 characters for Some other value. There are 16 characters in that value, so the correct way would be s:16:"Some other value";.

If someone put the value not serialized (without the s:9:"";) then it would also cause this problem.

I had this very problem in the past. I added some debug code to find out what variable was causing this. I added something like this:

$value = unserialize($variable->value);
if ($value === FALSE) {
    watchdog('unserialize', $variable->name);
}

I put this code right before the line causing the error and then I generated the error one more time and I went to the "Recent Log Entries" in Drupal admin http://yoursite.com/admin/reports/dblog and filtered by the type unserialize.

Once I had the name of the variable, I would connect to the database and perform this query:

SELECT * FROM variable WHERE name='name-goes-here';

and I put the name that I found in the logs. I look at the value and figure out why it is causing this error and then fix the value.

I hope this helps.

Upvotes: 3

Related Questions