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:

  1. That the variable or parameter being flipped is an array.
  2. That the values in the array can be used as array keys (ie. are not NULL values)

Remaining tasks

  1. Tests: Pass non-array values into methods that accept mixed type parameters
  2. Tests: Pass empty values into methods that accept mixed type parameters
  3. 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.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

rsvelko’s picture

Musa.thomas’s picture

I know this issue like at said in my previous post I look all variable wich is send to load, and all is array....

kenorb’s picture

ishwar’s picture

Issue summary: View changes
mskicker’s picture

hi
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

prince_kr’s picture

Hi, 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.

chOP’s picture

Title: Warning : array_flip(): Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->load() (ligne 178 in entity. » Warning : array_flip(): Can only flip STRING and INTEGER values! in DrupalDefaultEntityController
Version: 7.x-1.0-rc3 » 7.x-1.x-dev
Issue summary: View changes
Related issues: +#1893312: Delete Node Warning: array_flip() [function.array-flip]: Can only flip STRING and INTEGER values! in EntityAPIController->load(), +#2132931: array_flip() warning in EntityListWrapper->label() on line 1086 of entity.wrapper.inc, +#2390311: Module name causes array_flip(): Can only flip STRING and INTEGER values!
chOP’s picture

Issue summary: View changes
chOP’s picture

FileSize
4.33 KB

This 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.

chOP’s picture

Status: Closed (duplicate) » Needs review
NancyDru’s picture

This takes care of it for me:

    if (isset($ids[0]) && $ids[0] === FALSE) {
      $ids = array();
    }
    $passed_ids = !empty($ids) ? array_flip($ids) : FALSE;

That last line exists currently (175) in common/entity.inc.

chOP’s picture

@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.

Warning : array_flip(): Can only flip STRING and INTEGER values! in DrupalDefaultEntityController

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.

  1. Make sure loosely typed variables are an array, before passing them to PHP builtin functions that expect an array value.
  2. Make sure array values are not NULL or FALSE before trying to use them as array keys with the PHP builtin array_flip().
  3. If either of the above conditions aren't met, in an Entity API method, continue as if the Entity field contained an empty value with the correct structure.

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:

  1. Show a warning with the Entity type, bundle and field name.
  2. Continue as if the field contained an empty value with the correct structure.
joseph.olstad’s picture

Tried patch 8 , it didn't have any effect for me. Could be in my case caused by a different module.

petar.kolicov’s picture

This 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.

joseph.olstad’s picture

patch 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.

chOP’s picture

@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 to DrupalDefaultEntityController::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?

chOP’s picture

@joseph.olstad said:

Tried patch 8 , it didn't have any effect for me.

@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.

giorgio79’s picture

I 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

Warning: array_flip(): Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->load() (line 175 of /public_html/includes/entity.inc).
Warning: array_flip(): Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->cacheGet() (line 388 of /public_html/includes/entity.inc).
giorgio79’s picture

ericclaeren’s picture

Patch #16 seems to work.

kenorb’s picture

Status: Needs review » Reviewed & tested by the community
Chris Charlton’s picture

My watchdog has tons of these notices. :(

Patch applied fine for me.

Fabito’s picture

Hi, I tested patch #16 and i've always error :

Warning: array_flip(): Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->load() (line 175 of (...)/includes/entity.inc).
Warning: array_flip(): Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->cacheGet() (line 388 of (...)/includes/entity.inc).

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 :/

joseph.olstad’s picture

@Fabito, here are some debugging tips for you to help you capitalize on this opportunity.

DEBUGGING TIPS:

//When you want to debug the $wtf variable, and dpm isn't doing it for you, then you should use this:
  watchdog('Fabito_debug', '<pre>@print_r</pre>', array('@print_r' => print_r( $wtf, TRUE)));

When you need a backtrace

Here is some backtrace code that might come in handy. The file should be created in the web root.

if ($fp = fopen('backtrace.log', 'w')) {
  $bt = debug_backtrace();
  fwrite($fp, 'debug='.print_r($bt, true));
  fclose($fp);
}

Another approach if you want it in your browser:

$bt = debug_backtrace();
echo "<pre>" . print_r($bt, true) . "</pre>\n";

Here is an example of some output:

[4] => Array (
  [file] => sites/all/modules/contrib/path_breadcrumbs/path_breadcrumbs.module
  [line] => 135
  [function] => ctools_access
  [args] => Array (
    [0] => Array (
      [plugins] => Array (
        [0] => Array (
          [name] => entity_field_value:node:feed_item:field_news_category

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.


function imgoingtosaythis($what_im_sayin) {
  if ($fp = fopen('saythis.txt', 'a')) {
    fwrite($fp, "$what_im_sayin\r\n");
    fclose($fp);
  }
}

the file saythis.txt in this case would be written to the root of your drupal folder containing the contents of $what_im_sayin .

chrisroane’s picture

I confirmed Patch #16 worked for my case.

remyyyyy’s picture

thank you for the patch

biarr’s picture

Patch #16 is working. Thanks!

Majdi’s picture

Patch #16 is working. Thanks!

ron_s’s picture

Just 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.

cmseasy’s picture

With 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.

rivimey’s picture

FYI 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.

lubwn’s picture

Getting 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.

narkoff’s picture

Received this error when returning AJAX feed from Selective Tweets module. Patch 16 fixed issue.

murali97’s picture

Hi Guys, Is this patch working for php 7.2

martinhansen’s picture

In 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.

memcinto’s picture

In 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.

glynster’s picture

#16 interdiff-warning_array_flip-1803048-8-16.txt resolved the problem +1

fonant’s picture

Changes 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.

heyyo’s picture

#36 works from me too, but it is patch for Drupal Core.

ron_s’s picture

As 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.

heyyo’s picture

@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...

ron_s’s picture

I 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.

Pancho’s picture

Issue tags: +array_flip()
parasolx’s picture

We 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.

rivimey’s picture

@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.

themic8’s picture

Changes from comment #36 did the trick, Thank you memcinto!
I created a patch for the updates.

Marko B’s picture

I 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

aaldayel’s picture

#46 works for me, thank you!

ironsizide’s picture

I 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.

philsward’s picture

Just 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

cirrus3d’s picture

Thanks @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.

szeidler’s picture

#49 is fixing the issue perfectly for me. In my case the search results got broken for anonymous users. Thanks!

aubjr_drupal’s picture

I'm using both #16 and #49, and they're both working for my distro. Count this as a successful test.

dpico’s picture

I'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?

aubjr_drupal’s picture

@dpico - See comment #50 if you haven't seen it already.

dpico’s picture

Oops. Thanks you very much, @aubjr_drupal. I don't know how I skipped that message! That did the trick.

anrikun’s picture

This 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:

    [2] => Array
        (
            [file] => /[...]/sites/all/modules/entity/includes/entity.controller.inc
            [line] => 219
            [function] => array_flip
            [args] => Array
                (
                    [0] => Array
                        (
                            [0] => 10
                        )

                )

        )

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!

Vincent Wasswa’s picture

Issue tags: -

Patch #16 + patch #49 are the real deal. Worked for me.

ron_s’s picture

@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.

erwangel’s picture

In 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

if ($entity_type == 'user' && !is_numeric(arg($position))) {
  return NULL;
}
return entity_load_single($entity_type, arg($position));

Of course we need a more generic solution ibut I'll open an issue in menu_token module

Anybody’s picture

We'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

Anybody’s picture

@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:

Just 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

Sadly #49 doesn't apply against latest core for me anymore?

Anybody’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
1.41 KB

Here'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.

Anybody’s picture

Finally 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.

loopy1492’s picture

Patch 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.

ethan1el’s picture

Patch on #63 doesn't apply on Drupal 7.95

sano’s picture

After applying the patch I stopped seeing the error on my Drupal 7.97 installation. Thank you.