Problem/Motivation
When using Field Collections with the Entity API, its frequently reported that unexplained, hard to debug, PHP warnings related to array_flip creep into the site. This is most often the case after a site upgrade from Drupal 6 to 7, content import from another site, or database sync.
An example of the warnings that result are:
Warning : array_flip(): Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->load() (line 178 of /includes/entity.inc).
Proposed resolution
Whenever the Entity API attempts to use the PHP builtin array_flip()
, on a variable or parameter of mixed or undefined type, it should ensure:
- That the variable or parameter being flipped is an array.
- That the values in the array can be used as array keys (ie. are not NULL values)
Remaining tasks
- Tests: Pass non-array values into methods that accept mixed type parameters
- Tests: Pass empty values into methods that accept mixed type parameters
- Tests: Pass NULL values into methods that accept mixed type parameters
Original report by Emerya.thomas
Warning : array_flip(): Can only flip STRING and INTEGER values! dans DrupalDefaultEntityController->load() (ligne 178/includes/entity.inc).
Only happen with field collection load, have got last release entity & field collection.
I try to look, but I don't understand, field collection send always an array... I dunno if after field collection need to load other entity wich can make this warning.
Comment | File | Size | Author |
---|---|---|---|
#63 | CORE-entity.inc-hardening-1803048-63.patch | 1.41 KB | Anybody |
#49 | entity-1803048-49.patch | 1.39 KB | ironsizide |
#46 | entity-1803048-46.patch | 1.3 KB | themic8 |
#16 | interdiff-warning_array_flip-1803048-8-16.txt | 774 bytes | chOP |
#16 | warning_array_flip-1803048-16.patch | 4.22 KB | chOP |
|
Comments
Comment #1
rsvelko CreditAttribution: rsvelko commentedhttp://stackoverflow.com/questions/4798047/array-flipcan-only-flip-strin...
Comment #2
Musa.thomasI know this issue like at said in my previous post I look all variable wich is send to load, and all is array....
Comment #3
kenorb CreditAttribution: kenorb commented#1102570: array_flip() [function.array-flip] issue in DrupalDefaultEntityController / entity.inc
Comment #4
ishwar CreditAttribution: ishwar commentedComment #5
mskicker CreditAttribution: mskicker commentedhi
i active devel and add
foreach($ids as $key=>$value){
if(is_array($value)){
dpm( debug_backtrace() );
}
}
to line 176
this show me what is problem source
Comment #6
prince_kr CreditAttribution: prince_kr at Zyxware Technologies commentedHi, I too had come across this similar issue.
Array only flips integer and string values but it is trying to flip keys with NULL values.
I just made the below changes as mentioned in the patch to get this done. The solution is to filter out NULL values. Hope this helps.
Comment #7
chOP CreditAttribution: chOP at Technocrat commentedComment #8
chOP CreditAttribution: chOP at Technocrat commentedComment #9
chOP CreditAttribution: chOP at Technocrat commentedThis patch has been rolled against the correct Entity API branch and attempts to prevent any future
array_flip()
warnings, be they caused by bad configuration, imported content, or poorly implemented custom code.While I am no fan of Drupal silently failing when things go bad, Drupal modules should be a little defensive in their own use of loosely typed variables and parameters.
Comment #10
chOP CreditAttribution: chOP at Technocrat commentedComment #11
NancyDruThis takes care of it for me:
That last line exists currently (175) in common/entity.inc.
Comment #12
chOP CreditAttribution: chOP at Technocrat commented@nancydru glad to hear it,
Unfortunately the lines of code you've pointed out don't address it for me. I'm also not alone, given the number of posts on this Warning that I've seen all over the Web. Some of those posts are old, I admit, but many are not.
Here's the thing, wherever Entity API uses the PHP builtin function
array_flip()
, it needs to first check that all the array values are appropriate for use as array keys. It was probably fair enough to assume that if Drupal was properly configured, and other installed modules were playing well with Drupal, that the array values would be strings. The problem though arises when that assumption proves false.Now, you may well say, that if the configuration of Drupal is broken, or a module isn't playing by the rules, then Entity API should throw an error. Okay, then fine, throw an error, but can we make it meaningful?
Current Behaviour
When an Entity object (ie.
StdClass
) has badly structured field data, a cryptic warning, that tells us nothing, is shown to a developer or visitor.Patch Behaviour
The patch I've provided isn't perfect. It's a patch on the problem that exists out here in the real world.
array_flip()
.This patch though could be improved, to do more than the minimum of not reporting cryptic warnings.
Suggested improvement
If an Entity object (ie.
StdClass
) has a field data property with an incorrect or unexpected array structure:Comment #13
joseph.olstadTried patch 8 , it didn't have any effect for me. Could be in my case caused by a different module.
Comment #14
petar.kolicov CreditAttribution: petar.kolicov commentedThis code
if (!empty($this->entityCache) && is_array($ids) && $ids !== array()) {
$entities = $ids ? array_intersect_key($this->entityCache, array_flip(array_filter($ids))) : $this->entityCache;
from patch 8 brooking "Entity Reference View Widget Checkbox" in my DB view. I created patch only with $passed_ids changes.
Comment #15
joseph.olstadpatch 14 had no effect for me either in my configuration. I'd have to do a backtrace and really dig in to find out what is causing this in my case. If it helps for you, great.
Comment #16
chOP CreditAttribution: chOP at Deloitte Digital, Technocrat commented@petarkolicov :
I see the problem you had with Entity Reference View Widget checkbox. It seems that
DrupalDefaultEntityController::cacheGet()
will need to still work if the ids passed are not an array. It seems to return all cached results in that case.It's a bit odd in that
DrupalDefaultEntityController::cacheGet()
seems to work differently toDrupalDefaultEntityController::cacheGetByName()
. In cacheGet, an empty non-array $ids parameter should return results. In cacheGetByName, an empty non-array $names parameter should return no results.I've applied a fix in a new patch that should address the issue you found when used with Entity Reference View Widget. Can you please test it and let us know how you go?
Comment #17
chOP CreditAttribution: chOP at Deloitte Digital, Technocrat commented@joseph.olstad said:
@joseph.olstad could you show us the error output you were trying to resolve? I'm curious to see if there are any other places where PHP Warnings are generated by Entity API code.
Comment #18
giorgio79 CreditAttribution: giorgio79 commentedI am getting this error as well I believe.
I am loading a VBO View in rules, and fetching entities in a loop.
For every entity I am getting this error message
Comment #19
giorgio79 CreditAttribution: giorgio79 commentedWow, looks like a few hundred sites are affected https://www.google.hu/search?safe=off&q=%22line+388%22+of+%2Fpublic_html...
Comment #20
ericclaeren CreditAttribution: ericclaeren commentedPatch #16 seems to work.
Comment #21
kenorb CreditAttribution: kenorb commentedComment #22
Chris CharltonMy watchdog has tons of these notices. :(
Patch applied fine for me.
Comment #23
Fabito CreditAttribution: Fabito commentedHi, I tested patch #16 and i've always error :
I work with Drupal 7.56 (+ commerce module), Entity 7.18 (not -dev).
After install -dev version, errors always here.
I don't know how to fix it :/
Comment #24
joseph.olstad@Fabito, here are some debugging tips for you to help you capitalize on this opportunity.
DEBUGGING TIPS:
When you need a backtrace
Here is some backtrace code that might come in handy. The file should be created in the web root.
Another approach if you want it in your browser:
Here is an example of some output:
Keeping a log
Using a function like this, you can keep appending a log. The log is best viewed using gedit on Linux or Notepad++ on windows where you will be prompted automatically to reload. When you're wanting to see a fresh log, then just select-all, delete and save.
the file saythis.txt in this case would be written to the root of your drupal folder containing the contents of
$what_im_sayin
.Comment #25
chrisroane CreditAttribution: chrisroane commentedI confirmed Patch #16 worked for my case.
Comment #26
remyyyyythank you for the patch
Comment #27
biarr CreditAttribution: biarr commentedPatch #16 is working. Thanks!
Comment #28
Majdi CreditAttribution: Majdi as a volunteer commentedPatch #16 is working. Thanks!
Comment #29
ron_s CreditAttribution: ron_s commentedJust wanted to offer what happened in our situation in case anyone else has a similar issue. We started getting a few
array_flip
errors specifically on the/user
page for a logged-in user. If the same user visited any/user/<uid>
page (including their own), no error messages.We tried applying the patch in #16, and got even more
array_flip
errors as mentioned by Fabito in comment #23.After an exhaustive search, we realized a Profile2 profile type had recently been removed from user profiles, and we still had an old context in Panels referencing it.
So for anyone using Panels, it might be worthwhile to check if there are any associated contexts that are no longer valid, but haven't been removed.
Comment #30
cmseasy CreditAttribution: cmseasy commentedWith patch #16, on the page /user I still have:
Warning: array_flip(): Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->cacheGet() (line 389 of /home/path_to/public_html/drupal-7/includes/entity.inc).
This is only as anonymous user, I dont't have this in my logs as a logged in user.
Sorry, I don't have greath php skills, I can patch and test.
Comment #31
rivimeyFYI We ran into this issue with a node_export module run involving entity fields. The patch in #16 does help (in that the number of warnings is reduced) but there is at least one more place where I suspect the same fix needs to be made.
Status: RTBC but could be improved further.
Comment #32
lubwn CreditAttribution: lubwn commentedGetting array_flip() errors even after applying patch from #16. However, those are only for anonymous users. Not sure how or where should I place the code with debug_backtrace() to make it to work. I highly suspect my errors are from views printing out products (Drupal Commerce site) - because they are printed for each one product present on site every time. I would rather ignore the warning because it has no effect on site functionality, but I suspect watchdog table will get incredible big if I ignore it by time.
Comment #33
narkoff CreditAttribution: narkoff commentedReceived this error when returning AJAX feed from Selective Tweets module. Patch 16 fixed issue.
Comment #34
murali97 CreditAttribution: murali97 commentedHi Guys, Is this patch working for php 7.2
Comment #35
martinhansen CreditAttribution: martinhansen at PeaceWorks Technology Solutions commentedIn case this helps anyone: in my case, #23 was being caused by having custom php in a block calling
arg(1)
when that index didn't exist.Comment #36
memcinto CreditAttribution: memcinto as a volunteer commentedIn my case (Drupal 7.59), getting these errors when an anonymous user hits /user or /user/login, I was able to successfully patch /includes/entity.inc by copying some of the code from patch #16.
I'm not really competent to either create a patch from this or check if the code I created is secure, so I welcome feedback.
The file I patched is [docroot]/includes/entity.inc.
Here's what I did: line 175, changed this line:
$passed_ids = !empty($ids) ? array_flip($ids) : FALSE;
to this:
$passed_ids = is_array($ids) && !empty($ids) ? array_flip(array_filter($ids)) : FALSE;
and on line 388, changed this line:
$entities += array_intersect_key($this->entityCache, array_flip($ids));
to this:
$entities += array_intersect_key($this->entityCache, array_flip(array_filter((array) $ids)));
That seems to have removed the errors for me.
I hope this helps others.
Comment #37
glynster CreditAttribution: glynster commented#16 interdiff-warning_array_flip-1803048-8-16.txt resolved the problem +1
Comment #38
fonant CreditAttribution: fonant at Fonant Ltd commentedChanges as per #36 (thanks memcinto!) to
<drupal>/includes/entity.inc
worked for me.My situation was interaction between an empty entity_reference field and Rules loading.
Comment #39
heyyo CreditAttribution: heyyo commented#36 works from me too, but it is patch for Drupal Core.
Comment #40
ron_s CreditAttribution: ron_s commentedAs a general comment, I've come across this issue several times in the past year.
Every time there was a problem, it was an issue in a supporting module that needed to be fixed, and patching Drupal core just masked the actual issue.
Comment #41
heyyo CreditAttribution: heyyo commented@ron_s you are totally right, I have this issue since I applied a non final patch on the module field collection:
https://www.drupal.org/project/field_collection/issues/2833061#comment-1...
Comment #42
ron_s CreditAttribution: ron_s commentedI highly recommend for anyone having this issue to follow the suggestions provided by @joseph.olstad in comment #24.
Running a backtrace will give you lots of important information about the functions being run immediately before this error occurs. From there, you can track down which module is causing the problem.
Comment #43
PanchoComment #44
parasolx CreditAttribution: parasolx commentedWe implemented this patch 4 months ago. But the error still appears sometimes (not too frequent). My site also installed with the Entity Cache module. Maybe the error contributes from this module.
Comment #45
rivimey@parasolx the simplest way to make progress on this is to check the backtraces. Use xdebug's "debug_backtrace" function and output the result to a log file. It's very hard to identify where the issues appear otherwise.
Note: debug_backtrace use does not require you have a UI debugger hooked in, just that xdebug module is enabled and running.
Comment #46
themic8 CreditAttribution: themic8 commentedChanges from comment #36 did the trick, Thank you memcinto!
I created a patch for the updates.
Comment #47
Marko B CreditAttribution: Marko B commentedI would just add that with all this, there is also cases where this messages appears with core entity module,
Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->load() (line 177 of /var/www/html/mysite/includes/entity.inc).
so check this patch
https://www.drupal.org/files/issues/2019-03-26/entity-1803048-46.patch
Comment #48
aaldayel CreditAttribution: aaldayel commented#46 works for me, thank you!
Comment #49
ironsizide CreditAttribution: ironsizide at Message Agency commentedI tested #46 and it didn't quite work for me. I had the additional problem of nested arrays generating many warnings. I've attached a modified patch that addresses those warnings.
Comment #50
philsward CreditAttribution: philsward commentedJust to clarify, do we need patch #16 + patch #49?
Took me a min to figure out #49... For those who have come here and tl;dr the comments:
#16 is for the Entity API contrib module
[docroot]/sites/all/modules/entity
#49 is for the core entity.inc file located in:
[docroot]/includes
Comment #51
cirrus3d CreditAttribution: cirrus3d commentedThanks @ironsizide for #49. We had issues with a content type and the previous patches - and warnings were still generated. This seems to be working properly.
Comment #52
szeidler CreditAttribution: szeidler at Ramsalt Lab commented#49 is fixing the issue perfectly for me. In my case the search results got broken for anonymous users. Thanks!
Comment #53
aubjr_drupal CreditAttribution: aubjr_drupal commentedI'm using both #16 and #49, and they're both working for my distro. Count this as a successful test.
Comment #54
dpico CreditAttribution: dpico commentedI'm getting this error with entity API 7.x-1.9 but #46 and #49 are not applicable ("hunk failed") and #16 won't solve the issue. Are you using the latest version of the module?
Comment #55
aubjr_drupal CreditAttribution: aubjr_drupal commented@dpico - See comment #50 if you haven't seen it already.
Comment #56
dpico CreditAttribution: dpico commentedOops. Thanks you very much, @aubjr_drupal. I don't know how I skipped that message! That did the trick.
Comment #57
anrikun CreditAttribution: anrikun commentedThis happens after a simple entity_load_single('my_entity_type', '10');
Here's the backtrace of the call to array_flip() just before the error is reported:
This doesn't make sense: array([0] => 10) passed to array_flip() is valid!
EDIT: It appeared that 10 was a double instead of an integer!
Where on earth that id became a float? Need to figure that out...
EDIT 2: I found the faulty module that was turning the ID into a float.
So basically, there is no real bug here. It's up to the modules to make sure they call entity_load() with integer or string values!
Comment #58
Vincent Wasswa CreditAttribution: Vincent Wasswa commentedPatch #16 + patch #49 are the real deal. Worked for me.
Comment #59
ron_s CreditAttribution: ron_s commented@Vincent Wasswa, as has been said several times, all you're doing is covering up the real bug by applying these patches.
There is a mistake somewhere in the code causing the issue. This thread should have been closed as "won't fix" a long time ago.
Comment #60
erwangel CreditAttribution: erwangel commentedIn my case this warning appears with not logged user's urls like https://www.example.com/user?destination=/comment/reply/25506 or https://www.example.com/user/register, etc
Debugging lead me to object_load function of class menu_token_entity_context in file menu_token_entity_context of menu_token module.
This function tries to get some argument from the entity path but has no test if there is no entity_id before calling entity_load_single
I added the following test before the return function and this solved the problem
Of course we need a more generic solution ibut I'll open an issue in menu_token module
Comment #61
AnybodyWe're also using menu_token so I guess #60 is also the case for us ... -.-This is the issue @erwangel created there: #2939708: context object_load with path of "user" causes errors
As updating to latest dev didn't change anything, I'm quite unsure...
Update: See #64
Comment #62
Anybody@ironsizide could you please clarify if #16 is still needed or your patch from 49 is enough?
I'd vote to get this fixed asap as it seems to affect many users and tends to fill logs....
EDIT: sorry - found the required information in:
Sadly #49 doesn't apply against latest core for me anymore?
Comment #63
AnybodyHere's a reroll of #49 against latest 7.x core. I also named the file accordingly to prevent confusion.
The patch hardens the core, but of course typically the reasons for such problems should be eliminated so that wrong structure is not passed at all.
We can not run tests on this, as it's against CORE, not the module! #16 is against the module and also required.
Comment #64
AnybodyFinally this was the root cause for me (commerce_line_item): #3236711: commerce_line_item_form_alter creates core warning as it loads "false" order
Still I think we should harden the module and core to ensure this can not happen or at least provide a clear error message.
Comment #65
loopy1492 CreditAttribution: loopy1492 commentedPatch on #63 seems to have worked for me on PHP 8.
If this is being caused by a problem outside of core, then dblog needs to report a backtrace, otherwise this is the only solution.
Comment #66
ethan1el CreditAttribution: ethan1el commentedPatch on #63 doesn't apply on Drupal 7.95Comment #67
sano CreditAttribution: sano commentedAfter applying the patch I stopped seeing the error on my Drupal 7.97 installation. Thank you.