Вычислить объект в булево
Рассмотрим следующее:
class MyClass
{
private $var1 = "apple";
private $var2 = "orange";
}
$obj = new MyClass();
if($obj) {
// do this
}
else {
// do that
}
PHP оценивает мой объект как истинный, поскольку он имеет переменные-члены. Может ли эта логика быть переопределена каким-то образом? Другими словами, могу ли я контролировать то, что будет оценивать объект моего класса, если он рассматривается как логический?
Ответы
Ответ 1
PHP оценивает мой объект как true, потому что он имеет переменные-члены.
Это неверно PHP фактически оценивает $obj
как true
потому что он содержит объект. Это не имеет ничего общего с содержанием объекта. Вы можете проверить это, удалив членов из определения класса, это не будет иметь никакого значения, в какой ветки будет выбран if/else.
Нет способа заставить PHP оценивать переменную как ложную, если она содержит ссылку на объект. Вам нужно было бы присвоить переменной переменную, которая включает в себя следующие значения:
null
array()
""
false
0
См. Преобразование в логическое значение из документации PHP для получения списка всех значений, которые рассматриваются как false
при преобразовании в логическое значение.
Ответ 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
Нет, вы не можете. К сожалению, boolean casting в php не модифицируется, и объект всегда возвращает true при преобразовании в логическое.
Поскольку у вас явно есть логика, которую вы хотите разместить в этом контрольном заявлении, почему бы не определить метод на вашем объекте (скажем, "isValid()" ), который проверяет условия, которые вы хотите проверить, а затем заменить:
if ($obj)
с:
if ($obj->isValid())
Ответ 4
Вы можете использовать небольшое расширение для php7: https://github.com/p1ncet/obcast. Как вы можете видеть из описания, он позволяет отличать объект от boolean путем внедрения нового внутреннего интерфейса 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)
Ответ 5
Извините за опоздание, но я просто сыграл с подобной задачей и сделал какой-то хак/обходной путь. Обратите внимание на шаблон "$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!
Ответ 6
Вы можете сделать это так:
(bool) $yourObject
будет