Stack user
Stack user

Reputation: 519

How does the function get_config_bytes() works?

I am using an extension regarding image uploading which use the function mentioned below and it is a common function which is normally used to get max_upload_size in bytes but I wonder how does it work?

For example if $val = 20M then how does it multiply 20M * 1024 and get the correct output in bytes.

function get_config_bytes($val) {
            $val = trim($val);
            $last = strtolower($val[strlen($val)-1]);
            switch($last) {
                case 'g':
                    $val *= 1024;
                case 'm':
                    $val *= 1024;
                case 'k':
                    $val *= 1024;
            }
            return $this->fix_integer_overflow($val);
        }

I am very curious about this because a while ago when I was using this function it was generating a Notice that non integer is multiply by an integer but now it is working fine. I have no idea what happened. Thanks

Upvotes: 0

Views: 201

Answers (1)

M. Eriksson
M. Eriksson

Reputation: 13635

There are two parts to this question.

How does it work?

If you pass in 20M, the switch/case would match case 'm':. Since the case-blocks are missing the break; in them, the matched case-block will be executed and all other case-blocks that comes after. That would result in 20 * 1024 (from the m block) * 1024 (from the k-block)

Here's a demo showing how the switch/case works in this context

Why do you get notices?

The above function will throw a notice on PHP7.1+. Before, if you had a string like 20M and you used it as a number (performing a mathematical operation on it), it would silently be converted to the number 20.

From PHP 7.1, it would still work but would throw the notice "A non well formed numeric value encountered" unless you've turned off error reporting for notices.

Here's an updated version that won't throw any notices:

function get_config_bytes($val) {
    $val  = trim($val);
    $last = substr($val, -1);   // Get the last character
    $val  = rtrim($val, $last); // Trim away the last character which isn't a number

    switch(strtolower($last)) {
        case 'g':
            $val *= 1024;
        case 'm':
            $val *= 1024;
        case 'k':
            $val *= 1024;
    }

    return $this->fix_integer_overflow($val);
}

Here's a demo

I'm sure that there are more efficient ways to do this, but this solves the issue either way.

Upvotes: 1

Related Questions