user1467267
user1467267

Reputation:

Letting a PHP ternary operator refer to itself

I sometimes get very tired that PHP always wants it's fully reference in a ternary operator, giving your horrors like these;

$qb->records[$k]['Claimed'] = ($qb->records[$k]['Claimed'] === 1 ? $qb->records[$k]['Claimed'] : '0');

Is there a way to simply put refer to the current modified variable (object)? For example;

$qb->records[$k]['Claimed'] = (self === 1 ? self ? '0');

Please don't look at the code itself. It's not about the example's code working. It's purely about the possiblity of a SELF-reference without an extra modification. A DEFINE method would be nice too, but I guess PHP can't make complex DEFINEs like, for example, Objective-C can.

Also I'm aware of styles like so;

foreach ($qb->records as $k => &$v) { ... }

..but I dont' want that method in a pre-defined state.

Upvotes: 10

Views: 811

Answers (5)

dcro
dcro

Reputation: 13649

To answer the original question:

In PHP you can not reference the variable you are assigning the value to, as you apparently would in Python or other languages.

That being said, in PHP 5.3 they is a way to shorten the ternary operator in certain usages. From the PHP Doc :

Since PHP 5.3, it is possible to leave out the middle part of the ternary operator.

Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.

So you could use something like:

$result = ($qb->records[$k]['Claimed'] ?: 0);

if you want the value from $qb->records[$k]['Claimed'] when that value evaluates to TRUE.

Also, strictly relating to the original code example, where the value === 1 comparison was used, and without having anything to do with the ternary operator, you could rewrite the condition as:

$result = (int) ($qb->records[$k]['Claimed'] === 1);

This will return 1 when $qb->records[$k]['Claimed'] is 1, and 0 otherwise.

Upvotes: 5

MC Emperor
MC Emperor

Reputation: 22997

Another idea is to make a function which does the trick:

function setval(&$val, $desired, $default) {
    if ($val != $desired) {
        $val = $default;
    }
}

$val is passed by reference, so it is affected by the function; $desired is the desired value of the comparison; $default is the value when the desired value is not met.

Example:

setval($qb->records[$k]['Claimed'], 1, '0');

For the rest indeed: the condition ?: else shorthand if-else is the closest you'll get...

Upvotes: 1

Glavić
Glavić

Reputation: 43552

SELF-referenced pointer like you described doesn't exist. If you want shorter code, you can save long-named variable reference into new variable $v and use that variable in your if statements:

$qb['records']['k']['Claimed'] = 'test';
$v = &$qb['records']['k']['Claimed'];

$v = $v === 'test' ? $v . ' extra' : null;
unset($v);

print_r($qb);

Upvotes: 0

Jon
Jon

Reputation: 437386

Unfortunately there's not much you can do.

The best I could ever get was introducing a temporary variable inline, which reduces the number of occurrences of your initial variable from three to two. For example:

$arr = ['foo' => ['bar' => 2]];

// Introducing $_ -- the parens are needed!
$arr['foo']['bar'] = ($_ = $arr['foo']['bar']) === 2 ? $_ : 0;

Upvotes: 0

Mihai Stancu
Mihai Stancu

Reputation: 16107

Objective-C #define is a macro construct that uses stuff from the current context to allow you to define various shortcuts including defining constants, defining things that look like functions (but are actually replaced by other code).

PHP define() is a function with the sole purpose of initializing constants.

The only PHP shorthand for what you want to accomplish is the short form of the ternary operator $x ?: NULL.

Upvotes: -1

Related Questions