Моя цель – поставить сложную логику в оператор if (). Предположим, у меня есть массив значений, и я собираюсь выполнить немного кода, если все в моем массиве отличное от нуля. Обычно я могу сказать: $valid = true , foreach my array и set $valid = false когда найден нуль. Тогда я запустил бы свой код, if ($valid) . В качестве альтернативы, я мог бы включить мой цикл в функцию и поместить функцию intop my if() .
Но я ленив, поэтому я бы предпочел не гадать с кучей «правильных» флагов, и я бы предпочел написать совершенно новую функцию, которая используется только в одном месте.
Итак, скажем, у меня есть это:
if ($q = function() { return 'foo'; }) { echo $q; } else { echo 'false'; }
Я ожидал, что if получит 'foo' , который оценивается как true. Мое закрытие привязано к $q и оператор выполняется. $q возвращает строку foo , и 'foo' печатается.
Вместо этого я получаю ошибку. Object of class Closure could not be converted to string .
Итак, давайте попробуем это:
if (function() { return false; }) { echo 'foo'; } else { echo 'true'; }
Я ожидал, что моя функция вернет false, и «true» будет напечатано. Вместо этого печатается «foo».
Что не так в том, как я это делаю? Похоже, он говорит: «Да, это определенно функция!» вместо «Нет, потому что функция вычисляется как false». Есть ли способ сделать то, что я пытаюсь сделать?
function() { return false; } function() { return false; } создает объект типа Closure , аналогичный new с другими типами классов, сравнивает следующий код:
$func = function() { return false; };
$func теперь является объектом. Каждый объект возвращает true в if . Так
if ($func) { # true } else { # will never go here. }
Возможно, вы захотите сделать это:
if ($func()) { # true } else { # false }
который вызовет объект Closure $func и даст его возвращаемое значение.
Оба они оценивают истину.
Вы должны заставить функцию выполнить ее использовать в инструкции if.
Попробуй это:
$q = function() { return false; }; if ($q()) { //should not go here. echo $q(); } else { echo 'false'; }
Закрытия PHP реализованы как хак-объекты типа Closure . Ваш код фактически создает экземпляр объекта этого класса и присваивает его $ q. В PHP результат присваивания – это назначаемое значение, поэтому, по сути, код сводится к
if (new Closure()) { ... }
Вы не выполняете закрытие, когда вы вызываете echo , поэтому он пытается распечатать закрытие, а не результат закрытия:
echo $q();
Вы создаете анонимную функцию, но не выполняете ее. Когда вы проверяете $q = function() { return 'foo'; } $q = function() { return 'foo'; } , вы говорите: «Назначьте ссылку на эту анонимную функцию на $ q и передайте этот тест, если $ q не является нулевым» (не PHP весело?)
Вы должны вызвать закрытие и назначить его результат до $q перед тестированием и повторить $q .