29

Consider the following:

class MyClass
{
  private $var1 = "apple";
  private $var2 = "orange";
}

$obj = new MyClass();

if($obj) { 
  // do this
}
else {
  // do that
}

PHP evaluates my object to true because it has member variables. Can this logic be overridden somehow? In other words, can I have control over what an object of my class will evaluate to when treated as a boolean?

Niko Efimov
  • 2,183
  • 3
  • 20
  • 30

6 Answers6

30

PHP evaluates my object to true because it has member variables.

This is incorrect. PHP actually evaluates $obj as true because it holds an object. It has nothing to do with the contents of the object. You can verify this by removing the members from your class definition, it won't make any difference in which branch of the if/else is chosen.

There is no way of making PHP evaluate a variable as false if it holds a reference to an object. You'd have to assign something "falsy" to the variable, which includes the following values:

null
array()
""
false
0

See the Converting to boolean from the PHP documentation for a list of all values that are treated as false when converted to a boolean.

user229044
  • 232,980
  • 40
  • 330
  • 338
  • 2
    True. To clarify for the OP, `$obj` isn't the object. Rather, it is a *reference* to the location of the object, used by PHP to find the point in memory where the actual object begins. – AgentConundrum Apr 06 '11 at 21:10
  • `"PHP evaluates my object to true because it has member variables." This is incorrect.` Actually, this *was* true in PHP 4, but PHP 5 changed the behaviour to be as you describe. Not vastly relevant, but historically interesting. – HappyDog Nov 20 '20 at 14:05
23

The best you can do is using __invoke:

class MyObject {

    private $_state;

    public function __construct($state = false) {
        $this->_state = $state;
    }

    public function __invoke() {
        return $this->_state;
    }

}

$true  = new MyObject(true);
$false = new MyObject(false);

var_dump($true());   // true
var_dump($false());  // false
netcoder
  • 66,435
  • 19
  • 125
  • 142
10

You can use small extension for php7: https://github.com/p1ncet/obcast. As you may see from the description, it allows to cast an object to boolean by implementing new internal interface Boolable:

$obj = new class implements Boolable {
    public $container = [];
    public function __toBoolean() {
        return count($this->container) > 0;
    }
};

var_dump((bool) $obj);

$obj->container = [1];
var_dump((bool) $obj);

output:

bool(false)
bool(true)
p1ncet
  • 101
  • 1
  • 3
  • 7
    Strange why this isn't a built-in function. I'd expect there to be one like this due to the presence of `__toString()` since PHP 5.2 – Berry M. Apr 18 '17 at 13:28
  • I would expect a `__toPrimitive()` or `__toValue()` or something like that which would work for any non-object value. – toraman Aug 06 '19 at 21:49
8

No, you can't. Unfortunately boolean casting in php is not modifiable, and an object will always return true when converted to a boolean.

Since you clearly have some logic you mean to place in that control statement, why not define a method on your object (say "isValid()" ) that checks the conditions you wish to check, and then replace:

if ($obj)

with:

if ($obj->isValid())
schizodactyl
  • 1,445
  • 1
  • 10
  • 11
2

Sorry for being late, but I just played with similar task and have made some kind of a hack/workaround. Notice "$object" pattern which calls __toString method.

class tst {
  public $r = true;
  function __toString() { return $this->r ? "1" : "0"; }
}
$object = new tst();
$object->r = true;
echo '<br />1: ';
if ("$object") echo 'true!'; else echo 'false!'; // "$object" becomes "1" == true
//echo "$object" ? 'true!' : 'false!';

$object->r = false;
echo '<br />0: ';
echo "$object" ? 'true!' : 'false!'; // "$object" becomes "0" == false

Output:

1: true!
0: false!
Sh4dow
  • 129
  • 3
-3

You can do it like that : (bool) $yourObject

will

William Rossier
  • 873
  • 9
  • 15