如何通过ThinkPHP将上传文件直接存储至七牛云,实现SDK集成配置?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1127个文字,预计阅读时间需要5分钟。
在ThinkPHP框架中,无法直接将上传的文件保存在本地临时目录。通常情况下,上传的文件会先保存在PHP的临时目录中,这个目录可以通过配置`upload_tmp_dir`来指定。
所谓的直接上传,实际上是指将上传的文件直接通过七牛云等第三方云存储SDK上传到云服务器,而不是保存在本地临时目录。以下是简化的步骤:
- 必须确保服务器能访问七牛上传域名(如
up-z2.qiniup.com),部分内网环境需配置代理或白名单 - 不要在
think\facade\Filesystem或think\File的storeAs()流程里硬塞七牛逻辑,容易和 ThinkPHP 文件驱动冲突 - SDK 上传前务必检查
$_FILES['file']['error'] === UPLOAD_ERR_OK,否则可能传空文件或报file_get_contents(): Read of 8192 bytes failed
七牛 PHP SDK(v7.10+)在 ThinkPHP 中的最小可用配置
新版 SDK 不依赖 curl 扩展,但要求 fileinfo 开启(用于自动识别 MIME 类型)。推荐用 Composer 安装到项目根目录:composer require qiniu/php-sdk,然后在上传逻辑所在控制器里手动引入:
use Qiniu\Auth; use Qiniu\Storage\UploadManager;
配置项只需三样:accessKey、secretKey、bucket。域名(domain)可选,但生成公开 URL 时必须填;不填会导致 Qiniu\Storage\BucketManager::publicLink() 返回空字符串。
-
accessKey和secretKey必须从七牛控制台「密钥管理」获取,不能用账号密码 -
bucket名称区分大小写,且必须和空间绑定的区域一致(如华东区 bucket 对应up-z1.qiniup.com) - 不要把密钥写死在控制器里,应放在
config/qiniu.php配置文件中,用config('qiniu.access_key')读取
上传临时文件到七牛的典型代码写法(避开常见超时/400错误)
核心是用 UploadManager::putFile(),不是 put()(后者只接受资源句柄或字符串内容,对大文件易内存溢出)。
立即学习“PHP免费学习笔记(深入)”;
$auth = new Auth(config('qiniu.access_key'), config('qiniu.secret_key')); $uploadMgr = new UploadManager(); $token = $auth->uploadToken(config('qiniu.bucket')); $key = 'uploads/' . date('Ymd') . '/' . uniqid() . '_' . $_FILES['file']['name']; list($ret, $err) = $uploadMgr->putFile($token, $key, $_FILES['file']['tmp_name']);
-
$key中不要含中文或特殊符号(如空格、?、#),否则上传成功但 URL 访问 404 - 如果
$err是RequestError: status code 400,大概率是$token过期(默认 3600 秒)或$key长度超 256 字节 - 上传大文件(>10MB)建议加
'chunkSize' => 4 * 1024 * 1024到UploadManager构造参数,避免单次请求超时
上传成功后怎么生成可访问的外链?
七牛默认返回的 $ret['key'] 只是存储路径,不是 URL。必须拼接绑定的加速域名,且注意末尾是否带 /:
$domain = rtrim(config('qiniu.domain'), '/'); // 如 'https://cdn.example.com' $url = $domain . '/' . urlencode($ret['key']);
如果空间开启了私有链接,还需调用 Auth::privateDownloadUrl() 并传入过期时间,否则直接拼域名会返回 403。
- 别用
urlencode($ret['key'])处理整个路径再拼接——七牛官方 SDK 已处理,手动 encode 可能导致重复编码(如%2F变成%252F) - 测试时用浏览器直接访问生成的 URL,若返回
NoSuchKey,说明$key和实际上传的 key 不一致(常见于未正确处理中文文件名) - ThinkPHP 的
response()->header()不影响七牛上传流程,但若你在上传后立即返回 JSON,记得unlink($_FILES['file']['tmp_name'])清理临时文件,否则磁盘悄悄占满
七牛上传本身不难,真正卡住人的往往是 token 权限、key 命名规则、域名拼接方式这三点。特别是开发环境用的测试域名,上线后忘记切正式域名,或者没开 HTTPS 强制跳转,前端拿到 URL 也打不开。
本文共计1127个文字,预计阅读时间需要5分钟。
在ThinkPHP框架中,无法直接将上传的文件保存在本地临时目录。通常情况下,上传的文件会先保存在PHP的临时目录中,这个目录可以通过配置`upload_tmp_dir`来指定。
所谓的直接上传,实际上是指将上传的文件直接通过七牛云等第三方云存储SDK上传到云服务器,而不是保存在本地临时目录。以下是简化的步骤:
- 必须确保服务器能访问七牛上传域名(如
up-z2.qiniup.com),部分内网环境需配置代理或白名单 - 不要在
think\facade\Filesystem或think\File的storeAs()流程里硬塞七牛逻辑,容易和 ThinkPHP 文件驱动冲突 - SDK 上传前务必检查
$_FILES['file']['error'] === UPLOAD_ERR_OK,否则可能传空文件或报file_get_contents(): Read of 8192 bytes failed
七牛 PHP SDK(v7.10+)在 ThinkPHP 中的最小可用配置
新版 SDK 不依赖 curl 扩展,但要求 fileinfo 开启(用于自动识别 MIME 类型)。推荐用 Composer 安装到项目根目录:composer require qiniu/php-sdk,然后在上传逻辑所在控制器里手动引入:
use Qiniu\Auth; use Qiniu\Storage\UploadManager;
配置项只需三样:accessKey、secretKey、bucket。域名(domain)可选,但生成公开 URL 时必须填;不填会导致 Qiniu\Storage\BucketManager::publicLink() 返回空字符串。
-
accessKey和secretKey必须从七牛控制台「密钥管理」获取,不能用账号密码 -
bucket名称区分大小写,且必须和空间绑定的区域一致(如华东区 bucket 对应up-z1.qiniup.com) - 不要把密钥写死在控制器里,应放在
config/qiniu.php配置文件中,用config('qiniu.access_key')读取
上传临时文件到七牛的典型代码写法(避开常见超时/400错误)
核心是用 UploadManager::putFile(),不是 put()(后者只接受资源句柄或字符串内容,对大文件易内存溢出)。
立即学习“PHP免费学习笔记(深入)”;
$auth = new Auth(config('qiniu.access_key'), config('qiniu.secret_key')); $uploadMgr = new UploadManager(); $token = $auth->uploadToken(config('qiniu.bucket')); $key = 'uploads/' . date('Ymd') . '/' . uniqid() . '_' . $_FILES['file']['name']; list($ret, $err) = $uploadMgr->putFile($token, $key, $_FILES['file']['tmp_name']);
-
$key中不要含中文或特殊符号(如空格、?、#),否则上传成功但 URL 访问 404 - 如果
$err是RequestError: status code 400,大概率是$token过期(默认 3600 秒)或$key长度超 256 字节 - 上传大文件(>10MB)建议加
'chunkSize' => 4 * 1024 * 1024到UploadManager构造参数,避免单次请求超时
上传成功后怎么生成可访问的外链?
七牛默认返回的 $ret['key'] 只是存储路径,不是 URL。必须拼接绑定的加速域名,且注意末尾是否带 /:
$domain = rtrim(config('qiniu.domain'), '/'); // 如 'https://cdn.example.com' $url = $domain . '/' . urlencode($ret['key']);
如果空间开启了私有链接,还需调用 Auth::privateDownloadUrl() 并传入过期时间,否则直接拼域名会返回 403。
- 别用
urlencode($ret['key'])处理整个路径再拼接——七牛官方 SDK 已处理,手动 encode 可能导致重复编码(如%2F变成%252F) - 测试时用浏览器直接访问生成的 URL,若返回
NoSuchKey,说明$key和实际上传的 key 不一致(常见于未正确处理中文文件名) - ThinkPHP 的
response()->header()不影响七牛上传流程,但若你在上传后立即返回 JSON,记得unlink($_FILES['file']['tmp_name'])清理临时文件,否则磁盘悄悄占满
七牛上传本身不难,真正卡住人的往往是 token 权限、key 命名规则、域名拼接方式这三点。特别是开发环境用的测试域名,上线后忘记切正式域名,或者没开 HTTPS 强制跳转,前端拿到 URL 也打不开。

