对接短信接口,文档写着签名参数要带 13 位毫秒时间戳。用 date 拼出来是 14 位,接口回了个签名错误,日志里连请求体都没记下来,排查绕了一圈。
microtime(true) 给的是浮点秒
microtime(true) 返回类似 1740000000.1234 的浮点数,乘 1000 就到毫秒量级。直接 intval 有时会少一位,浮点表示不精确。写成 floor(microtime(true) * 1000) 更稳,取整方式选向下取整。32 位老机器上整数会溢出,这一点在旧项目里要留意。
位数固定要靠补零
取整之后的数字位数不固定,接口要求 13 位字符串时得补。sprintf 的写法是百分号加 013d,表示不足十三位左侧补零,拼出来正好。用 str_pad 也行,选项目里已经在用的那种写法,别混着来。补零漏了,签名照样对不上,报错却是一样的。
算耗时用 hrtime
统计接口跑了多少毫秒,别用两次 microtime 相减。系统时间被 NTP 往回校时,会算出负数。PHP 7.3 起有 hrtime(true),返回纳秒整数,除以一百万得毫秒,单调递增,不受改时间影响。日志里两个都记,方便对时间轴。
存库选类型
MySQL 的 datetime 括号里写 3 就能存到毫秒,写 6 是微秒。用 bigint 存 13 位整数也行,别用 int,2038 年之后会溢出。两种选一种,别一半存字符串一半存数字,排序和比较都会乱。
接口要几位就给几位。floor 加补零两步,比研究 date 的格式化字符快得多。