
本文旨在解决 laravel 项目中模型隐藏属性在特定场景下无法通过查询构建器直接显示的问题。通过详细阐述 `makevisible()` 方法在 eloquent 集合上的正确应用,我们将展示如何在分页查询结果中动态地暴露模型的隐藏属性,从而确保数据按需展示,同时维持模型的默认隐私设置。
在 Laravel 应用开发中,我们经常会使用模型的 $hidden 属性来隐藏敏感或不常用的数据字段,例如密码、API 密钥或内部标识符等。这是一种良好的安全实践,可以防止这些数据在默认情况下被意外暴露。然而,在某些特定的业务场景下,我们可能需要在特定路由或视图中临时显示这些通常被隐藏的属性。
Laravel Eloquent 模型提供了一个 $hidden 属性数组,用于指定在模型被序列化为数组或 JSON 时应隐藏的属性。例如:
class Hoster extends Model
{
protected $hidden = [
'past_works',
'anchor',
'contact_number',
'email'
];
// ... 其他模型定义
}当模型实例被转换为数组或 JSON 时,past_works、anchor、contact_number 和 email 这些属性将不会包含在输出中。
当使用 Laravel 的查询构建器(Query Builder)进行数据查询,并结合 paginate() 方法获取分页结果时,开发者可能会遇到一个问题:如何让查询结果中的模型实例显示其隐藏属性?
直接尝试在查询构建器链式调用中使用 makeVisible() 是无效的,因为 makeVisible() 是 Eloquent Collection(集合)上的方法,它作用于已经从数据库中检索并实例化后的模型对象集合,而不是作用于 SQL 查询本身。查询构建器负责构造并执行数据库查询,而模型的隐藏/显示逻辑是在模型被实例化并准备序列化时才发挥作用。
考虑以下控制器中的查询代码:
// 原始控制器代码片段
$hosters = Hoster::query()
->when($request->input('search'), function ($query, $search) {
if ($search == "approved") {
return $query->where('is_approved', '=', true);
} elseif ($search == "notapproved") {
return $query->where('is_approved', '=', false);
}
return $query
->where('name', 'like', '%' . $search . '%')
->orWhere('contact_number', 'like', '%' . $search . '%')
->orWhere('email', 'like', '%' . $search . '%');
})
->orderBy('created_at', 'desc')
->paginate(8)
->withQueryString();
// 此时 $hosters 是一个 LengthAwarePaginator 实例
// 如果直接在此处尝试 $hosters->makeVisible(),它会作用于整个分页器
// 并且 makeVisible 方法实际存在于 LengthAwarePaginator 内部的 collection 上
// 或者 LengthAwarePaginator 本身转发了此调用正确的做法是在查询执行完毕,获取到模型集合(或分页器实例)之后,再调用 makeVisible() 方法。paginate() 方法返回的是一个 Illuminate\Pagination\LengthAwarePaginator 实例,这个分页器实例封装了一个 Eloquent 模型的集合。LengthAwarePaginator 类已经实现了 makeVisible() 方法的转发,因此可以直接在其上调用。
makeVisible() 方法接收一个数组作为参数,数组中包含你希望临时显示的属性名称。
下面是修改后的控制器代码示例:
use Illuminate\Http\Request;
use Inertia\Inertia;
use App\Models\Hoster; // 确保引入你的模型
class HosterController extends Controller
{
public function show(Request $request)
{
$hosters = Hoster::query()
->when($request->input('search'), function ($query, $search) {
if ($search == "approved") {
return $query->where('is_approved', '=', true);
} elseif ($search == "notapproved") {
return $query->where('is_approved', '=', false);
}
return $query
->where('name', 'like', '%' . $search . '%')
->orWhere('contact_number', 'like', '%' . $search . '%')
->orWhere('email', 'like', '%' . $search . '%');
})
->orderBy('created_at', 'desc')
->paginate(8)
->withQueryString();
// 在获取到分页器实例后,调用 makeVisible() 方法
// 传入需要临时显示的属性数组
$hosters->makeVisible([
'past_works',
'contact_number',
'email'
// 根据需要添加其他隐藏属性
]);
return Inertia::render('Hoster/Show', [
'hosters' => $hosters,
'filters' => $request->only(['search']),
]);
}
}在上述代码中,$hosters 变量在调用 paginate(8) 后成为了一个 LengthAwarePaginator 实例。紧接着,我们在这个实例上调用了 makeVisible(['past_works', 'contact_number', 'email'])。这会遍历分页器内部的每个 Hoster 模型实例,并临时将其 past_works、contact_number 和 email 属性设置为可见。当这些模型数据被序列化并传递给 Inertia 视图时,这些属性将包含在输出中。
$hosters->setVisible(['id', 'name', 'email']); // 只显示 id, name, email
通过在 Eloquent 集合(或分页器实例)上正确使用 makeVisible() 方法,我们可以灵活地控制 Laravel 模型隐藏属性的可见性。这种方法允许我们在不修改模型默认配置的前提下,根据特定的业务需求动态地展示数据。在实际开发中,结合权限控制和 Laravel API 资源等工具,可以构建出既安全又灵活的数据展示方案。
以上就是如何在 Laravel 查询构建器中显示隐藏属性的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号