PHP Notice: A non well formed numeric value encountered in /var/www/zephyr/library/XenForo/Application.php on line 1534

[Sat Aug 12 02:21:28.993810 2017] [php7:notice] [pid 20352] [client :14302] PHP Notice: A non well formed numeric value encountered in /var/www/zephyr/library/XenForo/Application.php on line 1534

    /**
 * Gets the current memory limit.
 *
 * @return int
 */
public static function getMemoryLimit()
{
    if (self::$_memoryLimit === null)
    {
        $curLimit = @ini_get('memory_limit');
        if ($curLimit === false)
        {
            // reading failed, so we have to treat it as unlimited - unlikely to be able to change anyway
            $curLimit = -1;
        }
        else
        {
            switch (substr($curLimit, -1))
            {
                case 'g':
                case 'G':
                    $curLimit *= 1024; //This is line 1534
                    // fall through

                case 'm':
                case 'M':
                    $curLimit *= 1024;
                    // fall through

                case 'k':
                case 'K':
                    $curLimit *= 1024;
            }
        }

        self::$_memoryLimit = intval($curLimit);
    }

    return self::$_memoryLimit;
}

Not quite sure how to fix this one, kind of stumped, I pointed out line 1534

2 answers

  • answered 2017-08-12 09:29 Hamza Abdaoui

    You are multiplying a string with an integer in $curLimit *= 1024;. Because $curLimit equal (for example) 512M. So what you have to do is delete the last character :

    $curLimitNumber = substr($curLimit, 0, -1);//Will extract the number (512 FROM 512M)
    switch (substr($curLimit, -1))
            {
                case 'g':
                case 'G': 
                    $curLimitNumber *= 1024;
    

  • answered 2017-08-12 09:29 Gordon

    Your $curLimit comes from

    $curLimit = @ini_get('memory_limit');
    

    Quoting http://php.net/manual/en/ini.core.php#ini.memory-limit:

    When an integer is used, the value is measured in bytes. Shorthand notation, as described in this FAQ, may also be used.

    And quoting that FAQ mentioned in the docs:

    The available options are K (for Kilobytes), M (for Megabytes) and G (for Gigabytes; available since PHP 5.1.0), and are all case-insensitive. Anything else assumes bytes. 1M equals one Megabyte or 1048576 bytes. 1K equals one Kilobyte or 1024 bytes. These shorthand notations may be used in php.ini and in the ini_set() function.

    The code you show is checking for the last char in the $curLimit value taken from memory_limit:

    switch (substr($curLimit, -1))
    

    This means, it is already anticipating the shorthand notation. In the case blocks, it's checking for k, g, m and so on (the shorthands) and then expands $curLimit to the actual bytes.

    When you do

    $value = "1M";
    $value *= 1024;
    

    the result will be 1024, but you'll get the Notice you get, because "1M" is not a well formed numeric value, but just a string. What PHP does in this case is to type juggle the number up to the first non-numeric char, e.g. it treats "1M" as integer 1. So, the code will work, but it's sloppy. Hence the notice.

    If you want to get rid of the notice, you'll have to strip the shorthand from $curLimit or cast $curLimit to int or pass it to intval before multiplying it.

    There is a bug report about this in the XenForo forums: