如何在Laravel中实现发布超过30天的帖子自动修改状态为deleted
Laravel 实现过期帖子自动更新状态方案
1. 前置条件确认
- 确保
posts表已存在created_at(Laravel 自带 timestamps 字段默认生成)和status字段,status字段支持存储deleted值 - 确保已创建对应的
Post模型,路径通常为app/Models/Post.php(Laravel 8及以上版本,低版本路径为app/Post.php)
2. 业务逻辑实现(二选一即可)
方案一:自定义 Artisan 命令(规范易维护,适合后续扩展逻辑)
- 项目根目录执行终端命令生成命令文件:
php artisan make:command ExpirePostsCommand - 打开生成的
app/Console/Commands/ExpirePostsCommand.php文件,替换为以下代码:
<?php namespace App\Console\Commands; use Illuminate\Console\Command; use App\Models\Post; use Carbon\Carbon; class ExpirePostsCommand extends Command { protected $signature = 'posts:expire'; protected $description = '将发布超过30天的帖子状态更新为deleted'; public function handle() { $updatedNum = Post::where('created_at', '<', Carbon::now()->subDays(30)) ->where('status', '!=', 'deleted') ->update(['status' => 'deleted']); $this->info("已成功更新{$updatedNum}条过期帖子"); return Command::SUCCESS; } }
- 手动执行测试逻辑是否正常:
php artisan posts:expire
方案二:调度内核直接写闭包(适合简单逻辑,无需额外文件)
无需生成单独命令文件,直接在后续调度配置中写业务逻辑即可。
3. 配置 Laravel 调度规则
打开app/Console/Kernel.php文件,在schedule方法中添加对应配置:
protected function schedule(Schedule $schedule) { // 若使用方案一,添加此行 $schedule->command('posts:expire')->daily(); // 若使用方案二,添加此段 $schedule->call(function () { \App\Models\Post::where('created_at', '<', \Carbon\Carbon::now()->subDays(30)) ->where('status', '!=', 'deleted') ->update(['status' => 'deleted']); })->daily(); }
你可以根据需求调整执行频率:
->dailyAt('2:00')每天凌晨2点执行->hourly()每小时执行一次->twiceDaily(1, 13)每天1点、13点各执行一次
4. 配置服务器定时任务触发调度
Laravel 调度本身需要服务器 crontab 每分钟触发才能生效,操作如下:
- 终端执行
crontab -e编辑定时任务 - 加入以下配置,将
/你的项目根目录绝对路径替换为实际项目路径:* * * * * cd /你的项目根目录绝对路径 && php artisan schedule:run >> /dev/null 2>&1 - 保存退出后 crontab 自动生效,后续任务会按照配置的频率自动执行。
内容的提问来源于stack exchange,提问作者Paul Chase
相关产品推荐
相关产品推荐

