Problem/Motivation
We are experiencing multiple deprecation warnings on PHP 8.1 in the text_summary() function:
Deprecated function: strpos(): Passing null to parameter #1 ($haystack) of type string is deprecated in text_summary() (line 358 of /modules/field/modules/text/text.module).
Deprecated function: mb_strlen(): Passing null to parameter #1 ($string) of type string is deprecated in drupal_strlen() (line 482 of /includes/unicode.inc).
The first one is directly in text_summary() and the second one is in drupal_strlen() function which is called by text_summary().
The problem is not the Drupal core itself, but some modules seems to be calling text_summary() with null, which results in this warning. I can point out at Metatag module trying to generate node tokens, but it seems like this is not the only one module causing this. This will happen when there is a node with a text_with_summary field type and this field has a null value. Some modules are directly using this null value (like Metatag module) and it will end up with this deprecation warnings.
A im posting this as a Drupal core issue, because in some other issues we went the way of sanitizing it on the Drupal core side, as multiple modules can cause this. See the recent check_plain() fix: #3254699: [D7 PHP 8.1] check_plain(): Passing null to parameter #1 check_plain() includes/bootstrap.inc, line 1907
Steps to reproduce
Proposed resolution
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #6 | 3270881-6.patch | 1.2 KB | poker10 |
| #6 | 3270881-6_test_only.patch | 584 bytes | poker10 |
Comments
Comment #2
poker10 commentedBecause there are multiple calls in
text_summary()which can potentially cause deprecation warnings if$textwill be null I chose the way of returning the empty$textat the very beginning if it is empty.Comment #3
mfbThis patch changes how buggy code would be handled: currently
text_summary(array())throws a TypeError (on PHP 8.0), but with this patch it would return array(). That's probably not a big deal, but it might be preferable to be conservative and use is_null() logic..Comment #4
poker10 commentedYes, that is a good point, thanks. It will be better to focus only on the NULL issue in the patch and don't change behavior for other possible variable types. I am attaching updated patch.
Comment #5
mcdruid commentedWould like to see a test along with the patch ideally.
Comment #6
poker10 commentedAdding test.
Comment #7
mcdruid commentedExcellent, thanks!
Comment #8
fabianx commentedRTBC + 1, approved for Merge! Thanks all!
Comment #10
mcdruid commentedThanks!
Comment #12
greg boggsI got this warning in Drupal 9 as well when I set the homepage node path to /. Should I make a separate ticket for that or do we use this one and assign it to 9x?
Comment #13
mcdruid commentedI believe the policy is to create separate tickets these days.
Comment #14
drupal_developer2022 commentedSalut. Est ce que tu as trouvé une solution à propos de cette erreur dans le D9?
Comment #15
cilefen commentedDoes this need porting to Drupal 9?
Comment #16
cilefen commented@Greg Boggs did you ever make that issue? If not we can use #3312931: [D9 PHP 8.1] Deprecated function: strpos(): Passing null to parameter #1 ($haystack) of type string is deprecated in text_summary() (line 71 of core/modules/text/text.module) unless someone can find it is a duplicate.
Comment #17
gbirch commentedI understand that this precise issue is fixed, but the underlying problem with drupal_strlen() can be caused by many other things. Would it not be better for drupal_strlen() to return 0 if the $text is NULL?
I.e. add the following to drupal_strlen():
Comment #18
poker10 commented@gbirch, there are lot of functions where your mentioned approach could be used, if we decide to go this way (
drupal_strtoupper(),drupal_strtolower(), ...). But preferably we try to fix reported issues where they originated. We have made few exceptions in functions, where multiple contrib modules (and probably also core modules) were sending NULL instead of a string data. But the official policy for core is not babysit broken contrib code.I am not sure if there are any open issues about the
drupal_strlen()PHP 8 warning somewhere (except this fixed one). If yes, we can check the issue and the root cause of the problem and decide about the fix. If not, then I am not sure about fixing something, that is not an issue now. Thanks!Comment #19
gbirch commented@poker10, I don't think I agree with you about which code is "broken".
Prior to PHP 8, you could happily pass NULL to these functions in place of empty strings. The drupal_ functions you mention do not specify that the input must be a string in the PHP doc or otherwise. If they don't, then arguably the bug/incompatibility is in the drupal_ functions themselves, which don't behave as they used to, and not in the "broken" contrib code that uses them.
If you have been calling one of these functions in your custom/contrib code, how would you know that you must pass a string, if a) previously the functions accepted NULL values happily and b) now they don't, if the function signatures are unchanged? And from a purely practical point of view, what happens here is that the core code throws notices, and you don't immediately know what code called it without analyzing the back-trace. This is not a developer friendly result.
Finally, the whole POINT of those functions is to provide a wrapper around different PHP implementations, character sets, etc. This would be just one more compatibility wrapper.
Comment #20
poker10 commentedThe documentation of the
drupal_strlen()function is as follows:So it specifies, that the input has to be a string (in the parameter description), but it is not enforced like in D10. So yes, you were able to pass NULL to these functions prior to PHP 8 without problems, but only because the underlaying
strlen()function allowed that. Here are the reasons for this change in PHP: https://php.watch/versions/8.1/internal-func-non-nullable-null-deprecation.Yes, this is true. But as I have mentioned earlier, we cannot fix non-existing problems. So either there is an open issue about another problem with
drupal_strlen()in PHP 8+, and we can take a look at options here, or someone need to create such issue, so that we can consider this change. We are not going to do anything else in this issue, as it is closed (fixed). Thanks!Comment #21
poker10 commented@gbirch There is a new issue #3362238: _form_validate sends null to drupal_strlen triggering deprecation notice, which looks valid and we can discuss the potential global fix for
drupal_strlen()there. Thanks.