Невозможно использовать возвращаемое значение метода в контексте записи

465

Я думаю, что следующий фрагмент кода должен работать, но это не так (отредактировано: теперь работает в PHP 5.5+) :

if (!empty($r->getError()))

Где getError()просто:

public function getError()
{
    return $this->error;
}

Все же я в конечном итоге с этой ошибкой:

нельзя использовать возвращаемое значение метода в контексте записи

Что это значит? Разве это не просто чтение?

Extrakun
источник
2
Вероятно, в PHP 5.5 вам будет разрешено передавать выражения по адресуempty : wiki.php.net/rfc/empty_isset_exprs
Карлос Кампдеррос
2
Полное
Хорошо, я нахожу правильный ответ porneL, также это мой код, if ( !$e->find('div') ) который проверяет, является ли текущий элемент HTML DOM пустым или нет. Я использую его внутри цикла, чтобы распечатать только один Div без внутреннего Div внутри.
Салем

Ответы:

769

empty() должен получить доступ к значению по ссылке (чтобы проверить, указывает ли эта ссылка на что-то существующее), а PHP до 5.5 не поддерживал ссылки на временные значения, возвращаемые функциями.

Однако настоящая проблема, с которой вы столкнулись, заключается в том, что вы используете ее empty()вообще, ошибочно полагая, что «пустое» значение отличается от «ложного».

Пустой это просто псевдоним для !isset($thing) || !$thing. Когда проверяемая вещь всегда существует (в PHP всегда присутствуют результаты вызовов функций), empty()функция является ничем иным, как оператором отрицания .

В PHP нет понятия пустоты . Значения, которые оцениваются как ложные, являются пустыми, значения, которые оцениваются как истинные, не являются пустыми. Это то же самое. Этот код:

$x = something();
if (empty($x)) 

и это:

$x = something();
if (!$x) 

во всех случаях всегда имеет одинаковый результат для всех типов данных (поскольку $xопределяется empty()как избыточный).

Возвращаемое значение из метода всегда существует (даже если у вас нет returnоператора, возвращаемое значение существует и содержит null). Следовательно:

if (!empty($r->getError()))

логически эквивалентно:

if ($r->getError())
Корнель
источник
29
Это гораздо лучший ответ, чем тот, который выбран в настоящее время.
SystemParadox
20
@gcb: нет, руководство по PHP явно говорит, что оно идентично: «empty () является противоположностью (boolean) var, за исключением того, что предупреждение не генерируется, когда переменная не установлена».
Корнел
16
Не генерация части предупреждения очень важна ... empty ($ var) вернет true, если он равен 0, '', array (), NULL или даже не определен. Это хорошая практика, особенно когда вы можете записывать свои настоящие предупреждения без заполнения файлов
landons
3
Хорошо, отличный ответ, но как правильно избежать этого, кто-нибудь знает?
Javatar
3
@EugenMihailescu в целом это нормально, но это не совсем эквивалентно empty (), потому что "", 0и т. Д. "Пусто", но не равно нулю.
Корнель
330

Примечание. Это ответ с очень высоким рейтингом и высокой видимостью, но имейте в виду, что он способствует плохим, ненужным практикам кодирования! Смотрите ответ @ Kornel для правильного пути.

Примечание № 2: Я поддерживаю предложения использовать ответ @ Kornel . Когда я написал этот ответ три года назад, я просто хотел объяснить природу ошибки, а не обязательно одобрить альтернативу. Фрагмент кода ниже не рекомендуется.


Это ограничение empty () в версиях PHP ниже 5.5.

Примечание: empty () проверяет только переменные, так как все остальное приведет к ошибке разбора. Другими словами, следующее не будет работать: пусто (trim ($ name)).

Вы должны изменить это

// Not recommended, just illustrates the issue
$err = $r->getError();
if (!empty($err))
Питер Бейли
источник
156
Это безумно контрпродуктивно.
Дэвид Мердок
47
Примечание: то же самое относится и к isset(). то есть: isset($this->foo->getBar())приведет к той же проблеме.
ловушка
7
Ответ porneL объясняет это более подробно, с лучшим решением
SystemParadox
5
@SystemParadox - Зависит от того, что вы подразумеваете под «лучше». Ответ porneL, возможно, более тщательный с «более чистым» решением, но также фактически не объясняет причину ошибки.
Питер Бейли
4
Потому что это не так, @deceze. Это не лучший ответ, вы не получите от меня никаких аргументов. Я даже проголосовал за porneL сам. Это очень старый ответ, но это не так . Что касается высоких голосов: помните, porneL пришли почти через 17 месяцев после этого.
Питер Бейли
37

Согласно документации PHP :

empty () проверяет только переменные, так как все остальное приведет к ошибке разбора

Вы не можете empty()напрямую использовать возвращаемое значение функции. Вместо этого установите return из getError()переменной и запустите empty()переменную.

Джордж Клагхорн
источник
19

Я обычно создаю глобальную функцию is_empty (), чтобы обойти эту проблему

function is_empty($var)
{ 
 return empty($var);
}

Тогда везде, где я бы обычно использовал empty (), я просто использую is_empty ()

Люк PM
источник
2
Лучше не делать этого и придерживаться стандартов (какими бы раздражающими они ни были).
tonyhb
1
@dynamism не могли бы вы объяснить, почему нет?
Янис Вейнбергс
1
Потому что удобные функции могут быть болезненными для чтения в чужом коде. Кроме того, в архитектуре MVC / HMVC это может испортить вашу структуру. В конце концов, PHP-кодеры должны знать о его ограничениях и уметь понимать небольшие обходные пути без вспомогательных функций.
tonyhb
14
Вау, вы только что изобрели функцию отрицания . Вы знаете, что в PHP есть !оператор для этого? :)
Корнел
4

Как отмечают другие, это (странное) ограничение empty ().

Для большинства целей сделать это равносильно вызову empty, но это работает:

if ($r->getError() != '')
Яни Хартикайнен
источник
5
Это не так - empty()охватывает гораздо больше возможностей, чем просто пустая строка
Робби Аверилл
3
Вот почему он говорит, что «для большинства целей », не все
Яни Хартикайнен
2

Проблема в том, что вы хотите знать, если ошибка не пуста.

public function getError() {
    return $this->error;
}

Добавление метода isErrorSet () решит проблему.

public function isErrorSet() {
    if (isset($this->error) && !empty($this->error)) {
        return true;
    } else {
        return false;
    }
}

Теперь это будет хорошо работать с этим кодом без предварительного уведомления.

if (!($x->isErrorSet())) {
    echo $x->getError();
}
Жан Карло Бамбалан
источник
-3

Альтернативный способ проверить, является ли массив пустым:

count($array)>0

У меня работает без этой ошибки

quardas
источник