The Drupal system I have inherited is throwing a large number of PHP warnings into the logs that look like this:
Warning: array_flip(): Can only flip STRING and INTEGER values in Drupal\Core\Entity\EntityStorageBase->loadMultiple()
I have spent some time running it through a debugger and reading existing tickets, this is what I have found:
There seem to be a number of circumstances that can lead to this error. Some error reports I have seen talk about it being caused by an ID value being turned into a float rather than an int, due to an earlier call to floor().
In my case the error occurs in the loadMultiple() method when an ID arrives wrapped in a Drupal\Core\Render\Markup object rather than being a plain integer or string.
In all cases I've seen, the value is correct, but is just not presented in a format that array_flip can handle.
It therefore seems to me that an appropriate fix would be to add a little pre-processing to normalise the array to contain only strings or integers.
I therefore propose that we add the following code to the loadMultiple() method, before the call to array_flip():
if ($ids) {
foreach ($ids as $key=>$value) {
if (!is_string($value) && !is_integer($value)) {
$ids[$key] = (string)$value;
}
}
}
| Comment | File | Size | Author |
|---|---|---|---|
| #23 | 3145190-23.patch | 900 bytes | pamelalies |
| #21 | 3145190-21.patch | 900 bytes | _utsavsharma |
| #21 | interdiff_18-21.txt | 801 bytes | _utsavsharma |
| #18 | php_warnings_in_array_flip_3145190.patch | 901 bytes | rnaik16 |
Comments
Comment #2
spudley commentedComment #3
raunak.singh commentedComment #4
raunak.singh commentedHi @Spudley,
I am not able to reproduce this issue.
Comment #5
lendudeMoving this out of the views queue since this does not seem to be related to views.
We would need some steps to reproduce the problem here. That way we can asses if adding a wrapper for sanitisation is the correct way of addressing this. Most of the time, these wrappers just hide the upstream problem. If invalid data is passed, the upstream code should be cleaned up and it should not be the responsibility of the called code to clean up everything it gets passed.
Comment #6
longwaveIndeed, the original post notes this:
> In my case the error occurs in the loadMultiple() method when an ID arrives wrapped in a Drupal\Core\Render\Markup object rather than being a plain integer or string.
Why is this method being called with a markup object in the first place? It should be the caller's responsibility to cast markup to string/integer. A stack trace may help figure out the root cause, and then it can be fixed there.
Comment #7
spudley commented@Lendude: Apologies for putting it in Views if that wasn't right. As you'll see below, it seems to me that the Views module is where the problem originates, even if the warning is eventually thrown in the core entity code.
At the very least, the error seems to be entirely within Drupal: there is no custom code involved here; even the templates it goes through in the trace below are ones that are built-in.
@longwave, you asked for a stacktrace, so here it is:
Comment #8
spudley commentedComment #9
spudley commentedApologies for flipping the version/component settings back; I hadn't refreshed the page, so when I saved the new comment, it picked up the original values. I've put them back to the way you set them @Lendude.
Comment #10
longwave#44 /var/www/public/core/lib/Drupal/Core/Theme/ThemeManager.php(384): twig_render_template('themes/custom/s...', Array)
There is a custom Twig template involved, what does this do? A Views block gets rendered inside it, it seems like the arguments to this block might not be the correct type.
Comment #11
spudley commentedI think I've resolved this problem. I've made a number of other changes to the site in question, and the errors described here have now disappeared.
The change that I think sorted it was where I removed an older third-party module and replaced it with a newer one that is properly supported and up-to-date. The error seems to have gone away after I did this.
The older module linked into the views and allowed them to alter their behaviour according to the user's browser. This feature wasn't being used, but it would seem that the module was getting called by Views anyway and passed the field output through markup renderer regardless of whether it was necessary or correct.
I replaced the module for other reasons unrelated to this bug, but it was only the act of removing the module that allowed me to realise that it was also causing this bug. I honestly don't think I would have managed to track the bug down otherwise; I certainly had no idea it was linked to the module. In fact, I didn't even know the module had functionality that linked into Views.
Tracking this down has been an absolute nightmare. The warning message occurs at a point in the Drupal code that is very *very* far removed from where the problem originates. I've seen this a lot before in Drupal. Usually, where I've made a mistake in my own code, it's possible to work out what's going on, but in cases like this it's just impossible without spending literally days trawling through the code in a debugger.
I think the lesson to be drawn here is that Drupal needs much more robust error handling to pick up issues like this much sooner. A broken data structure that will cause a crash should be picked up early and reported on, not left until it actually crashes.
It's all very well saying that it's the module's fault. Yes it is. But the platform needs to give us the tools to be able to actually find the problem so that we can fix the module.
Comment #13
joachim commentedDuplicate of #3221534: throw an exception when IDs passed to loadMultiple() are badly formed?
Comment #16
rnaik16 commentedComment #17
rnaik16 commentedComment #18
rnaik16 commentedComment #20
qusai taha commentedThe patch working for me,
Thank you!
Comment #21
_utsavsharma commentedFixed CCF for #18.
Comment #22
longwaveClosing as duplicate of #3221534: throw an exception when IDs passed to loadMultiple() are badly formed as noted in #13. As far as I know this only happens when the set of IDs passed to loadMultiple is malformed in some way (usually a NULL); the solution is to fix the caller, but we can provide a better error message as well.
Comment #23
pamelalies commentedThis patch caused my site to throw: Warning: Array to string conversion in Drupal\Core\Entity\EntityStorageBase->loadMultiple() (line 315 of core/lib/Drupal/Core/Entity/EntityStorageBase.php). Just posting this patch to undo it.
Comment #24
janpongos commented#18 works for me thanks!
Comment #25
arx-e commentedSame problem with Drupal 11.2.5.
A few days ago and for reasons I have not traced to any specific change, I started having this "Can only flip string and integer values" error and it prevented a view block from loading in the pages it was placed. The view relies on filtering for the current user.
Adding the lines of code from #21 after line 278 in core/lib/Drupal/Core/Entity/EntityStorageBase.php solved my issue. The view is loaded again as it is expected and no errors are coming up. (The position where the lines should be inserted is a bit different in the current file in Drupal 11.2.5)