Error when clearing cache and on update.php
Mike_Waters - October 25, 2008 - 05:01
| Project: | Cache Router |
| Version: | 6.x-1.x-dev |
| Component: | Code |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | closed |
Jump to:
Description
When I clear the cache my cache, I recv the following error (several instances of it):
Invalid argument supplied for foreach() in /var/www/drupal-6/sites/all/modules/cacherouter/engines/apc.php on line 121That line resides in the delete() function (which makes sense).
function delete($key) {
// Remove from static array cache.
parent::delete($key);
if (substr($key, -1, 1) == '*') {
$key = substr($key, 0, strlen($key) - 1);
$lookup = apc_fetch($this->lookup);
foreach ($lookup as $k => $v) { <--- line 121
if (substr($k, 0, strlen($key) - 1)) {
apc_delete($k);
unset($lookup[$k]);
}
}(IIRC)I also had this problem with xcache installed (obviously it would say xcache.php, but I removed xcache for other reasons so I cannot say for sure).
I haven't done any real debugging, but with some print_r()'s to syslog it looks like apc_fetch is sometimes returning an empty array ('Array()'). In my case, the original $key/s passed to that function that caused apc_fetch to return an empty array were 'links:devel:*', 'links:navigation:*', and '*'.
I do not know how to go any further w/o a debugger (like, who is the caller, did those $keys ever get apc_store'd, etc..).
I am using Drupal 6.6/debian lenny kernel 2.6.24-19-xen x86_64/apache2/php5+suhoisin patch/APC-3.0.19 on a VPS, and am using the latest cacherouter files from CVS.
Thanks,
Mike Waters

#1
SOLUTION: (?)
The code doesn't check for a FALSE return value of apc_fetch(), so $lookup is sometimes FALSE/0. When php tries to parse 0 into an associative array, the error handler is invoked.
I don't know how to create a patch, but you want to replace
$lookup = apc_fetch($this->lookup);
foreach ($lookup as $k => $v) {
if (substr($k, 0, strlen($key) - 1)) {
apc_delete($k);
unset($lookup[$k]);
}
}
with
$lookup = apc_fetch($this->lookup);
if ($lookup != FALSE) {
foreach ($lookup as $k => $v) {
if (substr($k, 0, strlen($key) - 1)) {
apc_delete($k);
unset($lookup[$k]);
}
}
}
at line 120 of engines/apc.php.
I don't know much about the apc engine, so I can't say whether or not it is correct for apc_fetch() to ever return FALSE, and so can't say that this is a valid solution.
Wish I could help more, but I am debugging a remote server (across the country) so I only have what source code xdebug sends to my IDE over the wire (there's no 'step backward', and if I 'step into'd through the entire drupal bootstrap my F11 key would have blood on it ;).
Thanks for the great module.
-Mike Waters
#2
Can you tell me what version you are using? In the latest version, before I run over the lookup table, I check if it is "empty" with the php empty() function. Per the documentation on php.net:
Return Values
Returns FALSE if var has a non-empty and non-zero value.
The following things are considered to be empty:
* "" (an empty string)
* 0 (0 as an integer)
* "0" (0 as a string)
* NULL
* FALSE
* array() (an empty array)
* var $var; (a variable declared, but without a value in a class)
You can see that in apc.php on line 158.
<?php
function flush() {
$this->lock();
// Get lookup table to be able to keep track of bins
$lookup = apc_fetch('lookup_' . $this->name);
// If the lookup table is empty, remove lock and return
if (empty($lookup)) {
$this->unlock();
return TRUE;
}
// Cycle through keys and remove each entry from the cache
foreach ($lookup as $k => $v) {
if (apc_delete($k)) {
unset($lookup[$k]);
}
}
// Resave the lookup table (even on failure)
apc_store('lookup_' . $this->name, $lookup);
// Remove lock
$this->unlock();
return TRUE;
}
?>
#3
I am using the version from CVS as of 10/25/08. My copy of apc.php is identical to what you've posted.
Why would cache clearing even hit the delete() function? It looks like flush() calls apc_delete() directly.
Something I probably should have noted is that this error was the result of using the Devel modules 'Clear cache' function. It did not occur to me that Devel might use a separate cache clearing implementation; does it?.
(Note that I am not saying that Site Configuration->Performance->Clear Cache *didn't* cause the error, because I don't use it and so don't know.)
EDIT: migrating to the cvs version caused the apc_fix_lock patch to revert. Could this have anything to do with it?
Thanks,
Mike Waters
#4
i got the same error using apc with current release version and d6.10
i had cache browser and cache_path installed too
#5
Same problem here
#6
same problem
#7
And here too!
Edit: Not getting this anymore when updated to latest dev.
#8
It seems to me it happens when the cache table is clear or fresh.
I don't get that when i clear the cache here and there but when i install modules or remove and
then i clear the cache by hand 1 or 2 times, then it happens.
Because the error msg is in a forearch() it smells a bit like an empty var run.
#9
subscribing
#10
same problem
#11
Marking #494878: repeatin, growing list of "Invalid argument supplied for foreach()" warnings when using APC backend as duplicate.
#12
The same error on update.php
Is this module is abandoned?
#13
This is fixed now.
#14
Automatically closed -- issue fixed for 2 weeks with no activity.