Rowan Collins wrote on 23/09/2015 21:15:
On 23 September 2015 20:04:57 BST, Ryan Pallas <derokor...@gmail.com> wrote:
I dislike this because it makes refactoring harder.
What's more, the function is not dereferencing a variable to get its value, it 
is looking up a name in the symbol table, so the magic syntax that makes it 
look like you're using the variable is misleading.


Talking of refactoring, I thought of an interesting example of the ambiguity/confusion a combined exists() function could create.

For any normal function the two definitions below should be equivalent - you can refactor the use of $GLOBALS by importing the variable with the "global" keyword.

function foo() { var_dump(exists($GLOBALS['test'])); }
function bar() { global $test; var_dump(exists($test)); }

I haven't actually built François's branch to test, but based on behaviour of existing functions [e.g. https://3v4l.org/X0tOk], I predict the following output:

foo();
// bool(false)
bar();
// bool(true)

The "global $test" is the closest PHP comes to a variable declaration - the variable now exists in the symbol table, even though there was no global variable with that name to import.

Even more confusingly, it has a side-effect on the original function:

foo();
// bool(true)

That happens because "global $test" is basically "$test =& $GLOBALS['test']", so has to create the global variable in order to reference it. This is completely invisible to most programs, because it gets initialised to null, so isset() returns false consistently. [https://3v4l.org/f4dm2]

This is the kind of odd edge-case you end up with when you a) treat a variable's existence as an accessible property; and b) make that check appear to be the same as checking for an item in an array.


With the two functions I've proposed, you at least wouldn't be led astray by an automated refactoring tool because this would give an error, rather than a surprising result:

function bar() { global $test; var_dump(hasitem($test)); }

And you would have to specifically change it to this instead, clearly a different type of test:

function bar() { global $test; var_dump(variable_exists('test')); }


Regards,
--
Rowan Collins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to