1

My php variable has 3 possible values assigned, depending on a value of $_POST variable. Possible values are 'YES','NO' and 0 (zero). I'm trying to convert 0 to null value but end up converting 'YES' and 'NO' values to null as well.

echo $used; 
//outputs: YES

echo gettype($used);
//outputs: string

//so far it works fine

if($used == 0)
{
    $used = null;
}

echo $used; 
//outputs:

echo gettype($used);
//outputs: null

//So it converted my variable to null.

//I could probably try a workaround by doing
if($used != 'YES' && $used != 'NO')
{
    $used = null;
}

//or maybe even using =='0' in the conditional but I prefer to learn why this is happening before moving forward

I found Null vs. False vs. 0 in PHP and it seems that my problem might be in == 0 but I'm not sure. Thank you in advance.

Mike
  • 39
  • 5
  • It may help to compare along with type using === , like $used === 0 , this will also verify the type. This will avoid any pitfalls in terms of type conversion issues. – Althaf M Jan 07 '19 at 05:41
  • Really do avoid using `==` except you exactly know what you are doing and there is no easy alternative. It is very hard to overview implicit type casting precedence and the code gets hard readable on review. Furthermore we do not know if some future version improve the behaviour to be more consistent. Even `'true'` (implicitly) casted to an integer is `0`, `'3true'` is casted to int `3`. Casted to boolean every non-empty string is `true`. – Pinke Helga Jan 07 '19 at 06:19
  • `'false' == false` is false. Btw. if you have set the value by `$used = $_POST['used']`, expect the value to be `'0'` but `0`, i.e. a string. – Pinke Helga Jan 07 '19 at 06:36
  • Lwin Maung Maung posted a link, that lead me to another page, [link](http://php.net/manual/en/types.comparisons.php) which shows the tables for strict and loose comparisons in PHP. That + the answers and comments here helped me to understand what is happening. – Mike Jan 08 '19 at 00:48

3 Answers3

3

Always use the identical operator instead of the equality operator when dealing with more than one type.

Identical is when You compare with ===

Equal is when You compare with ==

Check for equality ONLY and ONLY if You are 100% sure that You are dealing with ONE type.

if ($used == 0) { $used = null; } // Not like this
if ($used === 0) { $used = null; } // .. but like this
Pinke Helga
  • 6,378
  • 2
  • 22
  • 42
Spooky
  • 1,235
  • 15
  • 17
  • Related reading: http://php.net/manual/en/language.operators.comparison.php – Marty Jan 07 '19 at 05:44
  • *"Check for equality ONLY and ONLY if You are 100% sure that You are dealing with ONE type"* That would be exactly a case where the identical operator `should` be used. The equality operator is for implicit type casting when you exactly know the possible values, e.g. when for some reason an input from a 3rd party library can be `100` or `'100'` as well (which should not happen in your own code), not to safe one character when coding. – Pinke Helga Jan 07 '19 at 06:48
  • I am hanging with PHP for almost 10 yrs. And if You ask me, in PHP, equality operator should be avoided, should be removed, or it should behave just like when we use identical operator. – Spooky Jan 07 '19 at 18:17
  • Other than that, I think that You have misunderstood what I wrote, here: "one type" meaning variable that is either string TYPE or integer TYPE, etc. and the person knows for sure which type it is, but doesn't know the value it holds. – Spooky Jan 07 '19 at 18:24
1

0 and NULL are both treated as false... whereas the 'YES' and 'NO' strings are treated as true.

So instead of $used == 0, why not look for the false?

Edit: I realise I read your question incorrectly, you are using == operator, so YES/NO as an integer are 0. So in your condition, look explicitly for a numeric value first, see below:

Example:

echo $used; 
//outputs: YES

echo gettype($used);
//outputs: string

// Now explicitly look for numeric values, and compare the integer
if(is_numeric($used) AND (int)$used === 0) $used = null;
Jonathan
  • 510
  • 3
  • 12
1

This is already discussed in here.

This is happened because "YES" or "NO" or any other strings cannot be literally converted to integer value.

So when converting any strings except "123" or any double quoted String will become false. That's why your code $used == 0 will leads to true.

$YES->false->0 == 0.

If you want to replace 0 to null, my current workaround is if (is_int($used)) because you have only 0 to catch.

I hope that will be solved. Thank you.

update: use '===' instead of '=='

  • 1
    Thank you for that link, it lead me to another page, [link](http://php.net/manual/en/types.comparisons.php) which shows the tables for strict and loose comparisons in PHP. Now I understand what is happening. – Mike Jan 08 '19 at 00:37