'Boolean assignment operators in PHP

I find myself doing this kind of thing somewhat often:

$foo = true;
$foo = $foo && false; // bool(false)

With bitwise operators, you can use the &= and |= shorthand:

$foo = 1;
$foo &= 0; // int(0)

Given that bitwise operations on 1 and 0 are functionally equivalent to boolean operations on true and false, we can rely on type-casting and do something like this:

$foo = true;
$foo &= false; // int(0)
$foo = (bool)$foo; // bool(false)

...but that's pretty ugly and defeats the purpose of using a shorthand assignment syntax, since we have to use another statement to get the type back to boolean.

What I'd really like to do is something like this:

$foo = true;
$foo &&= false; // bool(false)

...but &&= and ||= are not valid operators, obviously. So, my question is - is there some other sugary syntax or maybe an obscure core function that might serve as a stand-in? With variables as short as $foo, it's not a big deal to just use $foo = $foo && false syntax, but array elements with multiple dimensions, and/or object method calls can make the syntax quite lengthy.



Solution 1:[1]

In a way you have answered your own question:

bitwise operations on 1 and 0 are functionally equivalent to boolean operations on true and false

Bearing in mind that PHP is a weakly typed language, so it is not necessary to typecast to and from strict boolean values as 1 and 0 are equivalent to true and false (except strict equality, see below).

Consider the following code, using your examples:

$foo = true;
$foo &= false;

if (!$foo) {
  echo 'Bitwise works!';
}

$bar = true;
$bar = $bar && false;

if (!$bar) {
  echo 'Boolean works!';
}

// Output: Bitwise works!Boolean works!

Given PHP's implicit type juggling, falsy values, and with the exception of strict equaltiy, I'm hard pressed to see where such shorthand operations of &&= and ||= would not yield the same result as &= and |=. Especially when evaluating boolean values. It's likely why such shorthands don't exist in PHP.

Update

Some quick benchmarks prove these are indeed equivalent, except for truthy arrays/objects:

<?php
$values = array(false, 0, 0.0, "", "0", array(), 12, "string", array(1));

foreach ($values as $value) {
    $bit_test = true;
    $bit_test &= $value;

    $bool_test = true;
    $bool_test = $bool_test && false;
    if ($bit_test != $bool_test) {
        echo 'Difference for: ';
        var_dump($value);
    }
}

// Output:
// Difference for: array(1) {
//  [0]=>
//  int(1)
// }

Solution 2:[2]

As Jason mentioned, bitwise operators will work and it will not be necessary to convert the result back to boolean, as PHP will already handle their value as a boolean properly.

If you want an alternative that does not use bitwise operators, for the sake of readability or if you want strict equality, you can use this method :

function OrOp(&$booleanVar, $conditions)
{
    $booleanVar = $booleanVar && $conditions;
    return $booleanVar;
}

Which means, you could change this :

$foo = $foo && false;

To this :

OrOp($foo, false);

It would also work with multiple conditions :

OrOp($foo, $condition1 && $condition2 && $condition3);

Solution 3:[3]

Right, &&= and ||= operators are indeed missing in PHP because bitwise operators can not be used as a replacement (without casting).

Here is an example you would expect to return true but returns false:

$a = true;
$a &= 10; // => returns 0 (false) because 1 & 10 = 0

The missing &&= operator would return true because 1 && 10 = true

$a = true;
$a &&= 10; // => $a would be true

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 Christopher Pereira