Invalid arguments to theme.inc when swapping Drupal databases
Like many small consulting shops, we often work with developers scattered around the world. Recently a Drupal developer delivered a custom theme to us, with a SQL snapshot of the database he had been using to work on it. We installed the new database and eagerly tried out the new theme, only to be met with a slew of error messages of this format:
# warning: Invalid argument supplied for foreach() in /home/jon/Workspaces/php/secretprojectx/includes/theme.inc on line 463. # warning: Invalid argument supplied for foreach() in /home/jon/Workspaces/php/secretprojectx/includes/theme.inc on line 468.
What was the cause?
(Skip to the last paragraph if you only want the solution.)
Drupal is open-source, of course, so we fired up our debugger and set a breakpoint at theme.inc to take a look. The relevant bit is from the list_themes method:
foreach ($themes as $theme) { foreach ($theme->info['stylesheets'] as $media => $stylesheets) { foreach ($stylesheets as $stylesheet => $path) { $theme->stylesheets[$media][$stylesheet] = $path; } } foreach ($theme->info['scripts'] as $script => $path) { if (file_exists($path)) { $theme->scripts[$script] = $path; } } ...
This function processes theme data from the system table in Drupal database. The info column contains a serialized PHP hash of the theme's specific settings; when you navigate to admin/build/themes in your Drupal site and configure, you're accessing the variables that are found in that PHP has. For example, for the Zen starter kit theme, here's what was in that field in the table:
a:15:{s:4:"name";s:26:"Zen Themer’s Starter
Kit";s:11:"description";s:94:"Read the online docs on how to create a
sub-theme.";s:10:"screenshot";s:50:"sites/default/themes/zen/STARTERKIT
/screenshot.png";s:4:"core";s:3:"6.x";s:10:"base theme";
...
So by the time we get to line 463, $theme is supposed to have been fully populated from that database table. But the info instance variable was FALSE instead of containing the expected associative array. Thus, accessing it as a hash gives the illegal argument exception. But why was it illegal?
The problem was in the character set used in the SQL dump file. Note about thirty characters in the PHP hash shown above: there's a non-ASCII character in "Zen Themer's Starter Kit," instead of the apostrophe. PHP's unserialize method can't process the non-ASCII characters from the database, so FALSE was returned.
Happily for us the solution was trivial: we just visited /admin/build/themes/, and pushed "Save Configuration," which re-wrote the themes' associative hashes in pure ASCII. Poof, the warnings were gone.
Comments
That was very helpful
Got this weird error and was goin through various sites for the solutions and found my answer here.well explanation of the problem and simple technique to counter it..Thank you
Thanks this helped me a lot.
Thanks this helped me a lot. The charset problem arised when sending the whole sql dump to another guy - probably a mac/windows compatibility issue. I solved it uploading the sql dump myself staying on same OS.
Thanks for this information.
Thanks for this information. You probably saved my life, considering the heart attack I was having when my client called me to tell me that the giant site I made for them had died. The one thing I can't figure out was how the illegal character got in there in the first place -- in my case, nobody touched the database (unless my host did it behind my back).
Thanks
Thanks for this.