0

The ternary false seems to have no relevance. How is it working in this example?

PHP beginner here, I have a little program that was asking for a base number and returning a cubed result. I initially wrote it with an if/else but would get “unnamed index” errors, but that was resolved by using isset(). Next issue was "A non-numeric value” for the variable passed to the pow(). I got input to use the ternary below and it now works.


    <?php

    $base = (int) (isset($_POST['base']) ? $_POST['base'] : 0); 

    if ($base) {
        echo number_format(pow($base, 3));
    }
    else {
        echo 'Please enter a number';
    }

    ?>

I’m looking for an explanation of how the false after the : is working. It doesn’t seem to matter what is there - string, int etc. I first assumed that by having 0 it was passing false to the if/else below and therefore echoing the else statement.

To follow up, I found that simply using the (is_numeric(($_POST['base']))) as suggested by @Mark Locklear in the if statement was what I was originally looking for. Going down the ternary path lead me astray, but was definitely a learning experience. Therefore the How to write a PHP ternary operator will not fully solve my original problem. Thanks

piagetblix
  • 109
  • 3
  • 1
    It's doing as you expect - it is basically saying if `$_POST['base']` is not set then put *false* into `$base` , this means they haven't entered a number - hence the code will execute `echo 'Please enter a number';` – Nigel Ren Apr 30 '19 at 16:52
  • 1
    @NigelRen, that's not correct. He's putting the integer 0 into $base, which is *equivalent* to false, but not strictly identical. If he intends for 0 to be false, he should just put `false` instead of `0` so his intent is clear. `Null` would also be clearer. – Jonathan Eltgroth Apr 30 '19 at 16:55
  • @JonathanEltgroth which is why I put false as *false*. To be honest I wouldn't write the code like this anyway - but I was trying to explain what the code they have is doing. – Nigel Ren Apr 30 '19 at 16:57
  • If you don't undersand something, try to simplify and build up. A simple start might be `` and then running that from command line or your IDE. Then add a bit, maybe `` and observe, then a bit more `` and then maybe from your web script doing `var_dump($_POST);` or `var_dump(isset($_POST['base']));` and you can understand how it all plays together. – johannes Apr 30 '19 at 16:57
  • Possible duplicate of [How to write a PHP ternary operator](https://stackoverflow.com/questions/17981723/how-to-write-a-php-ternary-operator) – miken32 Apr 30 '19 at 16:59
  • So my confusion was why changing the 0 to anything still has the same result... – piagetblix Apr 30 '19 at 17:00
  • You would probably be better of coding it as `if (isset($_POST['base'])) {` – Nigel Ren Apr 30 '19 at 17:00
  • Are you sure that `$_POST['base']` is set correctly when the request is sent? – Ice76 Apr 30 '19 at 17:01
  • Or if you really like ternaries: `echo isset($_POST['base']) ? number_format(pow($_POST['base'], 3)) : 'Please enter a number';` – miken32 Apr 30 '19 at 17:01
  • @Ice76 vardump shows the input and the cube is correct. – piagetblix Apr 30 '19 at 17:07

2 Answers2

1

First

(isset($_POST['base']) ? $_POST['base'] : 0)

evaluates to $_POST['base'] if the key base exists, 0 otherwise

Then...

$base = (int) (isset($_POST['base']) ? $_POST['base'] : 0);

...casts the result to int.

If the user enters a non numeric string (ex. ABC) or passes an empty string then $base is set to 0

Finally

if ($base) {

casts $base to boolean. Any number different from 0 is evaluated as true. 0 is evaluated as false and leads to execution of the else block.


Any input numeric and different from 0 will be cubed.

No input, a non numeric string or the value 0 will lead to Please enter a number

Paolo
  • 15,233
  • 27
  • 70
  • 91
  • @ Paolo You state "If the user enters a non numeric string (ex. ABC) or passes an empty string then $base is set to 0" but if I change the ` : 0` to some other number or string, when I `var_dump()` right after that line it doesn't return whats in that position if it's false(it returns 0). So the `0` in the code is not relevant? – piagetblix Apr 30 '19 at 18:13
  • @piagetblix if the user enters a non numeric or empty string the first expression of the ternary operator evaluates TRUE so what is present after the colon : is not relevant. In that case $base is set to 0 due to implicit conversion to integer. – Paolo Apr 30 '19 at 20:44
  • 1
    This section "...is set to 0 due to implicit conversion to integer." helped a lot! cheers – piagetblix May 01 '19 at 01:41
0

PHP is loosely typed. What that basically means that any variable can change its type at any time. You could have $base = 'zero'; which would imply it's a string, and then on the next line have $base = 0;, and PHP won't care.

You're correct in a sense that 0 is equivalent to false, and that PHP will resolve it as false, but strictly speaking 0 is an integer. If you want to flag a condition as a boolean false, to make your code clear, you should just use false instead of 0.

When dealing with If conditionals, false, 0, null, and '' will all resolve as false.

  • @Paolo and @Jonathan Eltgroth Appreciate your answers. Breaking it down like that makes it much clearer. Why though can i change the `: 0);` value to essentially anything and it still works? The value after the `:` seems to be just a placeholder or pointer to the `else` block? – piagetblix Apr 30 '19 at 17:26
  • @piagetblix, think of ternaries as simplified if/else statements. It's not a pointer to any other block of code. You're saying `if this value exists, save that value to $base, else save 0 to $base`. Then, after that, you're saying `if ($base evaluates as true) do this, else do this other thing.` – Jonathan Eltgroth Apr 30 '19 at 17:40
  • so the part after the `:` is less relevant for the function of the conditional but should clearly reflect its purpose as you said in the above "When dealing with If conditionals, false, 0, null, and '' will all resolve as false." It just testing if there was a value passed to `$base` if not, pass it as `0` to the second if/else...hope im being clear. – piagetblix Apr 30 '19 at 17:56
  • @ Jonathan Eltgroth sorry forgot to mention your name in the above comment - it was response to your previous. thanks – piagetblix Apr 30 '19 at 18:05
  • @piagetblix, thats about right. Your first expression is saying `$base is equal to the value of $_POST['base'], else the value of $base is 0`. Then after that you are just checking whether the value (or state) of $base resolves true. Another way to look at that if conditional would be `if ($base != 0) { run this code } else { run this other code}` – Jonathan Eltgroth Apr 30 '19 at 19:06