调用美团AI菜品识别API前必须确认的三件事:一是申请API Key和Secret并获取access_token,二是图片须Base64编码且≤4MB,三是请求必须用application/x-www-form-urlencoded格式、Authorization头为Bearer {token}、type=dish。

调用美团AI菜品识别API前必须确认的三件事
美团AI菜品识别不是本地函数,没有 meituan_recognize_dish() 这种PHP内置方法。它只提供HTTP接口,必须用 cURL 或 file_get_contents() 发起POST请求,且需提前申请API Key和Secret——没拿到 access_token,所有请求都会返回 {"code":401,"msg":"Unauthorized"}。
- 去美团开放平台创建应用,开通「菜品识别」能力,拿到
client_id和client_secret -
access_token有2小时有效期,不能硬编码进脚本,得每次请求前先调用/api/v1/oauth2/token换取(注意:该接口只认application/x-www-form-urlencoded) - 图片必须 Base64 编码后作为
image字段传入,不能传本地路径或URL;大小限制为 ≤4MB,超限会返回{"code":400,"msg":"invalid image"}
PHP发送识别请求的实际写法(避开cURL常见坑)
别直接拼JSON字符串发POST,美团接口对Content-Type和字段名极其敏感。下面这段能跑通:
$token = getAccessToken(); // 自己实现的获取token函数
$imageData = base64_encode(file_get_contents('/path/to/menu.jpg'));
$data = [
'image' => $imageData,
'type' => 'dish', // 固定值,不是'dish_recognition'也不是'food'
];
$options = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\nAuthorization: Bearer {$token}\r\n",
'content' => http_build_query($data),
],
];
$result = file_get_contents('https://openapi.meituan.com/api/v1/ai/dish/recognition', false, stream_context_create($options));
- 必须用
application/x-www-form-urlencoded,用application/json会返回415 Unsupported Media Type -
Authorization头格式是Bearer {access_token},少空格或多空格都失败 -
type=dish是唯一合法值,填错会返回{"code":400,"msg":"Invalid type"} - 如果用
cURL,记得关掉CURLOPT_SSL_VERIFYPEER(美团证书链偶尔有问题),但生产环境应改用系统CA包
解析返回结果时最容易忽略的字段含义
响应体是JSON,但结构不像百度或阿里那么“友好”。关键点:
-
result是数组,每个元素代表一个检测到的菜品,不是按置信度排序,而是按图片中从左到右、从上到下的位置顺序 -
name字段是识别出的中文菜名,但可能带括号备注(如“宫保鸡丁(辣)”),别直接当数据库主键用 -
score是0~1之间的浮点数,不是百分比;低于0.6的结果大概率不准,建议过滤掉 - 没有OCR文字坐标信息,
bounding_box字段只在部分高阶套餐里返回,普通版返回空数组
为什么本地测试总返回空结果或乱码
90%的情况不是API问题,而是PHP环境或编码处理翻车:
- Windows下用
file_get_contents()读图,若路径含中文,得先iconv('UTF-8', 'GBK', $path),否则Base64结果损坏 - PHP版本低于7.4时,
base64_encode()对二进制数据不友好,建议加bindec(str_replace(['+', '/', '='], ['0', '1', ''], base64_encode(...)))验证是否截断(更稳妥是用fopen+stream_get_contents) - 美团返回的JSON默认是UTF-8,但某些老Apache配置会强制转GB2312,导致
json_decode()返回null,加一句mb_internal_encoding('UTF-8')再解码 - 别在浏览器里直接访问API地址调试——跨域被拦、Header缺失、GET参数长度超限,全得用PHP脚本发请求
真正卡住的地方往往不是算法,而是你传进去的Base64串最后一位是不是 =,以及 access_token 到底有没有在过期前刷新。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











