Неможливо використовувати значення повернення методу в контексті запису


465

Я думаю, що наступний фрагмент коду повинен працювати, але він не працює (Відредаговано: Зараз працює у PHP 5.5+) :

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

Де getError()просто:

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

Але я закінчую цю помилку:

не може використовувати значення повернення методу в контексті запису

Що це означає? Це не просто читання?


2
Ймовірно, в PHP 5.5 вам буде дозволено передавати вирази на empty: wiki.php.net/rfc/empty_isset_exprs
Carlos Campderrós


Гаразд, я знаходжу відповідь 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 прямо говорить про те, що воно ідентичне: "порожній () - це протилежне (boolean) var, за винятком того, що попередження не створюється, коли змінна не встановлена."
Корнель

16
Негенеруюча частина попередження є досить важливою ... порожня ($ var) повернеться true, якщо вона дорівнює 0, '', array (), NULL або навіть не визначена. Це хороша практика, особливо, щоб ви могли реєструвати свої реальні попередження без заповнення файлів
landons

3
Гаразд, чудова відповідь, але який правильний спосіб цього уникнути, хтось знає?
Джаватар

3
@EugenMihailescu взагалі це нормально, але це не є рівнозначним порожнім (), тому що "", 0і т.д. є "порожніми", але не нульовими.
Корнель

330

Примітка. Це дуже відповідна відповідь з високою видимістю, але зауважте, що вона сприяє поганій, непотрібній практиці кодування! Дивіться відповідь @ Корнеля про правильний спосіб.

Примітка № 2: Я схвалюю пропозиції використовувати відповідь @ Корнеля . Коли я писав цю відповідь три роки тому, я просто мав на меті пояснити природу помилки, не обов'язково схвалюючи альтернативу. Фрагмент коду нижче не рекомендується.


Це обмеження порожнього () у версіях PHP нижче 5,5.

Примітка: порожній () перевіряє лише змінні, оскільки все інше призведе до помилки розбору. Іншими словами, наступне не буде працювати: порожній (обрізка ($ ім'я)).

Вам доведеться змінити це

// Not recommended, just illustrates the issue
$err = $r->getError();
if (!empty($err))

156
Це шалено контрпродуктивно.
Девід Мердок

47
Примітка: те ж саме і з isset(). тобто: isset($this->foo->getBar())призведе до того ж питання.
catchdave

7
відповідь porneL пояснює це більш докладно, з кращим рішенням
SystemParadox

5
@SystemParadox - залежить від того, що ви маєте на увазі під «кращим». Відповідь porneL, можливо, більш ретельна з рішенням "чистішого", але також фактично не пояснює походження помилки.
Пітер Бейлі

4
Тому що це не помиляється, @deceze. Це не найкраща відповідь, ви не отримаєте від мене жодного аргументу. Я навіть сам проголосував за porneL. Це дуже стара відповідь, але це не так . Щодо високих голосів: пам’ятайте, porneL's приїхали майже цілих 17 місяців після цього.
Пітер Бейлі

37

Відповідно до документів PHP :

empty () перевіряє лише змінні, оскільки все інше призведе до помилки розбору

Ви не можете використовувати empty()безпосередньо для зворотного значення функції. Натомість встановіть повернення getError()до змінної та запустіть empty()змінну.


19

Зазвичай я створюю глобальну функцію під назвою is_empty () просто для подолання цієї проблеми

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

Тоді б я ніколи не використовував порожній (), я просто використовую is_empty ()


2
Краще цього не робити і дотримуватися стандартів (настільки прикро, як вони можуть бути).
tonyhb

1
@dynamism ви могли б пояснити, чому ні?
Janis Veinbergs

1
Оскільки функції зручності можуть бути болем читати в чужому коді. Крім того, в архітектурі MVC / HMVC це може зіпсувати вашу структуру. Зрештою, PHP-кодери повинні знати, що це обмеження, і мати можливість зрозуміти невеликі обхідні шляхи без зручності функцій.
tonyhb

14
Нічого собі, ти щойно винайшов функцію заперечення . Ви знаєте, що PHP має !оператора для цього? :)
Kornel

4

Як вказують інші, це (дивне) обмеження порожнього ().

Для більшості виправлень це робити так само, як називати порожнім, але це працює:

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

Це працює для мене без цієї помилки

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.