京东云OSS必须用官方jdc/jdcloud-oss-sdk-php,安装命令composer require jdc/jdcloud-oss-sdk-php;初始化需严格传accessKey、secretKey、bucket和带协议的endpoint(如https://s3.cn-north-1.jdcloud-oss.com)。

京东云 OSS 的 PHP SDK 怎么装和初始化
京东云对象存储(OSS)不兼容 AWS S3 SDK 的默认签名逻辑,直接用 aws/aws-sdk-php 会报 SignatureDoesNotMatch 错误。必须用京东云官方维护的 jdc/jdcloud-oss-sdk-php,它内置了 JD Cloud 特有的 V4 签名算法和 endpoint 路由规则。
安装命令是:
composer require jdc/jdcloud-oss-sdk-php注意不是
jdcloud-oss-sdk 或其他非官方包,那些多数已废弃或签名不完整。
初始化时要严格传入四个参数:accessKey、secretKey、bucket 和 endpoint(不能省略协议,必须是 https://s3.<region>.jdcloud-oss.com</region> 形式,比如 https://s3.cn-north-1.jdcloud-oss.com)。少一个或写错 region 都会导致 InvalidAccessKeyId 或连接超时。
上传文件时怎么避免中文名乱码或 400 错误
京东云 OSS 对 Object Key 中的非 ASCII 字符(如中文、空格、括号)要求严格:必须做 URL 编码,且编码后不能含 +(要用 %20 代替空格),否则返回 InvalidObjectName 或 400 Bad Request。
立即学习“PHP免费学习笔记(深入)”;
推荐做法是统一用 rawurlencode() 处理 key:
$key = rawurlencode('订单_2024-05-20_张三.pdf'); // ✅ 正确
$ossClient->putObject($bucket, $key, $fileContent);
别用 urlencode()(它把空格转成 +),也别跳过编码直接传中文字符串(PHP 会自动把中文转成 UTF-8 字节再发,OSS 解析失败)。
另外,大文件(>100MB)建议用分片上传 initiateMultipartUpload + uploadPart,否则可能因超时或内存溢出失败。
下载文件时如何控制 HTTP 头和防止路径遍历
调用 getObject() 返回的是流资源(StreamInterface),不是原始内容。如果直接 echo 或 file_put_contents,可能因未设置 Content-Type 导致浏览器无法识别类型,或因未校验 key 而被利用做路径遍历(比如 key 是 ../../etc/passwd)。
安全读取建议:
- 先用
basename($key)提取合法文件名,丢弃路径部分 - 用
pathinfo($key, PATHINFO_EXTENSION)白名单校验扩展名(如只允许pdf、jpg) - 设置响应头:
header('Content-Type: ' . $mimeType); header('Content-Disposition: attachment; filename="' . $safeFilename . '"'); - 用
stream_copy_to_stream($response->getBody(), fopen('php://output', 'w'))流式输出,不全量加载进内存
为什么 listObjectsV2 总是返回空或报 SignatureExpired
京东云 OSS 的 listObjectsV2 接口对 max-keys 和 continuation-token 参数敏感,且签名有效期默认仅 15 分钟。如果你生成 presigned URL 后隔了很久才请求,就会触发 SignatureExpired。
常见问题点:
-
max-keys必须是整数字符串(如'100'),传 int 0 或 null 会导致接口静默忽略参数,返回全部或空结果 - 分页继续必须用上一次响应里的
NextContinuationToken,不能自己拼接或 base64 编码任意字符串 - 如果用
prefix过滤,注意它不支持通配符,只做前缀匹配,且同样要rawurlencode()
调试时可先关掉签名验证(仅限本地测试),用 cURL 直接请求 endpoint,看原始错误信息是否含 X-Amz-Date 时间偏移提示——京东云服务时间必须与客户端误差在 15 分钟内。
实际生产中,listObjectsV2 响应体较大,别在循环里反复调用,尽量用 prefix 缩小范围,或改用服务端事件通知 + 本地缓存元数据的方式替代实时列举。



















