We upgraded our site from Drupal 6.34 to 7.34 and ran into the PDOException Issue (1003788). We have been using a patch derived from patch #204 since 7.34 and it works like a charm. However, since 7.37 supposedly committed this patch, after updating to 7.37 we got the following warning.
Warning: array_flip(): Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->load() (line 175 of /home/www/drupal-7.37/includes/entity.inc)
Cron will not run, and all page-loads (logged in or not) have this warning. We didn't have this warning when using the 7.36+1003788#204 patch solution.
Looks like this is an old bug somehow resurfaced, but I'm not sure how to fix it.
https://www.drupal.org/node/2476821
https://www.drupal.org/node/1102570
Attached is the derived patch file by our developer.
| Comment | File | Size | Author |
|---|---|---|---|
| #34 | entity.inc_.2487462.patch | 1015 bytes | dtamajon |
| #21 | array_flip_warning_in-2487462-21.patch | 1.61 KB | cilefen |
| #21 | interdiff-2487462.txt | 409 bytes | cilefen |
| #19 | array_flip_warning_in-2487462-19.patch | 1.61 KB | cilefen |
| #15 | array_flip_warning_in-2487462-15.patch | 1.5 KB | cilefen |
Comments
Comment #1
jmouse888 commentedComment #2
jmouse888 commentedComment #3
joseph.olstadlet's wake up the testbot
Comment #5
jmouse888 commentedThat patch is meant for 7.36. and it's working for me. Since 7.37 supposedly have the patch committed, applying the patch to 7.37 will definitely fail.
Comment #6
jmouse888 commentedSolved by our developer:
Here are lines 175-189 from includes/entity.inc:
Notice that array_flip($ids) is called before $this->cleanIds($ids) later in the code. By moving the cleanIds call before array_flip, you will ensure there are no non-integer ids before the array gets flipped, and the error will be prevented.
Comment #7
ladybug_3777 commentedThis seems to make sense to me and I can at least say that it made the error I saw within another module go away. Keeping an eye on this as it seems like a very simple solution....
Comment #8
David_Rothstein commentedThis is not caused by anything added in Drupal 7.37 - it's an issue caused by code that is using the entity API incorrectly (see discussion in #1102570: array_flip() [function.array-flip] issue in DrupalDefaultEntityController / entity.inc). Usually something like
entity_load('node', array(NULL))or maybeentity_load('node', 1)(rather thanentity_load('node', array(1))).The best solution is to find the offending code and fix it.
Since this indicates an actual problem with the calling code we don't necessarily want to hide the error completely... although clearly it would be better to have a more meaningful error message :)
Looking at the patch itself, a possible issue is that in moving this code up it changes the meaning of the $passed_ids variable (defined in between the old and new locations); it no longer necessarily represents the IDs that were actually passed in. Since that variable is used several other times in the function it seems like that could cause problems, but I haven't checked.
Comment #9
cilefen commentedComment #11
cilefen commentedComment #12
heddnAren't exception messages not supposed to use t()?
Comment #14
cilefen commentedWell I copied from entity_query.test...
Comment #15
cilefen commentedComment #17
heddnRTBC. This only adds error docs and tests cover the exception call. The exception used is appropriate as well i.e. InvalidArgumentException.
Comment #18
David_Rothstein commentedSo currently (before the patch), this gives me a fatal error:
But this by itself just gives me a PHP warning:
(The difference seems to have to do with whether the static cache is populated or not.)
So we probably don't want to throw an exception and break the whole page here, rather do something like trigger_error() (which should have a similar effect as a PHP warning, just with a more meaningful error message).
Also this patch won't do anything for the
entity_load('node', array(NULL))case (which anecdotally I think is more common?).Should probably be !== FALSE?
Doesn't matter if we wind up removing this anyway, but I don't think the leading slash works in PHP 5.2?
Comment #19
cilefen commentedComment #21
cilefen commentedComment #22
David_Rothstein commentedSo this sort of duplicates some of what the cleanIds() method does, but does it differently... I don't think we want the error to display when a user visits
node/1.string, rather only when it's a non-string and non-integer (such as NULL). And we definitely shouldn't unset() just because it's non-numeric because the goal of the original issue was to still support some entity types that have non-numeric IDs (apparently they exist out there).It seems to me this part could all be handled by:
1. Moving the existing cleanIds() call up (as the original patch here did) but making sure to think about the $passed_ids question I mentioned above.
2. After cleanIDs runs, compare the output to the original (with array_diff()?) and if anything was removed, and if the thing that was removed is neither a string nor integer, that's when the warning should be displayed.
3. cleanIds() itself could also be updated to do some cleaning even in the case of an entity type that allows non-numeric keys (in that case it should still remove things that are neither strings nor integers). Less important in practice, but I'm mentioning it for completeness.
I'm also surprised the tests pass with the trigger_error() - maybe that's because trigger_error does a debug-level notice by default? We might want E_USER_WARNING instead here...
Comment #23
David_Rothstein commentedIn that case I believe the tests would naturally fail, but there is some way to make them pass (I think it involves making the test use a different error handler that looks for the expected warnings rather than failing when warnings appear)... there is already test code for that somewhere I think, not sure where offhand.
So if we're going through the trouble of triggering custom messages would it make sense to put some more information in (e.g. about the $entity_type and $ids that were passed in)? Not sure if it's actually worth it - probably someone debugging this would need to do a backtrace anyway to figure out what the calling code was doing. So we can feel free to defer this question.
Comment #24
ladybug_3777 commentedI'm not sure if anyone has looked at the issue I had reported over here: https://www.drupal.org/node/2476821 I saw that someone was saying the calling code was to blame, not core... but I don't think that is quite the case in the example I have reported. Again, limited core/entity knowledge here.. but just wanted to point it out because book module comes with core and it was part of the issue I ran into.
**EDIT** actually perhaps you are already solving for that issue as well since book is guilty of the "-1" setting.
Comment #25
ladybug_3777 commentedAny update on this issue or anything I can do to help test/debug?
Comment #26
ladybug_3777 commentedI tested the patch in #21 and the debugging error is not a good solution. Perhaps that was intended to be temporary, but I can't use something like that on a production server. Especially with the use case that I outlined in my comment #24.
Comment #27
ladybug_3777 commentedFound another issue with patch #21, When I use that patch and I am also using the taxonomy deep index module, I am getting the following errors when I try and access the module listing page:
The entire module list page is broken until I roll the patch back out.
Comment #28
znerol commentedRe #24
This is correct. If the
entity_load()function is called with invalid arguments, then that is definitely a problem in the calling code.This is a bit more complicated. This is not actually a bug in the book module, but in the integration code for the book module in the contrib Entity API module.
Comment #29
ladybug_3777 commentedThanks for clearing up some more details znerol!
Comment #30
leisurman commentedMy array_flip error can from a default image in a cck field that was missing inside the cck field after a d6 to d7 upgrade
https://www.drupal.org/node/1102570#comment-10978037
Comment #31
drupaleze commentedThis worked for me:
open /includes/entity.inc
uncomment $passed_ids = !empty($ids) ? array_flip($ids) : FALSE; i.e. // $passed_ids = !empty($ids) ? array_flip($ids) : FALSE;
just before if ($this->cache && !$revision_id) {
comment $passed_ids = count($ids)>1 ? array_flip($ids) : FALSE;
save and clear cache via drush if you are having difficulty accessing the main site
Comment #32
herrwalter commentedSince I stumbled on the question with a search on google for my own problem what was causing this issue and not being able to find a solution.
I found a way to get track of this error. It is indeed a problem that is caused by the callee of the function.
I used the example of David_Rothstein to get a backtrace to through some of the custom code.
Since print_debug_backtrace gave me a memory exhaustion i'd use this:
Basicly I used a try catch in the drupal init to get the actual caller of the function without memory exhaustion en threw the Error where it came from.
Comment #33
yi_jiang commented#32 fixed my issue, it helps me nail down where the problems come from. Thanks, @herrwalter
Comment #34
dtamajon commentedHi!
In my case, the problem was the array passed via a View is Array ([] => ), so it is not empty for the empty function. I have added a check to validate that all values are set.
Comment #35
izmeez commented@dtamajon Your patch in #34 is a patch to includes/entity.inc whereas previous patches are to includes/common.inc
Can you explain if your patch is a substitute for the others or an addition?
Thanks
Comment #36
dtamajon commented@izmeez, the #34 solves the problem directly in the entity.inc, without need of modifying any other file... at least when the list comes with values like Array ([] => ).
As the final load is deletaged to the includes/entity.inc file, that fix should be in there. The given solution on #34 solves the malformed array given by some modules, like Views... and for other cases, as pointed in #8, the best solution is to find the offending code and fix it.
Comment #37
jomarocas commented#34 no working for me, make more errors with this patch
Warning: array_flip(): Can only flip STRING and INTEGER values! en DrupalDefaultEntityController->cacheGet() (línea 388 de /includes/entity.inc).Warning: array_flip(): Can only flip STRING and INTEGER values! en EntityAPIController->load() (línea 219 de /home/corcolco/public_html/sites/all/modules/contrib/entity/includes/entity.controller.inc).any solutions?
Comment #38
remyyyyyhttps://www.drupal.org/project/drupal/issues/1102570
Comment #39
a65162 commented