PHP 如何做定时并发
早上到公司,刚泡上茶,就收到运营同学的消息:“今天要给新用户发1000张满减券,得10点整准时发,不能早也不能晚!” 要是用PHP做这个任务,很多人第一反应是“PHP不是写网页的吗?能做定时任务?” 其实只要用对方法,PHP做定时任务并发一点都不难,今天就用日常例子给你讲明白。
先搞懂两个基础:定时和并发是什么
很多人刚接触的时候容易把这俩混在一起,其实分开看就简单。

定时就像家里的闹钟,比如你设7点闹钟叫你起床,到点就响,不用你一直盯着。PHP里的定时,就是让电脑到某个时间自动触发任务,不用人工点“开始”。
并发更简单,比如你去奶茶店点单,10个人同时下单,店员要同时处理,不能说先做第一个再做后面的,这就是并发。刚才说的发1000张券,要是一张一张发,用户得等好久,必须同时处理,这就是PHP定时要实现的并发。
第一种:用Linux自带工具做定时(最常用,适合新手)
大部分PHP项目都是放在Linux服务器上的,Linux自带一个叫“crontab”的工具,就像电脑的系统闹钟,比自己写代码做定时靠谱多了。
举个例子,你要每天10点发券,只要在服务器里输一行简单的命令,就能设置定时:0 10 * * * php /var/www/project/send_coupon.php。这行命令的意思是:每天(*代表任意天)10点(0分),自动执行send_coupon.php这个PHP文件,不用你手动打开。
那并发怎么实现?很简单,只要在send_coupon.php里写个循环,把1000张券的任务拆成100个小任务,或者用PHP的多进程扩展,比如pcntl_fork,就像奶茶店同时叫10个店员帮忙做单,不用等一个做完再做下一个。比如循环里每创建一个子进程处理10张券,100个进程一起跑,1000张券几秒就发完了,用户不会等。
要注意的是,crontab是“触发定时”,要是PHP脚本执行时间太长,别让crontab重复触发,不然会有两个脚本同时跑,反而乱了。
第二种:用PHP扩展做定时(适合复杂场景)
要是项目里需要更灵活的定时,比如每个用户的任务时间不一样,不是统一的10点,用crontab就麻烦了,这时候可以用PHP的扩展“Gearman”或者“Redis+队列”。
举个例子,你要给新用户按注册时间发券,注册时间是10点、10点1分、10点2分,各有100个用户。你可以先把这些任务放进Redis队列,就像把订单放在取餐台上,然后用PHP的“Worker”进程(相当于奶茶店的后台处理组)盯着队列,到时间就取任务处理,同时可以开多个Worker进程,比如10个,同时处理10个任务,并发就搞定了。
这种方法比crontab更灵活,不用改服务器配置,只需要在PHP代码里操作,适合中小项目自己维护,不会的话,用现成的第三方库也可以,不用自己写Worker。
避坑:这两个错误别踩
很多新手第一次做的时候容易踩坑,记住这两点就稳了。
第一个坑:别用PHP的sleep()做定时,比如写while(true){ send_coupon(); sleep(3600); },这样要是服务器重启,任务就没了,就像闹钟没电了不响,不靠谱。
第二个坑:别让定时任务的并发数太高,比如一下子开1000个进程,服务器会“卡壳”,就像奶茶店一下子来100个客人,店员忙不过来反而出餐慢,最好控制并发数在10-50之间,根据服务器性能调整就行。
其实PHP做定时并发,核心就是“找靠谱的定时触发工具,再用多进程或队列实现并发”,不用写复杂的代码,只要选对方法,哪怕是刚学PHP的新手,也能轻松实现发券、定时清理数据这类日常任务。