After just having spent two days trying to get to the bottom of a particularly weird bug I thought I'd post up what my question would have been — if I had taken the time to write it — and then post my answer also, just in the hope of helping other people avoid the headache.
PHP Fatal error: Class name must be a valid object or a string in /includes/common.inc on line 7522
This was the starting point. I got this error — along with a typically pleasant WSOD — after creating a new install of my site on a localhost. The strange thing about it was that I had almost exactly the same setup working on another machine. The code was served by GitHub and so was identical, the database was a direct dump from the original site, php was configured as expected and versions were only a 0.0.5 out (5.3.15 and 5.3.10), both Drupals were version 7.9 ... everything should be working.
What made this weirder still was the fact the site would work directly after a drush rr
, however, it would break immediately after a drush cc all
, or on refresh.
This led my collegue and I traipsing in circles, debugging common.inc
and modules.inc
trying to find a clue as to what was going on. What we discovered was that after the reset registry the correct entity_info
array was built, but after the clear cache, we only got part of the full entity_info
array.
Investigating further we found rather ridiculously that the following code — taken from module.inc — could not find particular functions in particular module files that we knew to exist.
foreach ($list as $module) {
$include_file = isset($hook_info[$hook]['group']) &&
module_load_include(
'inc', $module, $module . '.' . $hook_info[$hook]['group']
);
// Since module_hook() may needlessly try to load the include file again,
// function_exists() is used directly here.
if (function_exists($module . '_' . $hook)) {
$implementations[$hook][$module] = $include_file ? $hook_info[$hook]['group'] : FALSE;
}
}
This could only mean that at the point this code was being executed certain files that should have been included by now, weren't. What made this even more baffling was that if we called the following outside of any of the caching code, it returned the correct entity_info
array.
$entity_info = module_invoke_all('entity_info');
This meant that there wasn't anything wrong with the files, it just seemed to be the caching system. To cut a rather long story short, because we didn't have anything modifying the core drupal caching system, we decided to resort to the good old trial and error disable all modules and enable one by one. Great.
This took some time but we managed to whittle everything down to one bespoke module, which we then trial and errored function by function call. Until we got the culprit:
/**
* Helper function to redirect an actual submit to the ajax handler
*/
function microsites__admin_settings_submit(&$form, &$form_state) {
return microsites__admin_settings__ajax_button(&$form, &$form_state);
}
So I guess my question — apart from being, what can cause PHP Fatal error: Class name must be a valid object or a string
error — would be what out of the above function could cause such a disastrous error, and in such a weird manner?