Laravel登录报错Attempt to read property "Name" on array 求解
报错原因
Attempt to read property "Name" on array 触发的直接原因是:Laravel 中 DB::select() 执行查询后返回值是结果集数组,而非单个查询结果对象,你直接对返回的数组用 -> 访问 Name 属性,必然抛出该错误。
现有代码的其他问题
除了触发报错的核心问题,你的代码还存在多处不符合Laravel开发规范、逻辑错误的问题:
- 直接在Blade视图模板中编写数据库查询、请求处理、跳转逻辑,完全违背Laravel的MVC设计原则,视图层只应负责页面渲染,业务逻辑需要下沉到控制器处理
- 未做空结果判断:如果查询的用户名不存在,
DB::select()会返回空数组,没有判断就直接访问属性必然报错 - 密码校验逻辑错误:Laravel默认用户密码使用bcrypt算法哈希存储,不能直接与POST提交的明文密码做等值比对
- 会话使用不规范:不需要手动调用
session_start(),Laravel已自动启动会话,应使用框架提供的Session类操作会话数据 - 跳转逻辑错误:不能直接通过header跳转到
.blade.php文件路径,应通过定义的路由使用redirect()方法跳转 - 原生SQL直接拼接用户输入存在安全隐患,优先使用框架提供的查询构造器或Eloquent ORM操作数据库
标准修复方案(推荐)
按照Laravel规范重构代码,分离视图和业务逻辑:
1. 新增路由(修改routes/web.php文件)
// 登录页展示路由 Route::get('/login', [\App\Http\Controllers\LoginController::class, 'showLoginForm']); // 登录提交处理路由 Route::post('/login', [\App\Http\Controllers\LoginController::class, 'login']);
2. 新建控制器处理登录逻辑
执行php artisan make:controller LoginController生成控制器文件,写入如下代码:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Session; class LoginController extends Controller { // 渲染登录页 public function showLoginForm() { return view('login'); } // 处理登录提交 public function login(Request $request) { // 校验提交参数 $validated = $request->validate([ 'txtuser' => 'required|string', 'txtpass' => 'required|string', ]); // 查询对应用户,first()直接返回单个结果对象,无结果返回null $user = DB::table('users')->where('Name', $validated['txtuser'])->first(); if (!$user) { return back()->withErrors(['txtuser' => 'No user found!']); } // 校验哈希密码 if (!Hash::check($validated['txtpass'], $user->password)) { return back()->withErrors(['txtpass' => 'wrong password!']); } // 写入登录会话 Session::put('loggedin', true); Session::put('user_info', [ 'id' => $user->id, 'name' => $user->Name ]); // 跳转至首页 return redirect('/home'); } }
3. 重构Blade模板(resources/views/login.blade.php)
删除模板中所有原生PHP业务逻辑,只保留视图渲染和表单部分,增加错误提示展示:
@extends("Layout") <div class="card2"> <div class="center"> <button><a href="{{url('/home')}}">Home</a></button> <button><a href="{{url('/b2b')}}">Business to business</a></button> <button><a href="{{url('/b2c')}}">Business to consumer</a></button> <button><a href="{{url('/c2c')}}">Consumer to consumer</a></button> <button><a href="{{url('login-system/login')}}">Login</a></button> <button><a href="{{url('/store')}}">Store</a></button> </div> <h1>Login</h1> {{-- 错误提示区域 --}} @if ($errors->any()) <div class="error-box"> @foreach ($errors->all() as $error) <p>{{ $error }}</p> @endforeach </div> @endif <form method="post" action="{{url('/login')}}"> @csrf <input type="text" name="txtuser" value="" /> <input type="password" name="txtpass" /> <input type="submit" name="login" value="submit"/> </form> </div>
临时修复方案(仅解决当前报错,不推荐长期使用)
如果暂时不想重构代码结构,仅修复当前报错,可将模板中的PHP逻辑部分替换为如下代码:
<?php if($_SERVER["REQUEST_METHOD"] == "POST") { echo '<p>TEST</p>'; $result = DB::select('select * from users where Name = ?', [$_POST["txtuser"]]); if(empty($result)) { echo 'No user found!'; } else { $user = $result[0]; // 注意:如果密码是哈希存储的,请替换为Hash::check($_POST["txtpass"], $user->password)做校验 if($user->password == $_POST["txtpass"]) { session()->put('loggedin', true); redirect('/home')->send(); exit; } else { echo 'wrong password!'; } } } ?>
该方案仅为临时应急使用,在视图中编写业务逻辑会大幅提升后期维护成本,且存在安全隐患,建议尽快按规范重构。
内容的提问来源于stack exchange,提问作者Jamie Lee Wilkinson
相关产品推荐
相关产品推荐

