使用Alamofire 5直传视频至PHP服务器失败的问题排查
问题场景
- 需求:将iOS App本地存储的mp4格式视频文件,上传至PHP搭建的服务器指定文件夹内
- 技术选型:使用Alamofire实现上传能力,因官方说明multipart form data方式传输大文件存在速度慢、内存占用高的缺陷,选择官方推荐的文件直传方案,客户端核心代码如下:
AF.upload(videoURL, to: "[服务端目标地址]")
其中videoURL为设备本地mp4视频的路径。
已尝试的失败方案
配置服务端目标URL时,三种配置方式均未成功上传:
- 直接填写服务器目标文件夹的访问路径:接口返回浏览器访问该路径时的网页HTML源码,视频未存入服务器
- 填写目标文件夹下不存在的新文件路径:服务端返回404错误,提示「The requested URL was not found on this server.」
- 填写目标文件夹下已存在的mp4文件路径:期望上传后自动覆盖原文件,但服务端返回长度极长的字符串(会导致Xcode严重卡顿),判断为原有视频的原始内容,原文件未被新上传视频替换。
问题原因与解决方案
客户端的直传写法完全符合Alamofire官方规范,核心问题是缺少对应的PHP服务端接收处理逻辑,且URL配置逻辑存在错误。
核心原因说明
AF.upload(本地文件URL, to: 目标地址)的直传逻辑,是将本地文件的内容直接作为HTTP请求的请求体,发送到目标URL对应的服务端处理程序。Web服务器本身不会自动将请求体中的内容写入到服务器对应路径的文件中,三种失败尝试的具体原因:
- 填文件夹路径时,Web服务器收到请求后默认返回该路径的目录索引页(即你看到的HTML源码),完全没有处理上传的文件内容
- 填不存在的文件路径时,服务器找不到对应的处理资源,直接返回404错误
- 填已存在的mp4文件路径时,服务器默认静态文件处理逻辑会直接返回该文件的原始内容(即导致Xcode卡顿的超长字符串),不会执行文件覆盖写入操作。
正确实现步骤
- 编写PHP接收接口
在Web服务可访问的路径下新建专门的上传处理PHP文件(例如命名为handle_video_upload.php),通过读取HTTP原始请求流的方式接收文件,流写入方式内存占用低,适配大视频上传场景,参考代码如下:
注意:生产环境使用时需要补充权限校验、文件格式校验、文件大小限制逻辑,避免恶意文件上传风险。<?php // 配置视频存储的目标文件夹,需提前给该文件夹设置Web进程的写入权限 $storageDir = __DIR__ . '/video_storage/'; // 生成唯一存储文件名,避免非预期的文件覆盖 $saveName = uniqid(mt_rand(), true) . '.mp4'; $savePath = $storageDir . $saveName; // 打开原始请求输入流(对应Alamofire直传的视频内容) $inputStream = fopen('php://input', 'r'); $outputStream = fopen($savePath, 'w'); if ($inputStream && $outputStream) { // 流拷贝写入,大文件上传不会占满服务器内存 stream_copy_to_stream($inputStream, $outputStream); fclose($inputStream); fclose($outputStream); // 返回上传成功响应 header('Content-Type: application/json'); echo json_encode([ 'code' => 0, 'msg' => 'upload success', 'file_name' => $saveName ]); } else { http_response_code(500); header('Content-Type: application/json'); echo json_encode([ 'code' => 500, 'msg' => 'server write error, please check directory permission' ]); } ?> - 调整客户端请求地址
客户端AF.upload的目标URL填写上述PHP接口的可访问地址即可,例如https://你的域名/handle_video_upload.php,不需要拼接文件夹路径或具体mp4文件路径。如果需要传递自定义参数(比如用户ID、自定义文件名),可以通过请求头携带,PHP端从请求头中读取对应参数即可。 - 配置服务器权限
提前给服务器上的视频存储文件夹,分配Web运行进程(常见为www-data、nginx、apache用户)的写入权限,否则PHP会写入文件失败。
内容的提问来源于stack exchange,提问作者Emil Ryd
相关产品推荐
相关产品推荐

