I just noticed PHP has an type casting to (unset), and I'm wondering what it could possibly be used for. It doesn't even really unset the variable, it just casts it to NULL, which means that (unset)$anything should be exactly the same as simply writing NULL.
# Really unsetting the variable results in a notice when accessing it
nadav#shesek:~$ php -r '$foo = 123; unset($foo); echo $foo;'
PHP Notice: Undefined variable: foo in Command line code on line 1
PHP Stack trace:
PHP 1. {main}() Command line code:0
# (unset) just set it to NULL, and it doesn't result in a notice
nadav#shesek:~$ php -r '$foo = 123; $foo=(unset)$foo; echo $foo;'
Anyone ever used it for anything? I can't think of any possible usage for it...
Added:
Main idea of question is:
What is reason to use (unset)$smth instead of just NULL?
As far as I can tell, there's really no point to using
$x = (unset)$y;
over
$x = NULL;
The (unset)$y always evaluates to null, and unlike calling unset($y), the cast doesn't affect $y at all.
The only difference is that using the cast will still generate an "undefined variable" notice if $y is not defined.
There's a PHP bug about a related issue. The bug is actually about a (in my mind) misleading passage elsewhere in the documentation which says:
Casting a variable to null will remove the variable and unset its value.
And that clearly isn't the case.
I’d guess (knowing PHP and it’s notaribly... interesting choices for different things, I may be completely wrong) that it is so that the value does not need setting to a var. For exact reason to use it for a code, I can’t think of an example, but something like this:
$foo = bar((unset) baz());
There you want or need to have null as argument for bar and still needs to call baz() too. Syntax of function has changed and someone did a duck tape fix, like what seems to be hot with PHP.
So I’d say: no reason to use it in well-thought architecture; might be used for solutions that are so obscure that I’d vote against them in first place.
As of PHP 8.0.X, (unset) casting is now removed and cannot be used.
For example it can be used like this
function fallback()
{
// some stuff here
return 'zoo';
}
var_dump(false ? 'foo' : fallback()); // zoo
var_dump(false ? 'foo' : (unset) fallback()); // null
Even if fallback() returns "zoo" (unset) will clear that value.
Related
here are some X-files.
Let's check this script: https://admin.laysoft.tk/test.php
We tested it on different machines with different version of PHP.
Let's see this:
$tomb = 666;
var_dump($tomb);
$a = $tomb['akarmi'];
var_dump($a);
Result of this is:
int(666)
NULL
($tomb means array)
As you see, we initialized the $tomb as an integer.
Why $a = $tomb['akarmi']; does not drop a notice, that no key like this?
UPDATE
I've reported it, I am so curious.
https://bugs.php.net/bug.php?id=74579
UPDATE2
Ok, this bug is exists from years. There are a lot of issue about this:
https://bugs.php.net/bug.php?id=37676
Because of PHP's type juggling feature, which will implicitly convert between types, depending on how you attempt to access a variable.
The conversion to arrays however is not implemented, not even defined how it should work, as the manual says:
The behaviour of an automatic conversion to array is currently undefined.
As for why it has remained that way through the years ... nobody could really answer that question.
I have the following;
$foo;
$foo = serialize($foo);
print_r($foo);
it gave me a result of N;
Now I do not know if this is unique to the system i am using or if this is a normal result. All I know is it was causing major problems with my site.
My question is... is this normal when serializing an undefined variable?If so can someone please explain why it outputs this result.Thank you for your time.
It appears that the string N; is the serialize()d form of null. (See this codepad)
However, two things to note:
You should be defining all variables before using them, even if you just declare them as null. Otherwise you'll get a notice about $foo being an undefined variable. Some argue that you can hide warnings, but this is poor practice. You should prevent them completely by using sensible defaults for all variables.
Typically, one does not need to read the output of serialize(). You can store it on a DB, in a file, or in a memory cache system like Memcached, APC, or Redis. However, you will never need to understand what the output of serialize() means thanks to unserialize().
It works as expected:
<?php
$foo;
$foo = serialize($foo);
var_dump($foo); // Print the string "N"
$unserialized = unserialize($foo);
var_dump($unserialized); // Print NULL
But why are you looking at the output of serialize? This should not be relevant to your website. What matters is that unserialize gives you back the correct data.
I want to use a global variable setup where they are all declared, initialized and use friendly syntax in PHP so I came up with this idea:
<?
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
$GLOBALS['debugger'] = 1; // set $GLOBALS['debugger'] to 1
DEFINE('DEBUGGER','$GLOBALS["debugger"]'); // friendly access to it globally
echo "1:" . DEBUGGER . ":<br>";
echo "2:" . ${DEBUGGER}. ":<br>";
echo "3:" . $GLOBALS['debugger'] . ":<br>";
if (DEBUGGER==1) {echo "DEBUG SET";}
?>
generates the following:
1:$GLOBALS["debugger"]:
Notice: Undefined variable: $GLOBALS["debugger"] in /home/tra50118/public_html/php/test.php on line 8
2::
3:1:
How can there be an error with 2: when clearly $GLOBALS["debugger"] IS defined? And then not generate a similar notice with the test at line 10?
I think what I am trying to do is to force PHP to interpret a string ($GLOBALS["debugger"]) as a variable at run time i.e. a constant variable variable
Disclaimer: I agree with the comments, globals are generally a bad idea.
That said, there's a few questions here that are worth answering, and the concept of indirection is useful, so here goes.
${'$GLOBALS["debugger"]'} is undefined. You don't include the leading '$' when using indirection. So, the correct version would be define('DEBUGGER', 'GLOBALS["debugger"]').
But, this doesn't work either. You can only access one level down via indirection. So you can access the array $GLOBALS, but you can't access keys in that array. Hence, you might use :
define('DEBUGGER', 'debugger');
${DEBUGGER};
This isn't useful, practically. You may as well just use $debugger directly, as it's been defined as a global and will be available everywhere. You may need to define global $debugger; at the start of functions however.
The reason your if statement is not causing notices is because you defined DEBUGGER to be a string. Since you aren't trying to use indirection in that line at all, it ends up reading as:
if ("$GLOBALS['debugger']"==1) {echo "DEBUG SET";}
This is clearly never true, though it is entirely valid PHP code.
I think you may have your constants crossed a bit.
DEFINE('DEBUGGER','$GLOBALS["debugger"]'); sets the constant DEBUGGER to the string $GLOBALS["debugger"].
Note that this is neither the value nor the reference, just a string.
Which causes these results:
1: Output the string $GLOBALS["debugger"]
2: Output the value of the variable named $GLOBALS["debugger"]. Note that this is the variable named "$GLOBALS["debugger"]", not the value of the key "debugger" in the array $GLOBALS. Thus a warning occurs, since that variable is undefined.
3: Output the actual value of $GLOBALS["debugger"]
Hopefully that all makes sense.
OK, thanks to all who answered. I think I get it now, I am new to PHP having come form a C++ background and was treating the define like the C++ #define and assuming it just did a string replace in the precompile/run phase.
In precis, I just wanted to use something like
DEBUGGER = 1;
instead of
$GLOBALS['debugger'] = 1;
for a whole lot of legitimate reasons; not the least of which is preventing simple typos stuffing you up. Alas, it appears this is not doable in PHP.
Thanks for the help, appreciated.
You can not use "variable variables" with any of the superglobal arrays, of which $GLOBALS is one, if you intend to do so inside an array or method. To get the behavior you would have to use $$, but this will not work as I mentioned.
Constants in php are already global, so I don't know what this would buy you from your example, or what you are going for.
Your last comparison "works" because you are setting the constant to a string, and it is possible with PHP's typecasting to compare a string to an integer. Of course it evaluates to false, which might be surprising to you, since you expected it to actually work.
Last time I'm exploring PHP pretty much and I was curious if it's possible to define variable without initializing it like in C++.
Well interpreter doesn't output an fatal eror (only a notice that variable test is undefined) if I'll run this code:
<?php
$test = (int) $test;
?>
And if I try to check it with var_dump() function i get:
int(0)
I assumed interpreter automatically cast undefined to integer. Well, ok it's pretty clever.
But when I removed code repsonsible for type casting and checked it with var_dump() function I get:
NULL
Well, ok. So when I assign undefined variable as undefined variable I get variable with NULL. I can understand interpreter do it for me on the run. But when I try something like this:
<?php
var_dump($test);
var_dump($test);
?>
I get two notices that test is not defined, but var_dump() returns NULL, not undefined. And now I don't get it. If I'll turn off notices var_dump() function will have same result with undefined variables and variables assigned to NULL. And here comes a question from topic. Why interpreter (or rather a var_dump() function) treats undefined and NULL as same ?
The special NULL value represents a variable with no value. NULL is the only possible value of type NULL.
A variable is considered to be null if:
it has been assigned the constant NULL.
it has not been set to any value yet.
it has been unset().
(int)$test = casting, force a value to data type (integer)
warning notices = cause by $test is never defined, and you trying to use it
var_dump($test) = I dun have a value for $test, so, I return you a null (by PHP)
I recently stumbled across the following:
<? $d=false; var_dump($d[123]); ?>
which yielded NULL, but (unexpected to me) without any notice, as for example
<? $d=array(); var_dump($d[123]); ?>
does produce the well known
Notice: Uninitialized string offset: 123 in - on line 1
What is going on here? Is there any documentation of this behavior?
From here:
Accessing variables of other types (not including arrays or
objects implementing the appropriate interfaces) using [] or {}
silently returns NULL.
I guess that is what you would call undefined behaviour.
It makes sense, as a boolean can not have an offset.
error_reporting(E_ALL);
$d = TRUE;
var_dump($d[0]);
This also produces NULL (if FALSE was coerced to an empty string, it would make sense that TRUE would be 1).
Plus what meze said :)
Quick look at the source code shows that this is expected behavior. But don't ask me why they did it this way...