Как обрабатывать неопределенное смещение в laravel?

Я получаю эту ошибку при входе на страницу после входа в систему:

ErrorException в строке compiled.php 11573: неопределенное смещение: 0 (представление:
C: \ XAMPP \ HTDOCS \ campusguru \ ресурсы \ вид \ home.blade.php)

Я знаю, что причиной этой ошибки является пустая переменная, которую я передал представлению.

Я уже попробовал:

if(isset($blog)) { do something }

и в виде лезвия как:

{{ $blogs[0]->title or '' }}

Есть ли в любом случае я мог справиться с этой ошибкой. Или есть лучший способ сделать это?

15

Решение

Проблема в том, что $blogs на самом деле определяется и его значение [] (т.е. пустой array) так значит что isset($blogs) заявление оценит true, То же самое относится и к коллекциям. Если коллекция пуста (т.е. не имеет элементов, но она определена) isset($blogs) будет по-прежнему оценивать true но доступ $blogs[0] вызовет Undefined offset: 0 ошибка.

Вы можете попробовать следующие решения:

С помощью count

if(count($blogs)) { /* do something */ }

если $blogs = [] или же $blogs = null функция count вернет ноль, так что это означает, что $blogs пустой.

С помощью empty

if(!empty($blogs)) { /* do something */ }

Это эквивалент написания !isset($var) || $var == false как описано в Руководство по PHP — пусто:

Возвращает ЛОЖНЫЙ если var существует и имеет непустой, ненулевой
значение. В противном случае возвращается ПРАВДА.

Следующие вещи считаются пустыми:

  • "" (
    пустой строки)
  • 0 (0 как целое число)
  • 0.0 (0 как
    с плавающей точкой)
  • "0" (0 как строка)
  • NULL
  • FALSE
  • array() (пустой массив)
  • $var;
    переменная объявлена, но без значения)
  • Проверка, если коллекция пуста

    Если $blogs это Collection достаточно проверить, не является ли он пустым, используя `IsNotEmpty () метод:

    @if($blogs->isNotEmpty()) <!-- Do your stuff --> @endif
    

    РЕДАКТИРОВАТЬ

    Я забыл добавить синтаксис лезвия:

    @if(count($blogs)) <!-- Do whatever you like --> @endif
    

    или же

    @if(!empty($blogs)) <!-- Do whatever you like --> @endif
    

    РЕДАКТИРОВАТЬ 2

    Я добавляю больше контента к этому ответу для решения некоторых проблем, представленных в комментариях. Я думаю, что ваша проблема заключается в следующем:

    $blogs это пустая коллекция, поэтому она определена, но не имеет элементов. По этой причине if(isset($blogs)) заявление оценит true прохождение первого if состояние. В вашем шаблоне клинка вы делаете чек {{ $blogs[0]->title or '' }} то есть абсолютно не равно <?php isset($blogs[0]->title) ? $blogs[0]->title : '' ?> как указано в комментариях, но это выражение, которое вернет true или же falseтак что он никогда не распечатает title параметр, даже если $blogs[0] существует. Проблема здесь в том, что при проверке состояния $blogs[0]->title вы фактически получаете доступ к элементу 0 из $blogs коллекция, которая вызовет исключение Undefined offset: 0 потому что коллекция на самом деле пуста. То, что я говорил, это то, что в дополнение к

    if(count($blogs)) { /* do something */ }
    

    (это проверяет, что $blogs и что его длина больше 0) в вашем шаблоне вы должны сделать

    {{ isset($blogs[0]->title) ? $blogs[0]->title : '' }}
    

    или более кратко

    {{ $blogs[0]->title ?: '' }}
    

    Предполагая, что поток управления прибудет туда, только если $blogs прошел первый if, Если проблема все еще сохраняется, проблема в другом месте в вашем коде ИМХО.

    8

    Другие решения

    попробуйте следующее:

    {{ isset($blogs[0]) ? $blogs[0]->title : '' }}
    

    Если вы используете foreach для получения каждого $ blog-> title, используйте

    @foreach ($blogs as $blog)
    {{ $blog->title }}
    @endforeach
    
    6

    Вы можете просто решить это с data_get() помощник.

    Например:

    php artisan tink
    Psy Shell v0.8.11 (PHP 7.0.22-0ubuntu0.16.04.1 — cli) by Justin Hileman
    >>>
    >>> $a = collect([[], null, App\Models\User::find(1)]);
    => Illuminate\Support\Collection {#887
    all: [
    [],
    null,
    App\Models\User {#896
    id: 1,
    name: "user1",
    email: "[email protected]",
    last_name: "Gabrielle",
    first_name: "Rempel",
    deleted_at: null,
    created_at: "2017-08-12 15:32:01",
    updated_at: "2017-09-05 12:23:54",
    },
    ],
    }
    >>> data_get($a[0], 'name', 'nope');
    => "nope">>> data_get($a[1], 'name', 'nope');
    => "nope">>> data_get($a[2], 'name', 'nope');
    => "user1">>>
    

    Итак, в этом случае:

    {{ data_get($blogs[0], 'title', '') }}
    

    data_get() будет работать как с массивами, так и с объектами, возвращая ключ или атрибут, определенный во втором параметре (это может быть laravel.dot.notation.styleили просто массив), 3-й параметр будет возвращаемым значением по умолчанию, если объект / массив или ключ / атрибут не существует, значение по умолчанию равно нулю.


    Редактировать:

    Только что увидел запрос на дополнительное объяснение того, почему оригинальный код не работал.

    Индекс 0 просто не существует в массиве / коллекции, которые передаются в представление.

    >>> $a = [1 => App\Models\User::find(1)];
    => [
    1 => App\Models\User {#890
    id: 1,
    name: "user1",
    // ... etc
    },
    ]
    >>> $a[0]->name ?: 'nope';
    PHP error:  Undefined offset: 0 on line 1
    >>> $a[1]->name ?: 'nope';
    => "user1"

    Неважно, если ОП использовал лезвие or default, он даже не доходит до троичного оператора из-за отсутствия индекса 0 на $blogs,


    Изменить 2 по запросу:

    Итак, причина, по которой вы получаете Undefined offset: x ошибка из-за порядка, в котором PHP оценивает код.

    клинка or default находится за кадром не более чем троичное утверждение

    return preg_replace('/^(?=\$)(.+?)(?:\s+or\s+)(.+?)$/si', 'isset($1) ? $1 : $2', $value);
    

    Так что это сделает:

    isset($blogs[0]->title) ? $blogs[0]->title : ''
    

    isset() проверит, установлен ли заголовок объекта, но для этого потребуется $blogs[0] быть действительным объектом. Для этого он попытается получить объект из $blogs массив с индексом 0. Но так как этот индекс не существует, он вызовет исключение с Undefined offset: 0,

    Для того, чтобы сделать эту работу с Blade’s or defaultвы должны сначала убедиться, что $blogs[0] определяется (и предпочтительно также проверить, что это объект, в противном случае вы получите попытку получить свойство ошибки не-объекта, пожалуйста, обратите внимание, что это не должно быть ответственностью зрения), после этого вы сможете использовать or default как и в любой другой раз.

    @if (isset($blogs[0]) && is_object($blogs[0]))
    {{ $blogs[0]->title or '' }}
    @else
    // some other default placeholder
    @endif
    

    В основном вы получите ту же ошибку смещения при использовании data_get()потому что индекс 0 по-прежнему не существует.

    {{ data_get($blogs[0], 'title', '') }} // Undefined offset: 0
    

    Вы могли бы играть грязно и сделать это (это никуда не пропустит проверку кода, и мне вообще не следовало вводить это, это просто для иллюстрации)

    {{ data_get($blogs, '0.title', '') }} // Will display '' as it will check if key 0 exists
    

    Во всяком случае, с data_get() вы все равно будете в конечном итоге делать что-то вроде этого, так как вам нужно убедиться, $blogs[0] это то, с чем вы можете работать:

    @if (isset($blogs[0]))
    {{ data_get($blogs[0], 'title', '') }}
    @else
    // some other default placeholder
    @endif
    

    Итог, лучший вариант будет не полагаться на подобные индексы, по вашему мнению, это просто не ваша ответственность.

    клинка or default отлично работает с отдельными переменными, но при работе с атрибутами объекта вам просто нужно убедиться, что (родительский) объект существует при этом.

    3

    Если у вас есть объект, который передается в представление, и, скажем, ваши данные — это «записи», которые хранятся внутри объекта, например:
    $ Obj-> сообщений.

    Если вы затем выполните цикл foreach, который будет проходить по каждому посту и выводить его параметры, как в приведенном ниже примере, то он отлично работает, когда у вас есть посты.

    @foreach($obj->posts as $post)
    <h1>$post->title</h1>
    <p>$post->content</p>
    @endforeach
    

    Перед выполнением цикла вы хотите проверить, был ли установлен атрибут со значениями. Вы можете использовать isset () для этого, и, поскольку это специальная форма, ее можно использовать как isset ($ obj-> posts) или isset ($ obj-> posts [0]). Разница в том, что последний будет только проверять, имеет ли ключ массива какое-либо значение, поэтому, если ваш индексный ключ не равен 0, он вернет false. Например, у вас есть:

    $foo = ['first' => somevalue1, 'second' => somevalue2];
    isset($foo[0]); //returns false
    isset($foo['first']); //returns true
    isset($foo); //returns true
    

    Я сделал бы проверку следующим образом:

    @if(isset($obj->posts))
    @foreach($obj->posts as $post)
    ...
    @endoforeach
    @endif
    
    1

    Я делаю так в контроллере:

     if (empty($allFares) || count($allFares)==0){
    return back()->withError('No Fare Found For The City!');
    }
    

    ИЛИ в лезвии:

       @if (!empty($allFares) || count($allFares)>0)
    @foreach(allFares as $key=>$value)
    
    @endforeach
    @endif
    
    0
    По вопросам рекламы [email protected]