【问题标题】:Evaluate object to a boolean将对象评估为布尔值
【发布时间】:2011-07-31 04:18:58
【问题描述】:

考虑以下几点:

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

$obj = new MyClass();

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

PHP 将我的对象评估为 true,因为它具有成员变量。这个逻辑可以以某种方式被覆盖吗?换句话说,我可以控制我的类的对象在被视为布尔值时将评估的内容吗?

【问题讨论】:

  • 不,目前我们只能在字符串转换中控制它。
  • 为什么你需要有这种不寻常的行为?
  • 您可以达到的最佳效果是 if( $obj() ) 或 if ("$obj") 或 if (count($obj)) 代替布尔评估。

标签: php class object evaluation


【解决方案1】:

PHP 将我的对象评估为 true,因为它具有成员变量。

这是不正确的。 PHP 实际上将$obj 评估为true,因为它拥有一个对象。它与对象的内容无关。您可以通过从类定义中删除成员来验证这一点,选择 if/else 的哪个分支不会有任何区别。

如果变量持有对对象的引用,则无法让 PHP 将其评估为 false。您必须为变量分配一些“虚假”的东西,其中包括以下值:

null
array()
""
false
0

请参阅 PHP 文档中的 Converting to boolean 以获取在转换为布尔值时被视为 false 的所有值的列表。

【讨论】:

  • 是的。为了澄清 OP,$obj 不是对象。相反,它是对象位置的引用,PHP 使用它来查找内存中实际对象开始的点。
  • "PHP evaluates my object to true because it has member variables." This is incorrect. 实际上,这在 PHP 4 中 是正确的,但是 PHP 5 将行为更改为您所描述的那样。相关性不大,但在历史上很有趣。
【解决方案2】:

你能做的最好的就是使用__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

【讨论】:

    【解决方案3】:

    不,你不能。不幸的是,php 中的布尔型转换是不可修改的,对象在转换为布尔型时总是返回 true。

    既然您显然有一些逻辑要放在该控制语句中,为什么不在您的对象上定义一个方法(例如“isValid()”)来检查您希望检查的条件,然后替换:

    if ($obj)
    

    与:

    if ($obj->isValid())
    

    【讨论】:

    • 是的,我想这就是我必须要做的,但我只是想稍微简化一下编码。
    【解决方案4】:

    您可以使用 php7 的小扩展名:https://github.com/p1ncet/obcast。从描述中可以看出,它允许通过实现新的内部接口 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);
    

    输出:

    bool(false)
    bool(true)
    

    【讨论】:

    • 奇怪为什么这不是一个内置函数。由于自 PHP 5.2 以来__toString() 的存在,我希望会有这样一个
    • 我希望 __toPrimitive() 或 __toValue() 或类似的东西适用于任何非对象值。
    【解决方案5】:

    很抱歉迟到了,但我刚刚玩过类似的任务,并且做了某种破解/解决方法。注意调用__toString 方法的"$object" 模式。

    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
    

    输出:

    1: true!
    0: false!
    

    【讨论】:

      【解决方案6】:

      你可以这样做: (bool) $你的对象

      会

      【讨论】:

        猜你喜欢
        • 2012-11-22
        • 1970-01-01
        • 1970-01-01
        • 2011-08-28
        • 2017-05-24
        • 2013-11-11
        • 1970-01-01
        • 1970-01-01
        • 2012-06-04
        相关资源
        最近更新 更多