Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 316
FtDRbwLXw6 Avatar asked Jul 09 '13 16:07

FtDRbwLXw6


1 Answers

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)
// }
like image 150
Jason McCreary Avatar answered Oct 23 '22 13:10

Jason McCreary