Laravel 7 获取数据库数据时出现Undefined Offset错误求助
首先,先修正你Controller里的一个小错误:DB::select('users') 写法不对,select 方法需要传入完整的SQL语句,比如 DB::select('SELECT * FROM users WHERE user_deleted_flag != ?', [true]),但更推荐用Eloquent的查询构造器写法(更简洁且安全):
public function index(){ $data['modules'] = DB::table('users') ->where('user_deleted_flag', '!=', true) ->get(); return view('index', $data); }
这个写法错误可能导致你获取的结果不符合预期,先修正它。
接下来解决你核心的问题:Undefined Offset错误,以及PHP7.4中不能用array_key_exists()检查对象的问题。你查询返回的$modules是Collection对象(不是普通数组),所以不能用array_key_exists(),但Collection提供了专门的方法来处理这类场景,下面给你几种可行的方案:
方案1:在Blade模板中直接安全取值
Collection的get()方法支持传入索引和默认值,当指定索引不存在时,会返回你设置的默认值(比如空字符串),完美避免Undefined Offset错误:
@for($i=0;$i<13; $i++) {{ $modules->get($i, '') }} @endfor
你也可以用isset()来判断,因为Collection实现了ArrayAccess接口,支持数组式访问的判断:
@for($i=0;$i<13; $i++) {{ isset($modules[$i]) ? $modules[$i] : '' }} @endfor
或者用Collection自带的offsetExists()方法,这是专门用来检查索引是否存在的:
@for($i=0;$i<13; $i++) {{ $modules->offsetExists($i) ? $modules[$i] : '' }} @endfor
方案2:在Controller中提前填充元素
如果你希望$modules始终有13个元素,不足的部分用空值填充,可以用Collection的pad()方法:
public function index(){ $modules = DB::table('users') ->where('user_deleted_flag', '!=', true) ->get(); // 将集合填充到13个元素,不足的用null填充(你可以换成其他默认值,比如空对象) $modules = $modules->pad(13, null); $data['modules'] = $modules; return view('index', $data); }
这样在Blade模板中直接循环就不会报错了,不存在的元素会显示为null(你可以根据需求修改填充的默认值)。
额外说明
为什么array_key_exists()不能用?因为PHP7.4开始,array_key_exists()不再支持检查对象的属性/偏移,而Eloquent返回的Collection是对象,不是数组。你也可以将Collection转换成数组($modules->toArray()),但这样就失去了Collection的便捷方法,不推荐。
内容的提问来源于stack exchange,提问作者Skumar

