Чому функція empty () PHP не буде працювати так, як очікується, з $ this-> data у CakePHP 2?

Щоб полегшити деяку плутанину, я повністю переписав це питання.


Ось контролер:

<?php
class StaffController extends AppController{
    function test(){
        $this->data = $this->Staff->find( 'list' );
    }
}

Ось весь перегляд:


Count: <?php echo count( $this->data ) . "\n"; ?>
Empty: <?php echo ( empty( $this->data ) ? 'true' : 'false' ) . "\n"; ?>
Count: <?php echo count( $this->data ) . "\n"; ?>
<?php var_dump( $this->data ) ?>

Наведений вивід:

Count: 2
Empty: true
Count: 2
array(2) {
  [1]=>
  string(12) "Mock Staff 1"
  [2]=>
  string(12) "Mock Staff 2"
}

Чому empty() повертає True, коли як count() , так і debug() показують, що було призначено непусте значення?

Це помилка CakePHP? Помилка PHP? ???

If I use another variable instead of $this->data :

function test(){
    $this->set( 'data', $this->Staff->find( 'list' ) );
}

І вид:


Count: <?php echo count( $data ) . "\n"; ?>
Empty: <?php echo ( empty( $data ) ? 'true' : 'false' ) . "\n"; ?>
Count: <?php echo count( $data ) . "\n"; ?>
<?php var_dump( $data ) ?>

він працює як слід:

Count: 2
Empty: false
Count: 2
array(2) {
  [1]=>
  string(12) "Mock Staff 1"
  [2]=>
  string(12) "Mock Staff 2"
}

Будь-які беруть?

2
@ScottHarwell Наведене вище відлуння/налагодження в перегляді. Код для налагодження, випробуваний для цілей цього запитання, є точно таким, як вказано вище - немає шансів на що-небудь переписане між ними - цикл foreach, який перебирає $ this-> data після коду < > Порожній() тест може відображати всі елементи масиву. PHP 5.3.6.
додано Автор Farray, джерело
@ScottHarwell Наведене вище відлуння/налагодження в перегляді. Код для налагодження, випробуваний для цілей цього запитання, є точно таким, як вказано вище - немає шансів на що-небудь переписане між ними - цикл foreach, який перебирає $ this-> data після коду < > Порожній() тест може відображати всі елементи масиву. PHP 5.3.6.
додано Автор Farray, джерело
@ScottHarwell Хороший пункт про використання іншого імені змінної. Призначення даних іншому імені змінної виправляє симптоми, однак я все ще розумію, чому empty не працює з $ this-> data, а інші функції працюють дуже добре ...
додано Автор Farray, джерело
@ScottHarwell Оновлено питання, щоб включити повні контролери & перегляди. Я можу обійти його, але мені цікаво, чому це відбувається.
додано Автор Farray, джерело
Де ви повторюєте/налагоджуєте масив $ this-> data (контролер або модель). Якщо в контролері? Ваш код виглядає точно так само, як і в цьому прикладі; немає місця, де $ this-> дані перезаписуються між повторюваним рахунком і тестуванням на порожнечу? Ви використовуєте PHP 5.3 або вище?
додано Автор Scott Harwell, джерело
Я не впевнений, чому це відбувається, але ви, напевно, не повинні призначати $ this-> data. Скоріше призначте нову змінну даних з вашого пошуку і працюйте з нею таким чином. Як $ data = $ this-> Model-> findById (1);
додано Автор Scott Harwell, джерело
Я думаю, тому що перегляд використовує $ this-> data і, можливо, перепризначення змінної. Але я не можу бути впевненим, не бачачи всієї функції.
додано Автор Scott Harwell, джерело
Відповідь @ JohnWatson нижче пояснює, чому ви не повинні призначати дані для $ this-> data у вашому контролері.
додано Автор Scott Harwell, джерело
Ви спробували "$ this-> request-> data"?
додано Автор dccarmo, джерело

2 Відповіді

$this->data is special in Cake views. When you access $this->data in a view, you actually end up calling the magic method View::__get(), and empty() doesn't work with methods or functions--it only works with variables. As you've found, the correct way to pass data to a view is by using $this->set() in your controller. Just to clarify, $this in the view is a different object than $this in your controller.

3
додано
Так, я знаю. Він встановлює $ this-> data в контролер, але отримує доступ до $ this-> data у перегляді. І вони різні змінні. $ this у перегляді є екземпляром View і $ this у контролері є екземпляром контролера. І так, я погоджуюся, ви повинні уникати використання $ this-> data, тому що він часто використовується внутрішнім об'єктом, як у цьому випадку.
додано Автор John Watson, джерело
Я думаю, що він встановлював $ this-> data у своєму контролері, не переглядаючи. Я не мав часу дивитися на код AppController, щоб побачити, чому це відбувається. Проте, чи погоджуєтеся б ви, що найкращим методом буде уникнути встановлення $ this-> data за межами моделі?
додано Автор Scott Harwell, джерело

It could be that $this->data is inaccessible? (odd since you're in the class itself), in which case:

При використанні порожнього() щодо недоступних властивостей об'єкта, метод перевантаження __isset буде оголошено, якщо буде оголошено.

Either way, I would add a function to the class, something like $this->hasData() and use that instead. Have hasData return whether $this->data has elements.

0
додано
Оновлено питання для вирішення цього питання. Для цілей тестування, пов'язаних з цим запитанням, я маю count ($ this-> data) , за яким слід відразу empty ($ this-> data) і count повертає "2", а порожній повертає True. Якщо $ this-> data недоступний, count також не працюватиме.
додано Автор Farray, джерело
Ukrainian PHP comunity
Ukrainian PHP comunity
885 учасників

dev-ua/php