Laravel框架下无需循环获取指定唯一名称Hero表ID的实现方法
结论先行
你现在写的Hero::where('name_hero', $name_hero)->value('id')本身就没有遍历全表的问题,只要你给name_hero字段加上唯一索引,数据库会直接走索引定位到对应行,时间复杂度和Auth::user()->id完全一致,已经是最优实现。
如果你想要实现和Auth::user()->id完全一致的链式调用风格,可以按下面两种方案改造:
方案1:模型新增静态方法(最常用)
直接在Hero模型中新增自定义静态查询方法:
// app/Models/Hero.php class Hero extends Model { // 其他原有逻辑 public static function findByName(string $name_hero) { // 加firstOrFail是为了匹配不到时直接抛异常,和Auth的逻辑一致 return self::where('name_hero', $name_hero)->firstOrFail(); } }
调用方式就可以写成你要的链式风格:
$batmanId = Hero::findByName('batman')->id;
方案2:自定义全局辅助函数(最贴近Auth调用体验)
如果想要进一步简化调用,和Auth::user()一样不需要写模型名前缀,可以自定义全局辅助函数:
- 新建
app/helpers.php文件,写入如下内容:
<?php if (! function_exists('hero')) { function hero(string $name_hero) { return App\Models\Hero::where('name_hero', $name_hero)->first(); } }
- 在项目根目录的
composer.json中找到autoload配置块,新增files项引入辅助函数:
"autoload": { "psr-4": { "App\\": "app/", "Database\\Factories\\": "database/factories/", "Database\\Seeders\\": "database/seeders/" }, "files": [ "app/helpers.php" ] }
- 执行
composer dump-autoload让配置生效。
之后就可以直接用全局函数调用:
$batmanId = hero('batman')->id;
额外性能优化建议
- 务必给
name_hero字段添加唯一索引,迁移文件写法如下:
加索引后单表百万级数据查询也能在1ms内完成,完全不会有遍历开销。$table->string('name_hero')->unique(); - 如果同名英雄查询频率很高,可以在查询逻辑中加缓存,避免重复请求数据库:
public static function findByName(string $name_hero) { return cache()->remember("hero:{$name_hero}", 86400, function () use ($name_hero) { return self::where('name_hero', $name_hero)->firstOrFail(); }); }
内容的提问来源于stack exchange,提问作者thep200
相关产品推荐
相关产品推荐

