您可以使用 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: "user1@thisisdevelopment.nl",
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或key/attribute不存在,默认为null。
编辑:
刚刚看到要求额外解释原始代码为何不起作用的请求。
索引 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 并不重要,它甚至不会进入三元语句,因为 $blogs 上缺少 0 索引。
按要求编辑 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] 是一个有效对象。为了做到这一点,它将尝试从索引 0 处的 $blogs 数组中获取对象。但由于该索引不存在,它将触发带有 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 可以完美地处理单个变量,但是在处理对象属性时,您只需要确保(父)对象存在即可。