简体   繁体   中英

Ternary operator - unexpected behavior

I have a Product class which retrieves database data by the product name. The URL would look like this:

/products/product-name

My class works fine and retrieves product data when this method is function is executed:

$library->get('Router')->map('GET|POST', '/products/[*:product]', function($prod) use ($library){
    require_once(_DIR_ . 'lib/Product.php');
    $p = new Product($prod);
    $state = $p->prepare();
    require_once(_DIR_ . $state ? "views/product.php" : "views/404.php");
});

Only, when the $state is false, the required file is the product.php file not the 404.php file.

I have debugged this and the $state IS false when there is no product so my method is returning the correct bool, only, the ternary operator seems to run the TRUE each time.

If I change the expression to this:

require_once(_DIR_ . $state === TRUE ? "views/product.php" : "views/404.php");

It works fine, can someone explain why this is happening? If I was to do:

$example = false;
echo ($example) ? 'yes' : 'no';

It works, so why is it behaving this way?

Also,

require_once(_DIR_ . $p->prepare() === TRUE ? "views/product.php" : "views/404.php");

Does not work, this runs false everytime...

Because . has precedence over the ternary operator, you need to use parentheses:

require_once(_DIR_ . ($state ? "views/product.php" : "views/404.php"));

In the first require_once(_DIR_ . $state ? "views/product.php" : "views/404.php"); you don't eval a condition so the ternary not return the proper value

In the second

require_once(_DIR_ . $state === TRUE ? "views/product.php" : "views/404.php");

you clearly test a valid condition and the ternary operator can work correctly

 _DIR_ . $state 

is not a condition is an assertion

Only, when the $state is false, the required file is the product.php file not the 404.php file.

But you're not testing just $state , you're testing the result of the concatenation of _DIR_ and $state .

Since _DIR_ will always return a truthy value, the collective result is never false.

This is not your intention, of course; as @trincot notes, the _DIR_ reference is part of the require path, not the condition. So use parentheses to distinguish the two:

require_once(_DIR_.($state ? "views/product.php" : "views/404.php"));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM