Я получаю эту ошибку при входе на страницу после входа в систему:
ErrorException в строке compiled.php 11573: неопределенное смещение: 0 (представление:
C: \ XAMPP \ HTDOCS \ campusguru \ ресурсы \ вид \ home.blade.php)
Я знаю, что причиной этой ошибки является пустая переменная, которую я передал представлению.
Я уже попробовал:
if(isset($blog)) { do something }
и в виде лезвия как:
{{ $blogs[0]->title or '' }}
Есть ли в любом случае я мог справиться с этой ошибкой. Или есть лучший способ сделать это?
Проблема в том, что $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
, Если проблема все еще сохраняется, проблема в другом месте в вашем коде ИМХО.
попробуйте следующее:
{{ isset($blogs[0]) ? $blogs[0]->title : '' }}
Если вы используете foreach для получения каждого $ blog-> title, используйте
@foreach ($blogs as $blog)
{{ $blog->title }}
@endforeach
Вы можете просто решить это с 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
отлично работает с отдельными переменными, но при работе с атрибутами объекта вам просто нужно убедиться, что (родительский) объект существует при этом.
Если у вас есть объект, который передается в представление, и, скажем, ваши данные — это «записи», которые хранятся внутри объекта, например:
$ 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