跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

ThinkPHP怎么实现语音验证码_ThinkPHPTTS集成方法【方法】

ThinkPHP 的 think-captcha 仅支持图形验证码,不支持语音生成,因其底层仅依赖 GD 库绘图,无 TTS 或音频处理逻辑;需自行实现语音接口,通过调用云 TTS、本地 espeak 或数字音频拼接生成 MP3,并将验证码字符串存入 Session 供后端验证。 ThinkPHP 本身不提供语音验证码能力,必须靠外部 TTS 服务或本地命令行工具生成音频文件,再由 PHP 输出路径或流。直接调用
Captcha
类只能出图,不能出声。 为什么不能用 think-captcha 直接生成语音
think-captcha
是纯图形验证码组件,底层依赖 GD 库绘图,所有方法(如
entry()
、
create()
)只返回图像响应(
Content-Type: image/png
)。它没有音频生成逻辑,也不处理语音合成、文件拼接或 TTS 请求封装。 试图给
Captcha
传
type => 'mp3'
或类似参数——会静默忽略,仍输出图片 在控制器里调用
captcha_check()
验证语音输入?该函数只比对 Session 中的图形码明文,和语音内容无关 混淆点:有些文档把“语音验证码”和“图形验证码+语音播报按钮”混为一谈,后者是前端 JS 播放预录提示音,不是真 TTS 推荐做法:PHP 后端生成语音文件 URL,前端播放 核心思路是绕过
think-captcha
,自己写一个语音生成接口,返回可直接被
加载的 MP3/WAV 路径。有三种落地方式: 调用百度/腾讯云 TTS API :需注册平台、获取
access_token
,POST 到
https://tsn.baidu.com/text2audio
,注意
tex
参数要
urlencode()
,且必须带
vol
、
spd
等参数,否则返回错误码 本地执行 espeak :Ubuntu 上
sudo apt install espeak
,PHP 中用
exec("espeak -v zh -w /tmp/verify_".uniqid().".mp3 '您的验证码是 3729'")
,但要注意
www-data
用户是否有权限写入
/tmp
和执行二进制 数字片段拼接(最稳) :提前录好
0.mp3
~
9.mp3
和
prompt.mp3
,PHP 用
file_get_contents()
读取并合并(可用
ffmpeg
命令或
php-ffmpeg
库),生成完整语音文件 Session 存什么、前端怎么传、后端怎么验 图形码靠 Session 存原始字符串,语音码也得存——但不能存语音文件内容,而要存**本次生成的验证码数字本身**(比如
3729
),和图形码完全一样。区别只在呈现方式。 PHP 8.5.5 PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。 下载 立即学习 “ PHP免费学习笔记(深入) ”; 生成语音接口时,先用
session('voice_code', $code)
把数字写入 Session,再调 TTS 或拼接音频 前端提交表单时,用户听到语音后手动输入,把文本值(如
input[name="voice_code"]
)发到后端 验证逻辑就是:
if (session('voice_code') === input('post.voice_code')) { /* 通过 */ }
,不需要任何额外扩展 务必在验证后立即
session('voice_code', null)
清除,避免重放 容易被忽略的兼容性与安全细节 语音验证码不是“加个 audio 标签”就完事,几个硬伤常被跳过: MP3 文件路径必须能被 Web 服务器直接访问(比如放在
public/voice/
下),不能藏在
app/
里;否则前端
会 404 如果用
readfile()
输出音频流,记得设 header:
header('Content-Type: audio/mpeg');
,否则浏览器无法识别 验证码数字若含前导零(如
0283
),PHP 默认转成整数会丢掉,必须全程当字符串处理:
(string)rand(1000, 9999)
或用
sprintf('%04d', $n)
别让同一个语音 URL 被反复请求——每次生成都要用
uniqid()
或时间戳命名文件,否则 CDN 或浏览器缓存会导致用户听到旧码

相关文章