Laravel模型默认使用时间戳以实现“约定优于配置”,自动记录数据的创建和更新时间,通过created_at和updated_at字段提供数据追踪能力。框架底层将时间戳存储为DATETIME或TIMESTAMP类型,并在模型中转换为Carbon实例,便于格式化和比较。可通过对模型设置$timestamps = false禁用此功能,或通过定义CREATED_AT和UPDATED_AT常量自定义字段名。访问时可直接使用Carbon方法进行时间处理。利用时间戳可实现基础审计、数据生命周期管理、缓存失效策略、报表分析及乐观锁辅助。常见误区包括使用查询构建器时updated_at不自动更新,规避方式是优先通过模型实例操作或手动设置时间字段;时区配置不一致可能导致时间显示错误,建议数据库和应用均使用UTC并在展示时转换;批量操作时时间戳更新可能带来性能开销,可通过withoutTimestamps()临时禁用。功能扩展包括使用软删除实现deleted_at字段,添加自定义时间字段如published_at并通过$casts转换为datetime,利用$touches属性在子模型更新时同步更新父模型时间戳,结合模型观察者监听时间变化触发日志、缓存清理等逻辑,或集成第三方包实现完整操作审计。

Laravel模型中的时间戳,本质上是数据库表里的
created_at
updated_at
管理和使用Laravel模型的时间戳,通常涉及理解其默认行为、根据需求进行调整,以及在特定场景下进行干预。
默认情况下,当你创建一个新的模型实例并保存时,
created_at
updated_at
updated_at
DATETIME
TIMESTAMP
Carbon
如果你不希望某个模型自动维护时间戳,可以在模型类中设置
public $timestamps = false;
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
public $timestamps = false;
// ...
}有时,你的数据库表可能使用了不同的时间戳字段名,比如
creation_date
last_modified_date
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
const CREATED_AT = 'creation_date';
const UPDATED_AT = 'last_modified_date';
// ...
}访问时间戳非常直接,由于它们被转换为
Carbon
Carbon
$user = User::find(1);
echo $user->created_at->format('Y-m-d H:i:s'); // 格式化输出
echo $user->updated_at->diffForHumans(); // "5 minutes ago"如果你需要在保存模型时临时禁用时间戳更新,例如在导入旧数据时想保留原始的
updated_at
$post = Post::find(1); $post->timestamps = false; // 禁用时间戳更新 $post->title = '新的标题'; $post->save(); $post->timestamps = true; // 重新启用(如果后续还需要)
Laravel模型默认启用时间戳,这其实是框架设计哲学中“约定优于配置”的一个典型体现。从我的经验来看,这大大减少了我们在数据层面做审计和追踪的重复工作。想象一下,如果每次创建或更新数据,我们都得手动去设置
created_at
updated_at
利用时间戳进行数据追踪,远不止看看数据是什么时候创建或修改的那么简单:
created_at
updated_at
updated_at
created_at
updated_at
updated_at
updated_at
updated_at
updated_at
updated_at
尽管Laravel的时间戳机制非常方便,但在实际开发中,我确实遇到过一些让人头疼的“坑”,或者说是一些容易被忽略的细节。
一个最常见的误区,也是初学者经常会踩的坑,就是使用查询构建器(Query Builder)进行更新操作时,updated_at
DB::table('users')->where('id', 1)->update(['name' => 'New Name']);updated_at
updated_at
规避方法: 除非你明确知道自己在做什么,并且不需要
updated_at
$user = User::find(1); $user->name = '新的名字'; $user->save(); // 此时 updated_at 会自动更新
如果你确实需要使用查询构建器,但又想更新
updated_at
DB::table('users')->where('id', 1)->update([
'name' => 'New Name',
'updated_at' => now(), // 手动设置
]);第二个“坑”是时区问题。数据库通常会存储UTC时间,而你的应用可能在
config/app.php
Carbon
规避方法: 最佳实践是让数据库和应用都使用UTC时间存储和处理。在
config/app.php
timezone
'UTC'
Carbon
// config/app.php 'timezone' => 'UTC',
第三个可能遇到的问题是,在进行大量数据导入或批量操作时,时间戳的自动更新可能会带来额外的性能开销。虽然对于大多数应用来说,这种开销可以忽略不计,但如果你正在处理百万级别的数据,每次保存都触发时间戳更新和相关事件,可能会拖慢进程。
规避方法: 在这种极端情况下,你可以考虑暂时禁用时间戳,或者使用原始SQL语句进行批量操作,并在操作完成后,手动更新相关记录的
updated_at
// 临时禁用时间戳
Model::withoutTimestamps(function () use ($data) {
foreach ($data as $item) {
// 创建或更新模型,此时时间戳不会自动更新
MyModel::create($item);
}
});created_at
updated_at
created_at
updated_at
一个最直接且内置的扩展就是软删除(Soft Deletes)。当我们需要“删除”一条数据,但又不想真正从数据库中移除它时,软删除就派上用场了。它通过在模型中添加一个
deleted_at
delete()
deleted_at
withTrashed()
onlyTrashed()
要使用软删除,只需在模型中引入
SoftDeletes
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes; // 引入 Trait
class Post extends Model
{
use SoftDeletes; // 使用 Trait
// ...
}然后在数据库迁移中添加
deleted_at
Schema::table('posts', function (Blueprint $table) {
$table->softDeletes(); // 添加 deleted_at 字段
});除了软删除,我们还可以添加自定义的时间戳字段来追踪更具体的业务状态。例如,一个文章模型可能需要一个
published_at
paid_at
shipped_at
在数据库迁移中添加这些字段:
Schema::table('articles', function (Blueprint $table) {
$table->timestamp('published_at')->nullable(); // 可空的时间戳
});在模型中,为了让Laravel自动将这些字段转换为
Carbon
$casts
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
protected $casts = [
'published_at' => 'datetime',
];
// ...
}这样,你就可以像操作
created_at
published_at
$article = Article::find(1); $article->published_at = now(); $article->save();
另一个非常实用的功能是“触摸”父级时间戳(Touching Parent Timestamps)。假设你有一个
Post
Comment
updated_at
$touches
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
protected $touches = ['post']; // 当 Comment 更新时,关联的 Post 的 updated_at 也会更新
public function post()
{
return $this->belongsTo(Post::class);
}
}对于更复杂的逻辑,比如在某个时间戳更新时触发特定的业务流程,或者需要记录更详细的历史版本,模型观察者(Model Observers)和事件(Events)是强大的工具。你可以在
updating
saved
User
updated_at
// UserObserver.php
namespace App\Observers;
use App\Models\User;
class UserObserver
{
public function updated(User $user)
{
// 只有当 updated_at 字段实际改变时才执行逻辑
if ($user->isDirty('updated_at')) {
// 记录日志,或者触发其他业务逻辑
\Log::info("用户 {$user->id} 的信息在 {$user->updated_at} 被更新了。");
}
}
}最后,如果你的需求是完整的版本控制或操作历史记录,那么仅仅依赖时间戳可能就不够了。这时,你可以考虑使用专门的包(如
spatie/laravel-activitylog
owen-oj/laravel-auditing
history
以上就是Laravel模型时间戳?时间戳怎样管理使用?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号