Shopware插件促销码重复分配问题咨询
我来针对你的三个问题逐一分析,结合你提供的代码细节来拆解:
1. 插件是否真的生成唯一码?会不会重用旧码?
你当前依赖uniqid('test-')生成促销码,但这个PHP函数本身不保证全局唯一性。uniqid的底层逻辑是基于系统当前的微秒时间戳生成字符串,如果多个请求在同一微秒内触发coupon方法,就会生成完全相同的码。
你的代码里生成促销码后,既没有校验这个码是否已经存在于Shopware的促销系统中,也没有先将其与订单绑定再发送邮件——所以本质上是「生成时不保证唯一,生成后不做重复校验」,并非主动重用旧码,但存在极高的概率生成与历史旧码重复的新码。
2. 为什么两个不同客户会拿到相同的促销码?
核心原因是uniqid在高并发场景下的唯一性漏洞:
比如两个用户几乎同时提交评论触发了coupon接口,服务器在同一微秒内处理这两个请求,strtoupper(uniqid('test-'))会生成完全一致的字符串,随后分别发送给不同客户,最终导致两人拿到重复的促销码。
而且你的流程里没有任何「生成后校验唯一性再发送」的逻辑,直接将生成的码发送给客户,相当于把重复风险直接传递给了用户。
3. 如果插件重用旧码,为什么会分配给新客户?
从你的代码逻辑来看,插件并没有主动去重用旧码,更可能的情况是新生成的码恰好和某个已使用的历史旧码重复。
因为uniqid的熵(唯一标识的复杂度)不够高,加上你没有在生成后校验这个码是否已经被Shopware的促销系统记录(比如是否有其他订单、其他用户已经使用过该码),所以当生成的重复码与历史旧码撞车时,就会出现新客户拿到的码在系统中已有旧客户使用记录的矛盾情况。
额外的流程风险提示
从你的代码还能看到一个潜在问题:你在coupon方法里先发送带促销码的邮件,再通过updatePromotionCode绑定到订单(假设updatePromotionCode是在发邮件后触发),如果这两个步骤之间出现异常,可能会导致「客户收到了码,但订单里没有记录」的情况,不过这和当前的重复码问题关联不大。
如果要彻底解决重复问题,建议:
- 改用熵更高的唯一码生成方式,比如结合UUID(
uuid_create(UUID_TYPE_RANDOM)),或者在uniqid后拼接随机字符串增加复杂度 - 生成促销码后先做双重校验:检查该码是否存在于Shopware的
promotion_code表,以及是否已被其他订单的自定义字段存储,确认唯一后再发送邮件并绑定订单
备注:内容来源于stack exchange,提问作者Auhona

