Upon viewing any webform node (also as anonymous user), the following warning is shown after upgrading to PHP 7.1.
Warning: A non-numeric value encountered in _webform_render_number() (line 318 of /somepath/sites/all/modules/webform/components/number.inc).
The corresponding code is
if (!is_int($element['#step'] * 1)) { //<-- this line
$decimals = strlen($element['#step']) - strrpos($element['#step'], '.') - 1;
$element['#step'] = sprintf('%1.' . $decimals . 'F', $element['#step']);
}
The warning is triggered when $element['#step'] is the empty string (or any non-integer). Explicitly casting to int solves it, but I'm not sure if that's the nicest way to fix this bug.
numeric.inc contains many more examples of !is_int($maybeint * 1), so it is likely that the warning can also be triggered in other locations.
Comments
Comment #2
liam morlandI expect that the error is because of the
* 1; it doesn't like multiplying something that isn't a number. Perhaps that variable should always be initialized to an integer. I don't mind casting, but that whole block of code looks suspicious, like it could be rewritten some other way. In particular, I think there ought to be a better way than using string functions to manipulate the number.Comment #3
pifagor commentedpatch
Comment #4
pifagor commentedpatch
Comment #5
pifagor commentedpatch
Comment #8
pifagor commentedpatch
Comment #9
pifagor commentedpatch
Comment #10
liam morlandIt doesn't make sense to call is_int() on a value that has just been cast to int; it will always be true.
I expect that the
* 1is there to convert to numeric. Casting to float might do what is needed.Comment #11
pifagor commentedpatch
Comment #12
pifagor commentedpatch
Comment #13
bocaj commented#12 worked well for me!
Comment #14
liam morlandWhile I am sure the new code will get rid of the error, I'm not certain that it has the same functionality. The PHP documentation on floats states that (float) 8 might be internally represented as 7.9999999999999991118. If that is cast to integer, it will be 7. So this code would erroneously state that "8" is not an integer. Perhaps by using round() we can avoid this problem (round() returns a float, so strict comparison is possible):
round($element['#step']) !== (float) $element['#step']number.inc contains another example of the problematic code which should be fixed by this patch:
if (is_int(($value . '') * 1))Comment #15
liam morlandMaybe this would be better:
filter_var((float) $element['#step'], FILTER_VALIDATE_INT) !== FALSEComment #16
pifagor commented@Liam Morland
This is the best solution I've seen :)
Comment #17
liam morlandI think we should use strict equality (===) and do that comparison with the last one as well. The eliminates the possibility that zero gets treated differently. We want to know only whether or not the filter failed.
Comment #18
pifagor commentedpatch
Comment #20
liam morlandComment #22
webservant316 commentedjust ran into this.
Comment #23
jjmackow commentedThanks for the patch. I applied the patch in #28 against version 7.x-4.15 and the issue went away. I'm using PHP 7.1 on a CentOS 7 server
Comment #24
pifagor commentedThank
Comment #25
Mustrum commented#18 worked for me. I'm using PHP 7.1 on Ubuntu server 18.04.
Drupal 7.61