Ответ 1
попробуйте следующее:
{{ isset($blogs[0]) ? $blogs[0]->title : '' }}
Если вы используете foreach, чтобы использовать каждый заголовок $blog- > title
@foreach ($blogs as $blog)
{{ $blog->title }}
@endforeach
Я получаю эту ошибку, когда я прихожу на страницу после входа в систему:
ОшибкаException в команде compiled.php 11573: Undefined offset: 0 (Вид: C:\XAMPP\HTDOCS\campusguru\ресурсы\вид\home.blade.php)
Я знаю, что причиной этой ошибки является пустая переменная, которую я передал в представление.
Я уже пробовал:
if(isset($blog)) { do something }
и в виде лезвия:
{{ $blogs[0]->title or '' }}
В любом случае я могу справиться с этой ошибкой. Или есть лучший способ сделать это?
попробуйте следующее:
{{ isset($blogs[0]) ? $blogs[0]->title : '' }}
Если вы используете foreach, чтобы использовать каждый заголовок $blog- > title
@foreach ($blogs as $blog)
{{ $blog->title }}
@endforeach
Проблема заключается в том, что $blogs
фактически определен, и его значение равно []
(т.е. пустое array
), поэтому это означает, что оператор isset($blogs)
будет оцениваться как true
. То же самое справедливо для коллекций. Если коллекция пуста (т.е. Не имеет элементов, но она определена) isset($blogs)
будет по-прежнему оцениваться до true
, но доступ к $blogs[0]
приведет к ошибке Undefined offset: 0
.
Вы можете попробовать следующие решения:
Использование count
if(count($blogs)) { /* do something */ }
if $blogs = []
или $blogs = null
функция count
будет возвращать ноль, поэтому означает, что $blogs
пуст.
Использование empty
if(!empty($blogs)) { /* do something */ }
Это эквивалент записи !isset($var) || $var == false
, как описано в PHP Manual - empty:
Возвращает FALSE, если var существует и имеет непустую ненулевую стоимость. В противном случае возвращается TRUE.
Следующие вещи считаются пустыми:
""
(an пустая строка)0
(0 как целое число)0.0
(0 как float)"0"
(0 в виде строки)NULL
FALSE
array()
(пустой массив)$var;
(a переменная объявлена, но без значения)
Проверка наличия пустой коллекции
Если $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
. Если проблема все еще сохраняется, проблема находится в другом месте вашего кода IMHO.
Вы можете просто решить это с помощью помощника 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
или просто массив), третий параметр будет возвратным значением по умолчанию, если объект /array или ключ/атрибут не существует, значение по умолчанию равно null.
Edit:
Только что увидел запрос на дополнительное объяснение причин, по которым исходный код не работал.
Индекс 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"
Не имеет значения, использовал ли OP лезвие or default
, он даже не попадает в тернарный оператор из-за отсутствия индекса 0 на $blogs
.
Изменить 2 в соответствии с запросом:
Итак, причина, по которой вы получаете ошибку Undefined offset: x
, связана с порядком, в котором PHP оценивает код.
Blade 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 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
Внизу, лучший вариант будет не, чтобы полагаться на такие индексы, как это в вашем представлении, это просто не несет ответственности за ваше мнение.
Blade or default
отлично работает с одиночными переменными, но при работе с объектными атрибутами вам просто нужно убедиться, что объект (родительский) существует при этом.
Если у вас есть объект, переданный в представление, и пусть ваши данные являются "сообщениями", которые хранятся внутри такого объекта: $ 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
Я делаю это в контроллере:
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