800 字
4 分钟
PHP 实现金额语音播报接口

PHP 实现金额语音播报接口#

在收银系统、收款提醒、桌面播报等场景中,经常需要将数字金额转为语音播报。本文使用 PHP 编写一套金额语音合成接口,通过拆分数字、匹配对应读音音频,将多段 MP3 按顺序拼接并以流的形式返回,实现完整的语音播报能力。

一、功能简介#

  1. 接收 GET 方式传递的金额数字,支持整数、小数格式。
  2. 严格校验参数格式,非法参数直接返回错误状态码。
  3. 根据数字位数、单位(个、十、百、千、万、亿、小数点)匹配对应音频文件。
  4. 自动拼接「叮、到账、金额、元」等多段音频,流式输出 MP3。
  5. 增加文件存在性检测,音频缺失时返回服务端错误。
  6. 自带跨域响应头,可直接被前端页面调用。

二、完整接口代码与逻辑说明#

新建 PHP 文件,粘贴以下全部代码:

<?php
// 允许跨域请求
header("Access-Control-Allow-Origin: *");
// 音频文件存放目录(与当前php文件同级的 mp3 文件夹)
$voiceDir = __DIR__ . '/mp3/';
// 获取 GET 传递的 money 参数
$num = trim($_GET['money'] ?? '');
// 正则校验:仅允许纯数字 + 小数格式
if (!preg_match('/^\d+(\.\d+)?$/', $num)) {
http_response_code(400);
exit;
}
// 数字读音映射
$AA = ["0","1","2","3","4","5","6","7","8","9"];
// 数位、小数点读音映射
$BB = ["","shi","bai","qian","wan","yi","dian",""];
// 将数字按小数点拆分为 整数部分、小数部分
$a = explode(".", $num);
// 去除整数部分前面多余的 0
$intStr = ltrim($a[0], '0');
if ($intStr === '') {
$intStr = '0';
}
$re = [];
// 处理整数部分为 0 的场景
if ($intStr === '0') {
$re[] = '0';
// 存在小数部分
if (isset($a[1]) && $a[1] !== '') {
$re[] = 'dian';
for ($i = 0; $i < strlen($a[1]); $i++) {
$re[] = $AA[(int)$a[1][$i]];
}
}
} else {
$intLen = strlen($intStr);
$k = 0;
// 从后往前遍历整数,组合数位与读音
for ($i = $intLen - 1; $i >= 0; $i--) {
switch ($k) {
case 0:
array_unshift($re, $BB[7]);
break;
case 4:
$reg = "/0{4}\d{" . ($intLen - $i - 1) . "}$/";
if (!preg_match($reg, $intStr)) {
array_unshift($re, $BB[4]);
}
break;
case 8:
array_unshift($re, $BB[5]);
$BB[7] = $BB[5];
$k = 0;
break;
}
// 处理中间零的读音
if ($k % 4 == 2 && isset($intStr[$i+2]) && $intStr[$i+2] != '0' && isset($intStr[$i+1]) && $intStr[$i+1] == '0') {
array_unshift($re, $AA[0]);
}
$currChar = $intStr[$i];
if ($currChar != '0') {
array_unshift($re, $BB[$k % 4]);
array_unshift($re, $AA[(int)$currChar]);
}
$k++;
}
// 拼接小数部分读音
if (isset($a[1]) && $a[1] !== '') {
$re[] = $BB[6];
for ($i = 0; $i < strlen($a[1]); $i++) {
$re[] = $AA[(int)$a[1][$i]];
}
}
}
// 过滤空值,重新整理数组下标
$re = array_values(array_filter($re, fn($v) => $v !== ''));
// 组装完整音频列表:开头音效 + 金额读音 + 结尾单位
$fileList = [];
$fileList[] = $voiceDir . 'ding.mp3';
$fileList[] = $voiceDir . 'daozhang.mp3';
foreach ($re as $val) {
$fileList[] = $voiceDir . $val . '.mp3';
}
$fileList[] = $voiceDir . 'yuan.mp3';
// 遍历检测所有音频文件是否存在、可读
foreach ($fileList as $file) {
if (!file_exists($file) || !is_readable($file)) {
http_response_code(500);
exit;
}
}
// 设置响应头为音频类型
header("Content-Type: audio/mpeg");
header("Content-Disposition: inline; filename=alipay.mp3");
// 清空缓冲区,准备流式输出
ob_clean();
flush();
// 分段读取音频并输出,实现无缝播放
foreach ($fileList as $file) {
$handle = fopen($file, 'rb');
while (!feof($handle)) {
echo fread($handle, 8192);
flush();
}
fclose($handle);
}
exit;
?>

具体MP3文件可进QQ群516128569见群文件

PHP 实现金额语音播报接口
https://blog.137869.xyz/posts/guide/
作者
Sucyan.苏青
发布于
2026-05-30
许可协议
2026 苏青