Search code examples
phpstrict

Why strtolower() does not follow the PHP strict Standard


If i use

strtolower(end(explode('.',$_FILES['file']['name'])));

it give me error

PHP Strict Standards: Only variables should be passed by reference in

I thought ok I just store the values in a variables first, and then use explode

 $filename = $_FILES['file']['name'];
 $filearray = explode('.',$filename);

and it works fine

But i have another line

strtolower(end($filearray));

I thought it should give me the same error , i mean i should first have to store end($filearray) in a variable then use that variable in strtolower(),

But this is not giving me any error ,So why strtolower() accepting a function as parameter , and not giving an error , can someone explain why ?


Solution

  • It's not strtolower that gives you the warning - but end function. Quoting the docs:

    end() advances array's internal pointer to the last element, and returns its value. [...] The array is passed by reference because it is modified by the function. This means you must pass it a real variable and not a function returning an array because only actual variables may be passed by reference.

    In your first example you attempt to end the result of explode call - i.e., not a real variable. While it's possible for PHP to ignore such a use case, it usually means that you've done something by mistake - and E_STRICT warning attempts to notify you about it.

    Your third example works fine, because:

    1) strtolower actually doesn't care about the reference. It returns a string with all alphabetic characters converted to lowercase instead of modifying the string in place.

    2) end has a variable - array - passed in. It returns its last element, while advancing the internal pointer of that array to, well, its end. Have you attempted to employ this internal pointer (with current or some other means), you'd see the difference.


    As a sidenote (already mentioned in comments by @DoktorOSwaldo), you can replace the all explode(end() stuff with simple pathinfo call:

    $ext = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));