PHP 如何做并发

处理并发是后端开发里很常见的问题,哪怕是做个简单的投票页,100个人同时点“投”,也可能出现数据混乱——比如本该只有100票,结果算出101票,这就是并发没处理好的锅。很多用PHP做项目的开发者,常纠结“PHP怎么处理并发”,其实不用搞复杂的术语,用生活里的小事就能讲明白。

先搞懂:PHP为什么要处理并发?

PHP本身是“单线程同步”的,简单说就是同一时间只能干一件事。举个超市结账的例子:收银员(PHP进程)一次只能扫一个商品,要是100个顾客(并发请求)同时挤过来,收银员得一个一个来,要是没做安排,就会出现同一个商品被扫两次、算重了的情况——这就是并发冲突。

PHP 如何做并发

对网站来说,并发请求就是100个用户同时打开提交按钮,PHP得保证每个请求的操作不打架,比如用户抢优惠券,不能1张券被2个人都领到。

处理并发的核心:给共享资源“设关卡”

PHP里的共享资源一般是数据库、缓存这些,处理并发的核心就是让多个请求“排队用资源”,别乱抢,最常用的办法是“锁”,就像小区单元门的门禁,同一时间只让一个人进出:

  • 文件锁(适合小项目,比如博客的评论提交):PHP有个flock函数,就像给文件加个临时门锁。比如写评论时,先给评论文件加锁,别的请求要写就得等锁解开,写完再解锁,避免多条评论乱插。
  • 数据库锁(适合大多数项目,比如电商下单):这是最常用的,比如用MySQL的“行锁”,只锁当前要改的那一行数据,不是锁整个表。比如抢优惠券时,先查“还剩多少券”,如果剩1,就给这张券加锁,别的请求就看不到这张券的信息,这样就不会重复发券了。
  • 缓存锁(适合高并发场景,比如秒杀):Redis这类缓存能做“分布式锁”,比如秒杀商品,先给商品ID加个锁,只有拿到锁的请求能扣库存,别的请求直接返回“已抢完”,不用都去碰数据库,速度快还能防超卖。

简单实用的PHP并发处理实例

拿最常见的“抢优惠券”举例,用PHP+MySQL的行锁就能搞定,代码逻辑(简化版)是这样的:

每个请求过来,先查对应优惠券的剩余数量;

加行锁,确保同一时间只有一个请求能改这个优惠券的数据;

数量减1,保存到数据库,返回成功;

最后解锁,让下一个请求进来。

要是做小型项目,不用太复杂,用文件锁就能应付:比如写日志的时候,用flock给日志文件加锁,多个请求就不会把日志写混,不会出现“1234”后面跟着“5678”这种乱序的情况。

新手容易踩的坑

很多初学者会犯两个错:一是觉得“加锁会变慢”就干脆不加,结果出现数据错误;二是加了锁但忘了解锁,导致后面所有请求都卡住,就像超市收银员锁了门忘了开,后面顾客全没法结账。其实只要锁的范围只在“改数据”的那一小段代码里,就不会影响太多速度,反而能避免更麻烦的数据混乱问题。

其实PHP处理并发,本质就是让多个请求按顺序用共享资源,不用想的太复杂,从适合自己项目的小方法入手就行,比如小博客用文件锁,电商项目用数据库锁,高并发秒杀用缓存锁,一步步来就没问题。

上一篇 Java 如何卸载