AWS Elastic Beanstalk上CodeIgniter S3上传:图片成功但音频上传报fopen空文件名错误
问题根因说明
你遇到的Unable to open using mode r: fopen(): Filename cannot be empty报错,本质是AWS S3 SDK在执行上传时,收到了空的SourceFile参数,SDK内部尝试对该路径执行fopen读操作时,因为路径为空直接触发警告。
你两段S3上传的代码结构完全一致,缩略图上传正常、音频上传报错,说明问题根本不在S3上传逻辑本身,核心原因就是$_FILES['audio']['tmp_name']取到了空值,传给了S3的SourceFile参数。
逐步排查思路
- 先做最直接的字段值校验
在S3上传代码调用前,先打印$_FILES全量值,不要直接读tmp_name:
重点看两个值:一是// 放在upload_audio函数的最开头 var_dump($_FILES['audio']);exit;tmp_name是不是空字符串,二是error字段的错误码,大部分情况下这里会直接看到非0的错误码。 - 排查PHP全局上传配置(AWS Elastic Beanstalk环境默认配置最容易踩坑)
EB默认的php.ini配置通常upload_max_filesize=2M、post_max_size=8M,这个值远低于常见音频文件的体积:- 如果你上传的音频大小超过
upload_max_filesize,PHP会直接将该上传字段的tmp_name置空,同时返回UPLOAD_ERR_INI_SIZE(错误码1),因为你代码里没有对上传错误做拦截,直接取tmp_name就拿到了空值 - 如果缩略图+音频的总提交体积超过
post_max_size,PHP会直接清空整个$_POST和$_FILES数组,你之所以看到缩略图上传正常,很可能是缩略图本身体积很小,单独提交时远低于阈值,加上音频后总大小超过限制,但因为代码顺序是先传图、后传音频,图已经走完上传逻辑没报错,等到读音频的字段时才发现值是空的 - 检查
max_file_uploads配置值,确认同时上传2个文件(图+音频)没有超过上限,避免被PHP直接拦截
- 如果你上传的音频大小超过
- 排查前端表单的上传配置
- 确认上传表单的
enctype设置为multipart/form-data,且音频对应的input标签name属性和后端读取的audio完全一致,没有拼写错误 - 检查前端上传组件的大小限制,很多前端会默认拦截大于1M的文件,导致音频文件根本没有提交到后端,
$_FILES里自然拿不到对应字段
- 确认上传表单的
- 排查CodeIgniter框架层的拦截逻辑
- 很多CI项目会在全局钩子、控制器构造函数里,对上传文件做类型、大小的前置校验,如果校验不通过,会主动清空对应的上传字段值。可以临时注释掉框架的上传钩子,单独测试音频上传逻辑,排除框架拦截的可能
- 注意你触发代码里的注释把音频上传写成了视频上传,说明这段逻辑大概率是从之前的视频上传模块改过来的,要确认有没有漏改对应的上传字段名、校验规则,导致音频字段被框架层过滤掉
快速验证方法
临时把一个1M以内的小音频文件上传测试,如果小文件能正常传成功,就100%是PHP上传大小配置的问题,只需要在EB环境调整PHP的上传大小阈值即可解决。
内容的提问来源于stack exchange,提问作者alsongsule
相关产品推荐
相关产品推荐

