36

I've been trying to use isset() in nested form like below:

isset($_POST['selectedTemplate'])?$_POST['selectedTemplate']:isset($_GET['selectedTemplate'])?$_GET['selectedTemplate']:0

But seems I'm missing something. Can anyone assist me how to do it?

Joseph Silber
  • 214,931
  • 59
  • 362
  • 292
sikas
  • 5,435
  • 28
  • 75
  • 120
  • 16
    Please don't use one-liners for that. It's unreadable. – PeeHaa Jan 04 '12 at 22:56
  • 2
    Nesting the ternary operator really isn't recommended because it is completely non-intuitive: if you need to nest, you really should use full if/else syntax because it's much easier to read both for yourself and others – Mark Baker Jan 04 '12 at 22:58
  • 1
    This bears the question why your form can be submitted via POST and GET in the first place. [HTTP verbs have certain semantics to them.](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html). – Gordon Jan 04 '12 at 23:13

7 Answers7

69

Wrap it in parentheses:

$selectedTemplate = isset($_POST['selectedTemplate'])
                  ? $_POST['selectedTemplate']
                  : (
                       isset($_GET['selectedTemplate'])
                       ? $_GET['selectedTemplate']
                       : 0
                  );

Or even better, use a proper if/else statement (for maintainability):

$selectTemplate = 0;

if (isset($_POST['selectedTemplate'])) {
    $selectTemplate = $_POST['selectedTemplate'];
} elseif (isset($_GET['selectedTemplate'])) {
    $selectTemplate = $_GET['selectedTemplate'];
}

However, as others have pointed out: it would simply be easier for you to use $_REQUEST:

$selectedTemplate = isset($_REQUEST['selectedTemplate'])
                  ? $_REQUEST['selectedTemplate']
                  : 0;
Joseph Silber
  • 214,931
  • 59
  • 362
  • 292
  • 2
    Just a note: `$_REQUEST` takes more than `$_POST` and `$_GET` and the order can vary. – hakre Jan 04 '12 at 23:12
  • 1
    Cheers. Exactly what I needed, I did not know you had to wrap the whole second part of the statement in parenthesis. – Barry Chapman Feb 06 '14 at 06:48
  • Good on the maintainability. – johnny Aug 24 '15 at 14:35
  • C/C++ don't need parens for nested ?:, https://stackoverflow.com/q/18237432/2097284, so someone who comes to PHP from there gets a surprise. – Camille Goudeseune May 17 '19 at 20:32
  • 2
    @CamilleGoudeseune - C/C++ uses right-associativity by default for ternary expressions, while PHP uses left-associativity by default. In reality, left-associativity is almost never what you want, so PHP's default doesn't really make much sense. In fact, [this is being deprecated in PHP 7.4](https://wiki.php.net/rfc/ternary_associativity). – Joseph Silber May 28 '19 at 12:55
  • Finally - The bug is now "deprecated". And will be fixed in like 20 years (version 9.0?). – Paul Spiegel Jul 29 '19 at 13:55
10

As of PHP 7 we can use Null coalescing operator

$selectedTemplate = $_POST['selectedTemplate'] ?? $_GET['selectedTemplate'] ?? 0;
Risul Islam
  • 804
  • 1
  • 12
  • 24
Adersh
  • 598
  • 1
  • 9
  • 22
5

A little investigate here, and I guess, I've found real answer :)

Example code:

<?php

$test = array();
$test['a'] = "value";


var_dump(
    isset($test['a'])
        ? $test['a']
        : isset($test['b'])
            ? $test['b']
            : "default"
);

Be attentive to round brackets, that I've put.

I guess, you're waiting to get similar behavior:

var_dump(
    isset($test['a'])
        ? $test['a']
        : (isset($test['b'])  // <--  here
            ? $test['b']
            : "default")      // <--  and here
);

But! Real behavior looks like this:

var_dump(
    (isset($test['a'])        // <--  here
        ? $test['a']
        : isset($test['b']))  // <--  and here
            ? $test['b']
            : "default"
);

General mistake was, that you've missed notice: Undefined index.

Online shell.

Sergey Chizhik
  • 617
  • 11
  • 22
4

It's simpler to read if we write ternary in the following manner:

$myvar = ($x == $y)
  ?(($x == $z)?'both':'foo')
  :(($x == $z)?'bar':'none');

But ternary operators are short, effective ways to write simple if statements. They are not built for nesting. :)

spex
  • 1,110
  • 10
  • 21
Govind Totla
  • 1,128
  • 13
  • 16
3

You might have an easier time simply using the $_REQUEST variables:

"$_REQUEST is an associative array that by default contains the contents of $_GET, $_POST and $_COOKIE."

http://us2.php.net/manual/en/reserved.variables.request.php

Fletch
  • 963
  • 6
  • 15
2

I believe this will work:

$test = array();
$test['a'] = 123;
$test['b'] = NULL;


$var = (isset($test['a']) ? $test['a'] : (!isnull($test['b']) ? $test['b'] : "default"));

echo $var;
Carlos
  • 21
  • 1
1

Instead of the ternary with the ambiguous precedence, you could just use $_REQUEST instead of the fiddly $_GET and $_POST probing:

 isset($_REQUEST['selectedTemplate']) ? $_REQUEST['selectedTemplate'] : 0

This is precisely what it is for.

mario
  • 144,265
  • 20
  • 237
  • 291