Оценить объект как логическое значение - PullRequest
19 голосов
/ 07 апреля 2011

Обратите внимание на следующее:

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

$obj = new MyClass();

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

PHP оценивает мой объект как true, потому что у него есть переменные-члены.Может ли эта логика быть отвергнута как-то?Другими словами, могу ли я контролировать то, что объект моего класса будет оценивать, когда рассматривается как логическое значение?

Ответы [ 6 ]

20 голосов
/ 07 апреля 2011

PHP оценивает мой объект как true, поскольку в нем есть переменные-члены.

Это неверно.PHP фактически оценивает $obj как true, потому что он содержит объект.Это не имеет ничего общего с содержанием объекта.Вы можете проверить это, удалив члены из определения класса, это не будет иметь никакого значения, в какой ветви будет выбран if / else.

Нет способа заставить PHP оценивать переменную как false, еслион содержит ссылку на объект.Вам нужно было бы присвоить переменной переменную, которая включает следующие значения:

null
array()
""
false
0

См. Преобразование в логическое значение из документации PHP для получения списка всех значений.которые обрабатываются как false при преобразовании в логическое значение.

15 голосов
/ 07 апреля 2011

Лучшее, что вы можете сделать, это использовать __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
7 голосов
/ 07 апреля 2011

Нет, вы не можете. К сожалению, логическое приведение в php нельзя изменить, и объект всегда будет возвращать true при преобразовании в логическое значение.

Поскольку у вас явно есть какая-то логика, которую вы хотите поместить в этот оператор управления, почему бы не определить метод для вашего объекта (скажем, "isValid ()"), который проверяет условия, которые вы хотите проверить, и затем заменить:

if ($obj)

с:

if ($obj->isValid())
2 голосов
/ 14 сентября 2016

Вы можете использовать небольшое расширение для 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)
0 голосов
/ 06 ноября 2016

Извините за опоздание, но я только что поиграл с похожим заданием и сделал какой-то хак / обходной путь. Обратите внимание на шаблон "$object", который вызывает метод __toString.

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!
0 голосов
/ 04 декабря 2015

Вы можете сделать это так: (bool) $ yourObject

будет

...