Null vs. False vs. 0 in PHP - php

I am told that good developers can spot/utilize the difference between Null and False and 0 and all the other good "nothing" entities.
What is the difference, specifically in PHP? Does it have something to do with ===?

It's language specific, but in PHP :
Null means "nothing". The var has not been initialized.
False means "not true in a boolean context". Used to explicitly show you are dealing with logical issues.
0 is an int. Nothing to do with the rest above, used for mathematics.
Now, what is tricky, it's that in dynamic languages like PHP, all of them have a value in a boolean context, which (in PHP) is False.
If you test it with ==, it's testing the boolean value, so you will get equality. If you test it with ===, it will test the type, and you will get inequality.
So why are they useful ?
Well, look at the strrpos() function. It returns False if it did not found anything, but 0 if it has found something at the beginning of the string !
<?php
// pitfall :
if (strrpos("Hello World", "Hello")) {
// never exectuted
}
// smart move :
if (strrpos("Hello World", "Hello") !== False) {
// that works !
}
?>
And of course, if you deal with states:
You want to make a difference between DebugMode = False (set to off), DebugMode = True (set to on) and DebugMode = Null (not set at all, will lead to hard debugging ;-)).

null is null. false is false. Sad but true.
there's not much consistency in PHP (though it is improving on latest releases, there's too much backward compatibility). Despite the design wishing some consistency (outlined in the selected answer here), it all get confusing when you consider method returns that use false/null in not-so-easy to reason ways.
You will often see null being used when they are already using false for something. e.g. filter_input(). They return false if the variable fails the filter, and null if the variable does not exists (does not existing means it also failed the filter?)
Methods returning false/null/string/etc interchangeably is a hack when the author care about the type of failure, for example, with filter_input() you can check for ===false or ===null if you care why the validation failed. But if you don't it might be a pitfall as one might forget to add the check for ===null if they only remembered to write the test case for ===false. And most php unit test/coverage tools will not call your attention for the missing, untested code path!
Lastly, here's some fun with type juggling. not even including arrays or objects.
var_dump( 0<0 ); #bool(false)
var_dump( 1<0 ); #bool(false)
var_dump( -1<0 ); #bool(true)
var_dump( false<0 ); #bool(false)
var_dump( null<0 ); #bool(false)
var_dump( ''<0 ); #bool(false)
var_dump( 'a'<0 ); #bool(false)
echo "\n";
var_dump( !0 ); #bool(true)
var_dump( !1 ); #bool(false)
var_dump( !-1 ); #bool(false)
var_dump( !false ); #bool(true)
var_dump( !null ); #bool(true)
var_dump( !'' ); #bool(true)
var_dump( !'a' ); #bool(false)
echo "\n";
var_dump( false == 0 ); #bool(true)
var_dump( false == 1 ); #bool(false)
var_dump( false == -1 ); #bool(false)
var_dump( false == false ); #bool(true)
var_dump( false == null ); #bool(true)
var_dump( false == '' ); #bool(true)
var_dump( false == 'a' ); #bool(false)
echo "\n";
var_dump( null == 0 ); #bool(true)
var_dump( null == 1 ); #bool(false)
var_dump( null == -1 ); #bool(false)
var_dump( null == false ); #bool(true)
var_dump( null == null ); #bool(true)
var_dump( null == '' ); #bool(true)
var_dump( null == 'a' ); #bool(false)
echo "\n";
$a=0; var_dump( empty($a) ); #bool(true)
$a=1; var_dump( empty($a) ); #bool(false)
$a=-1; var_dump( empty($a) ); #bool(false)
$a=false; var_dump( empty($a) ); #bool(true)
$a=null; var_dump( empty($a) ); #bool(true)
$a=''; var_dump( empty($a) ); #bool(true)
$a='a'; var_dump( empty($a)); # bool(false)
echo "\n"; #new block suggested by #thehpi
var_dump( null < -1 ); #bool(true)
var_dump( null < 0 ); #bool(false)
var_dump( null < 1 ); #bool(true)
var_dump( -1 > true ); #bool(false)
var_dump( 0 > true ); #bool(false)
var_dump( 1 > true ); #bool(true)
var_dump( -1 > false ); #bool(true)
var_dump( 0 > false ); #bool(false)
var_dump( 1 > true ); #bool(true)

Below is an example:
Comparisons of $x with PHP functions
Expression gettype() empty() is_null() isset() boolean : if($x)
$x = ""; string TRUE FALSE TRUE FALSE
$x = null; NULL TRUE TRUE FALSE FALSE
var $x; NULL TRUE TRUE FALSE FALSE
$x is undefined NULL TRUE TRUE FALSE FALSE
$x = array(); array TRUE FALSE TRUE FALSE
$x = false; boolean TRUE FALSE TRUE FALSE
$x = true; boolean FALSE FALSE TRUE TRUE
$x = 1; integer FALSE FALSE TRUE TRUE
$x = 42; integer FALSE FALSE TRUE TRUE
$x = 0; integer TRUE FALSE TRUE FALSE
$x = -1; integer FALSE FALSE TRUE TRUE
$x = "1"; string FALSE FALSE TRUE TRUE
$x = "0"; string TRUE FALSE TRUE FALSE
$x = "-1"; string FALSE FALSE TRUE TRUE
$x = "php"; string FALSE FALSE TRUE TRUE
$x = "true"; string FALSE FALSE TRUE TRUE
$x = "false"; string FALSE FALSE TRUE TRUE
Please see this for more reference of type comparisons in PHP. It should give you a clear understanding.

In PHP you can use === and !== operators to check not only if the values are equal but also if their types match. So for example: 0 == false is true, but 0 === false is false. The same goes for != versus !==. Also in case you compare null to the other two using the mentioned operators, expect similar results.
Now in PHP this quality of values is usually used when returning a value which sometimes can be 0 (zero), but sometimes it might be that the function failed. In such cases in PHP you return false and you have to check for these cases using the identity operator ===. For example if you are searching for a position of one string inside the other and you're using strpos(), this function will return the numeric position which can be 0 if the string is found at the very beginning, but if the string is not found at all, then strpos() will return false and you have to take this into account when dealing with the result.
If you will use the same technique in your functions, anybody familiar with the standard PHP library will understand what is going on and how to check if the returned value is what is wanted or did some error occur while processing. The same actually goes for function params, you can process them differently depending on if they are arrays or strings or what not, and this technique is used throughout PHP heavily too, so everybody will get it quite easily. So I guess that's the power.

False, Null, Nothing, 0, Undefined, etc., etc.
Each of these has specific meanings that correlate with actual concepts. Sometimes multiple meanings are overloaded into a single keyword or value.
In C and C++, NULL, False and 0 are overloaded to the same value.
In C# they're 3 distinct concepts.
null or NULL usually indicates a lack of value, but usually doesn't specify why.
0 indicates the natural number zero and has type-equivalence to 1, 2, 3, etc. and in languages that support separate concepts of NULL should be treated only a number.
False indicates non-truth. And it used in binary values. It doesn't mean unset, nor does it mean 0. It simply indicates one of two binary values.
Nothing can indicate that the value is specifically set to be nothing which indicates the same thing as null, but with intent.
Undefined in some languages indicates that the value has yet to be set because no code has specified an actual value.

I have just wasted 1/2 a day trying to get either a 0, null, false to return from strops!
Here's all I was trying to do, before I found that the logic wasn't flowing in the right direction, seeming that there was a blackhole in php coding:
Concept
take a domain name hosted on a server, and make sure it's not root level, OK several different ways to do this, but I chose different due to other php functions/ constructs I have done.
Anyway here was the basis of the cosing:
if (strpos($_SERVER ['SERVER_NAME'], dirBaseNAME ())
{
do this
} else {
or that
}
{
echo strpos(mydomain.co.uk, mydomain);
if ( strpos(mydomain, xmas) == null )
{
echo "\n1 is null";
}
if ( (strpos(mydomain.co.uk, mydomain)) == 0 )
{
echo "\n2 is 0";
} else {
echo "\n2 Something is WRONG";
}
if ( (mydomain.co.uk, mydomain)) != 0 )
{
echo "\n3 is 0";
} else {
echo "\n3 it is not 0";
}
if ( (mydomain.co.uk, mydomain)) == null )
{
echo "\n4 is null";
} else {
echo "\n4 Something is WRONG";
}
}
FINALLY after reading this Topic,
I found that this worked!!!
{
if ((mydomain.co.uk, mydomain)) !== false )
{
echo "\n5 is True";
} else {
echo "\n5 is False";
}
}
Thanks for this article, I now understand that even though it's Christmas, it may not be Christmas as false, as its also can be a NULL day!
After wasting a day of debugging some simple code, wished I had known this before, as I would have been able to identify the problem, rather than going all over the place trying to get it to work. It didn't work, as False, NULL and 0 are not all the same as True or False or NULL?

From the PHP online documentation:
To explicitly convert a value to boolean, use the (bool) or (boolean) casts.
However, in most cases the cast is unncecessary, since a value will be automatically converted if an operator, function or control structure requires a boolean argument.
When converting to boolean, the following values are considered FALSE:
the boolean FALSE itself
the integer ``0 (zero)
the float 0.0 (zero)
the empty string, and the string "0"
an array with zero elements
an object with zero member variables (PHP 4 only)
the special type NULL (including unset variables)
SimpleXML objects created from empty tags
Every other value is considered TRUE (including any resource).
So, in most cases, it's the same.
On the other hand, the === and the ==are not the same thing. Regularly, you just need the "equals" operator. To clarify:
$a == $b //Equal. TRUE if $a is equal to $b.
$a === $b //Identical. TRUE if $a is equal to $b, and they are of the same type.
For more information, check the "Comparison Operators" page in the PHP online docs.
Hope this helps.

The differences between these values always come down to detailed language-specific rules. What you learn for PHP isn't necessarily true for Python, or Perl, or C, etc. While it is valuable to learn the rules for the language(s) you're working with, relying on them too much is asking for trouble. The trouble comes when the next programmer needs to maintain your code and you've used some construct that takes advantage of some little detail of Null vs. False (for example). Your code should look correct (and conversely, wrong code should look wrong).

Null is used in databases to represent "no record" or "no information". So you might have a bit field that describes "does this user want to be sent e-mails by us", where True means they do, False means they don't want to be sent anything, but Null would mean that you don't know. They can come about through outer joins and suchlike.
The logical implications of Null are often different - in some languages NULL is not equal to anything, so if(a == NULL) will always be false.
So personally I'd always initialise a boolean to FALSE, and initialising one to NULL would look a bit icky (even in C where the two are both just 0... just a style thing).

I think bad developers find all different uses of null/0/false in there code.
For example, one of the most common mistakes developers make is to return error code in the form of data with a function.
// On error GetChar returns -1
int GetChar()
This is an example of a sugar interface. This is exsplained in the book "Debuging the software development proccess" and also in another book "writing correct code".
The problem with this, is the implication or assumptions made on the char type. On some compilers the char type can be non-signed. So even though you return a -1 the compiler can return 1 instead. These kind of compiler assumptions in C++ or C are hard to spot.
Instead, the best way is not to mix error code with your data. So the following function.
char GetChar()
now becomes
// On success return 1
// on failure return 0
bool GetChar(int &char)
This means no matter how young the developer is in your development shop, he or she will never get this wrong. Though this is not talking about redudancy or dependies in code.
So in general, swapping bool as the first class type in the language is okay and i think joel spoke about it with his recent postcast. But try not to use mix and match bools with your data in your routines and you should be perfectly fine.

In PHP it depends on if you are validating types:
(
( false !== 0 ) && ( false !== -1 ) && ( false == 0 ) && ( false == -1 ) &&
( false !== null ) && ( false == null )
)
Technically null is 0x00 but in PHP ( null == 0x00 ) && ( null !== 0x00 ).
0 is an integer value.

One interesting fact about NULL in PHP: If you set a var equal to NULL, it is the same as if you had called unset() on it.
NULL essentially means a variable has no value assigned to it; false is a valid Boolean value, 0 is a valid integer value, and PHP has some fairly ugly conversions between 0, "0", "", and false.

Null is nothing, False is a bit, and 0 is (probably) 32 bits.
Not a PHP expert, but in some of the more modern languages those aren't interchangeable. I kind of miss having 0 and false be interchangeable, but with boolean being an actual type you can have methods and objects associated with it so that's just a tradeoff. Null is null though, the absence of anything essentially.

Well, I can't remember enough from my PHP days to answer the "===" part, but for most C-style languages, NULL should be used in the context of pointer values, false as a boolean, and zero as a numeric value such as an int. '\0' is the customary value for a character context. I usually also prefer to use 0.0 for floats and doubles.
So.. the quick answer is: context.

In pretty much all modern languages, null logically refers to pointers (or references) not having a value, or a variable that is not initialized. 0 is the integer value of zero, and false is the boolean value of, well, false. To make things complicated, in C, for example, null, 0, and false are all represented the exact same way. I don't know how it works in PHP.
Then, to complicate things more, databases have a concept of null, which means missing or not applicable, and most languages don't have a direct way to map a DBNull to their null. Until recently, for example, there was no distinction between an int being null and being zero, but that was changed with nullable ints.
Sorry to make this sound complicated. It's just that this has been a harry sticking point in languages for years, and up until recently, it hasn't had any clear resolution anywhere. People used to just kludge things together or make blank or 0 represent nulls in the database, which doesn't always work too well.

False and 0 are conceptually similar, i.e. they are isomorphic. 0 is the initial value for the algebra of natural numbers, and False is the initial value for the Boolean algebra.
In other words, 0 can be defined as the number which, when added to some natural number, yields that same number:
x + 0 = x
Similarly, False is a value such that a disjunction of it and any other value is that same value:
x || False = x
Null is conceptually something totally different. Depending on the language, there are different semantics for it, but none of them describe an "initial value" as False and 0 are. There is no algebra for Null. It pertains to variables, usually to denote that the variable has no specific value in the current context. In most languages, there are no operations defined on Null, and it's an error to use Null as an operand. In some languages, there is a special value called "bottom" rather than "null", which is a placeholder for the value of a computation that does not terminate.
I've written more extensively about the implications of NULL elsewhere.

Somebody can explain to me why 'NULL' is not just a string in a comparison instance?
$x = 0;
var_dump($x == 'NULL'); # TRUE !!!WTF!!!

The issues with falsyness comes from the PHP history. The problem targets the not well defined scalar type.
'*' == true -> true (string match)
'*' === true -> false (numberic match)
(int)'*' == true -> false
(string)'*' == true -> true
PHP7 strictness is a step forward, but maybe not enough. https://web-techno.net/typing-with-php-7-what-you-shouldnt-do/

Related

PHP - What is the difference between '!== false' and ' == true'?

Sometimes I see people write conditional statements like this:
if($var !== false) {...}
Instead of like this:
if($var == true) {...}
These are the same, right?
I see the former used much more frequently and am wondering if there is a reason behind this, or if it is just personal preference.
I appreciate that this might be opinion based, but I am curious to see if there is a legitimate reason behind this.
This:
if($var !== false) {...}
will only evaluate to false if $var is exactly false. It will not evaluate to false if $var is any other value, whether 'false-y' or not.
This:
if($var == true) {...}
will evaluate to false for any 'false-y' value. e.g. 0, '0'.
In addition this:
if($var === true) {...}
will evaluate to true only if $var is exactly set to true, not other 'truthy-y' values.
So you are correct that they are the same if you know $var is exclusively one of either true or false, but they behave differently for other values.
$var !== false could be used for something other than readability or personal preference. Various PHP functions are expected to return false in case of error and they might as well return a falsy value on success. Take strpos for example:
Returns the position of where the needle exists relative to the
beginning of the haystack string (independent of offset). Also note
that string positions start at 0, and not 1.
Returns FALSE if the needle was not found.
This means the function can return an integer, even 0 if the needle was found at the beginning, and false if needle was not found. You have to use !== false to check if the expression is false, not falsy.
They're not the same.
!== is a strict comparison that compares value and type. $var has to equal (bool) false. This means if a string of 'false' was returned it would fail.
== is a loose comparison that just checks the value. This means $var can equal '(string) string' and be true. When checking a var like this:
if ($var == true) {
}
you check if $var has anything in it/defined. As long as something is a against it (and doesn't equal (bool) false) it will pass the conditional. This means '(string) false' would pass that conditional.
Worth nothing some functions (like strpos) return (bool) false so doing the first one (IMO) is better for those sort of functions.
When you use ==
First, it typecast the variable and compare are those values same.
You can see in the following example
var_dump(0==FALSE); // ( 0 == ( int ) false ) bool(true)
var_dump(0=='anystring'); // ( 0 == ( int ) 'anystring' ) bool(true)
When you use ===
It compares the value and types too
So it would be something like
var_dump( gettype( 0 ) == gettype( false ) && 0 == false )
This is faster in case if your type check fails Since it has not to typecast the value for further 'value check' if type check fails.

Logic in PHP, why is this happening?

function x() {return -1;}
echo x();
echo "<br>";
if(x()) {echo "True";} else {echo "False";}
output:
-1
True
Why am I getting 'True' outputted, surely the if() test would fail as it's negative?
That's because you can only test on true or false.
False is defined as 0, while true is defined as not 0. So -1 is just as much true as 1, 2, 3 etc.
To make sure you're getting the right result, make a real comparison.
-1 is considered TRUE in boolean context. See Converting to boolean in the PHP manual.
Only numeric 0 values are false in PHP: http://php.net/manual/en/language.types.boolean.php
0 is false and everything else is true. That's why !
In PHP a -1 is true as it isn't 0. Use a real comparison like:
if(x() <= 0) { ...do stuff... }
Have a look here:
var_dump(x()); //output: int(-1)
and casted to boolean:
var_dump((bool)x()); //output: bool(true)
-1 is not false in PHP. You could check if it's > 0?
All what is 0 is false and everything else is true. Wikipedia article about it
Converting to boolean in PHP
To explicitly convert a value to boolean, use the (bool) or (boolean) casts. However, in most cases the cast is unnecessary, since a value will be automatically converted if an operator, function or control structure requires a boolean argument.
See also Type Juggling.
When converting to boolean, the following values are considered FALSE:
the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the string "0"
an array with zero elements
an object with zero member variables (PHP 4 only)
the special type NULL (including unset variables)
SimpleXML objects created from empty tags
Every other value is considered TRUE (including any resource).
Warning
-1 is considered TRUE, like any other non-zero (whether negative or positive) number!
Source http://www.php.net/manual/en/language.types.boolean.php#language.types.boolean.casting

Difference between "true == isset($variable)" and "isset($variable) == true" in php

I was just wandering the about the concept of equating the condition in PHP that is,
what could be the difference between
true == isset($variable)
and
isset($variable) == true
?
For this specific case, no difference.
The first syntax is used to prevent accidental assignment instead of comparison.
if ( true = $x ) // would yiled error
if ( $x = true ) // would work
But again, in your case, no difference.
Elaboration:
Say you want to compare a variable $x to true and do something. You could accidentally write
if ( $x = true )
instead of
if ( $x == true )
and the condition would always pass.
But if you get into the habit of writing
if ( true == $x )
these mistakes wouldn't happen, since a syntax error would be generated and you would know in advance.
There is no difference. But isset() itself returns a boolean value.
So never use
if (true == isset($variable))
Just:
if (isset($variable))
Remember that when php parses that true is actually defined and its equal to 1. Furthermore so is false and it is equal to 0. php automatically checks these for comparison with these values in an IF statement. You'll be safe using the ! operator, because its the same as if ($something == false) good luck!
Would it be Java, there was difference.
i.e.
String test = null;
if("".equals(test)){
System.out.println("I m fine..");
}
if(test.equals("")){
System.out.println("I m not fine..");
}
There is no "real" diffrences(in this case)
Between
true == isset($variable) AND
isset($variable) == true

How is `if (!integer) {}` evaluated?

I came across this code in a php database class:
if( !$this->_Link_ID )
Link_ID is an integer.
So does this code just check if Link_ID is not 0?
I know from experience that if a variable is type Boolean, you can just test the var like
$myBoolean = true;
if ($myBoolean){
// code
}
I didn't realise this can be done for integers.
So how is if( !$this->_Link_ID ) evaluated?
It checks if the integer is zero if it's integer. It also evaluates to truth if it's set to null and if it's unset, but in the latter case it also spits out a warning. if there was no negation, that would be a test for non-zero.
For more details see: converting to boolean:
When converting to boolean, the following values are considered FALSE:
the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the string "0"
an array with zero elements
an object with zero member variables (PHP 4 only)
the special type NULL (including unset variables)
SimpleXML objects created from empty tags
Every other value is considered TRUE (including any resource).
this is simply a silly way of check for non-zero,if LINK_ID is 0 or null or false ,it will
give true(please notice the '!') ,else if the LINK_iD is any thing it will give false
LINK_iD = 1 ,if (!LINK_ID) //this will give false
LINK_ID = 0 if (!LINK_iD) //this will give true
if( !$this->_Link_ID )
will return true if the value of $this->_Link_ID is 0, empty string or null.
If you want to check explicitly for "0" then you should use the triple equal ("===" or "!==") to test the value. like so
if($this->_Link_ID === 0)
or
if($this->_Link_ID === false)
if you only want it to return true for false, but not "0".
if (!$this->_Link_ID) will be true if $this->_Link_ID is not 0, and false if it is 0.
In PHP, you can test anything as a Boolean. A Boolean can be represented as 0 or 1, with 0 being false and 1 being true. In PHP, anything that is not 0 will be true, and anything that is 0 will be false. For example:
$string = 'This is a test.'
if ($string) echo 'Evaluated to true!';
Will print 'Evaluated to true!'. If $string does not exist, it will print nothing.
you should use
if (!is_int($var))
because
if (!$var)
checks if $var is not 0 or false
and if you want to check if $var exists you need to use this:
if (isset($var))
not only integers though
Here goes an explanation http://php.net/manual/en/language.types.type-juggling.php
And here goes a cheat-sheet http://www.php.net/manual/en/types.comparisons.php

PHP's variable type leniency

The most recent comment on PHP's in_array() help page (http://uk.php.net/manual/en/function.in-array.php#106319) states that some unusual results occur as a result of PHP's 'leniency on variable types', but gives no explanation as to why these results occur. In particular, I don't follow why these happen:
// Example array
$array = array(
'egg' => true,
'cheese' => false,
'hair' => 765,
'goblins' => null,
'ogres' => 'no ogres allowed in this array'
);
// Loose checking (this is the default, i.e. 3rd argument is false), return values are in comments
in_array(763, $array); // true
in_array('hhh', $array); // true
Or why the poster thought the following was strange behaviour
in_array('egg', $array); // true
in_array(array(), $array); // true
(surely 'egg' does occur in the array, and PHP doesn't care whether it's a key or value, and there is an array, and PHP doesn't care if it's empty or not?)
Can anyone give any pointers?
763 == true because true equals anything not 0, NULL or '', same thing for array because it is a value (not an object).
To circumvent this problem you should pass the third argument as TRUE to be STRICT and thus, is_rray will do a === which is a type equality so then
763 !== true
and neither will array() !== true
Internally, you can think of the basic in_array() call working like this:
function in_array($needle, $haystack, $strict = FALSE) {
foreach ($haystack as $key => $value) {
if ($strict === FALSE) {
if ($value == $needle) {
return($key);
}
} else {
if ($value === $needle) {
return($key);
}
}
return(FALSE);
}
note that it's using the == comparison operator - this one allows typecasting. So if your array contains a simple boolean TRUE value, then essentially EVERYTHING your search for with in_array will be found, and almost everything EXCEPT the following in PHP can be typecast as true:
'' == TRUE // false
0 == TRUE // false
FALSE == TRUE // false
array() == TRUE // false
'0' == TRUE // false
but:
'a' == TRUE // true
1 == TRUE // true
'1' == TRUE // true
3.1415926 = TRUE // true
etc...
This is why in_array has the optional 3rd parameter to force a strict comparison. It simply makes in_array do a === strict comparison, instead of ==.
Which means that
'a' === TRUE // FALSE
PHP treating arrays as primitive values is a constant source of pain as they can be very complex data structures, it doesn't make any sense. For example, if you assign array to something, and then modify the array, the original isn't modified, instead it is copied.
<?php
$arr = array(
"key" => NULL
);
var_dump( array() == NULL ); //True :(
var_dump( in_array( array(), $arr ) ); //True, wtf? It's because apparently array() == NULL
var_dump( in_array( new stdClass, $arr ) ); //False, thank god
?>
Also, 'egg' is not a value in the array, it's a key, so of course it's surprising that it would return true. This kind of behavior is not ok in any other language I know about, so it will trip over many people who don't know php quirks inside out.
Even a simple rule that an empty string is falsy, is violated in php:
if( "0" ) {
echo "hello"; //not executed
}
"0" is a non-empty string by any conceivable definition, yet it is a falsy value.

Categories