Reputation: 75
In my script a particular array element (say, $foo['bar']
) can take different values, or no value at all. A particular action is triggered if the value of $foo['bar']
is not equal to, say, 42. The following code
if (!isset($foo['bar']) || ($foo['bar'] != '42')) action()
is not ideal, because php issues a warning about when $foo['bar']
is not set.
Question: is there an elegant way to test for such condition?
Upvotes: 1
Views: 158
Reputation: 3470
Can be in this way
$bar = isset($foo['bar']) ? $foo['bar'] : NULL;
There you don't get warning and you are setting the variable.
Then you do the check
if($bar != 42 && !empty($bar)){
//do something
}
Read Ternary Operator
The expression (expr1) ? (expr2) : (expr3)
evaluates to expr2
if expr1
evaluates to TRUE
, and expr3
if expr1
evaluates to FALSE
.
Upvotes: 2
Reputation: 14501
For PHP 5.3+ you can use optimitzed version of Emilio Gort answer:
$bar = isset($foo['bar']) ?: '';
if ($bar != 42) action();
Upvotes: 1
Reputation: 577
I think this is what you want:
if (!(isset($foo['bar']) && ($foo['bar'] = '42'))) action();
Upvotes: 1
Reputation: 173562
This code:
if (!isset($foo['bar']) || $foo['bar'] != 42) {
}
Because of short-circuiting logic will actually not issue any warnings, because it skips at the first truthy condition, in this case that happens if $foo['bar']
is not defined.
This can also be seen from the opcodes that the compiler generates for your code:
compiled vars: !0 = $foo
line # * op fetch ext return operands
------------------------------------------------------------------------------
3 0 > ZEND_ISSET_ISEMPTY_DIM_OBJ 1 ~0 !0, 'bar'
1 BOOL_NOT ~1 ~0
2 > JMPNZ_EX ~1 ~1, ->6
3 > FETCH_DIM_R $2 !0, 'bar'
4 IS_NOT_EQUAL ~3 $2, 42
5 BOOL ~1 ~3
6 > > JMPZ ~1, ->8
4 7 > > JMP ->8
8 > > RETURN 1
The below opcode is important:
2 > JMPNZ_EX ~1 ~1, ->6
The inverted outcome of isset($foo['bar'])
gets checked and if truthy the code jumps over the next few statements that actually inspect the value of $foo['bar']
, thereby avoiding any notices.
This also means that if you would reverse the two operands of ||
you will get a notice and the second operand is mostly useless anyway.
Because values like 0
, false
, []
, etc. are also not equal to 42
you can use empty()
as well:
if (empty($foo['bar']) || $foo['bar'] != 42) {
}
This arguably makes the code easier to read.
Upvotes: 4