本文目录导读:

基础版(单文件上传凭证)
<?php
class QiniuToken
{
private $accessKey;
private $secretKey;
private $bucket;
public function __construct($accessKey, $secretKey, $bucket)
{
$this->accessKey = $accessKey;
$this->secretKey = $secretKey;
$this->bucket = $bucket;
}
/**
* 生成上传凭证
* @param string $key 上传的文件名(可选)
* @param int $expires 有效期(秒)
* @param array $policy 其他策略
* @return string
*/
public function generateToken($key = null, $expires = 3600, $policy = [])
{
// 1. 构建上传策略
$deadline = time() + $expires;
$policy = array_merge([
'scope' => $this->bucket . ($key ? ':' . $key : ''),
'deadline' => $deadline
], $policy);
// 2. 对策略进行JSON编码并base64
$encodedPolicy = $this->base64UrlEncode(json_encode($policy));
// 3. 使用SecretKey对编码后的策略进行HMAC-SHA1签名
$sign = hash_hmac('sha1', $encodedPolicy, $this->secretKey, true);
// 4. 将签名进行base64编码
$encodedSign = $this->base64UrlEncode($sign);
// 5. 拼接上传凭证
return $this->accessKey . ':' . $encodedSign . ':' . $encodedPolicy;
}
/**
* Base64 URL安全编码
*/
private function base64UrlEncode($data)
{
return str_replace(['+', '/'], ['-', '_'], base64_encode($data));
}
}
// 使用示例
$qiniu = new QiniuToken(
'YOUR_ACCESS_KEY',
'YOUR_SECRET_KEY',
'YOUR_BUCKET_NAME'
);
// 生成普通上传凭证
$token = $qiniu->generateToken();
echo $token;
?>
完整版(包含多种上传场景)
<?php
class QiniuTokenManager
{
private $accessKey;
private $secretKey;
private $bucket;
public function __construct($accessKey, $secretKey, $bucket)
{
$this->accessKey = $accessKey;
$this->secretKey = $secretKey;
$this->bucket = $bucket;
}
/**
* 普通上传凭证
*/
public function simpleUploadToken($key = null, $expires = 3600)
{
$policy = [
'scope' => $this->bucket . ($key ? ':' . $key : ''),
'deadline' => time() + $expires
];
return $this->createToken($policy);
}
/**
* 覆盖上传凭证(同名覆盖)
*/
public function overwriteUploadToken($key, $expires = 3600)
{
$policy = [
'scope' => $this->bucket . ':' . $key,
'deadline' => time() + $expires,
'insertOnly' => 0 // 允许覆盖
];
return $this->createToken($policy);
}
/**
* 限定上传内容类型
*/
public function mimeLimitToken($mimeTypes, $key = null, $expires = 3600)
{
$policy = [
'scope' => $this->bucket . ($key ? ':' . $key : ''),
'deadline' => time() + $expires,
'mimeLimit' => $mimeTypes // 如: 'image/*;text/plain'
];
return $this->createToken($policy);
}
/**
* 生成带回调的上传凭证
*/
public function callbackToken($callbackUrl, $callbackBody = null, $key = null, $expires = 3600)
{
$policy = [
'scope' => $this->bucket . ($key ? ':' . $key : ''),
'deadline' => time() + $expires,
'callbackUrl' => $callbackUrl,
'callbackBody' => $callbackBody ?: 'key=$(key)&hash=$(etag)&fsize=$(fsize)',
'callbackBodyType' => 'application/x-www-form-urlencoded'
];
return $this->createToken($policy);
}
/**
* 生成带持久化处理的上传凭证
*/
public function persistentToken($persistentOps, $persistentNotifyUrl, $key = null, $expires = 3600)
{
$policy = [
'scope' => $this->bucket . ($key ? ':' . $key : ''),
'deadline' => time() + $expires,
'persistentOps' => $persistentOps, // 如: 'avthumb/mp4/ab/160k'
'persistentNotifyUrl' => $persistentNotifyUrl
];
return $this->createToken($policy);
}
/**
* 创建上传凭证核心方法
*/
private function createToken($policy)
{
// 对策略进行JSON编码并base64
$encodedPolicy = $this->base64UrlEncode(json_encode($policy));
// 使用SecretKey进行HMAC-SHA1签名
$sign = hash_hmac('sha1', $encodedPolicy, $this->secretKey, true);
$encodedSign = $this->base64UrlEncode($sign);
// 拼接上传凭证
return $this->accessKey . ':' . $encodedSign . ':' . $encodedPolicy;
}
/**
* Base64 URL安全编码
*/
private function base64UrlEncode($data)
{
return str_replace(['+', '/'], ['-', '_'], base64_encode($data));
}
/**
* Base64 URL安全解码(用于调试)
*/
public function base64UrlDecode($data)
{
$base64 = str_replace(['-', '_'], ['+', '/'], $data);
return base64_decode($base64);
}
}
// 使用示例
$qiniu = new QiniuTokenManager(
'YOUR_ACCESS_KEY',
'YOUR_SECRET_KEY',
'YOUR_BUCKET_NAME'
);
// 1. 简单上传
$simpleToken = $qiniu->simpleUploadToken('images/avatar.jpg', 3600);
// 2. 覆盖上传
$overwriteToken = $qiniu->overwriteUploadToken('files/document.pdf', 7200);
// 3. 限制MIME类型
$imageToken = $qiniu->mimeLimitToken('image/*', 'images/', 3600);
// 4. 回调上传
$callbackToken = $qiniu->callbackToken(
'https://your-domain.com/callback.php',
'key=$(key)&hash=$(etag)&fsize=$(fsize)',
null,
3600
);
// 5. 持久化处理
$persistentToken = $qiniu->persistentToken(
'avthumb/mp4/ab/160k',
'https://your-domain.com/notify.php',
'videos/video.mp4',
3600
);
?>
使用官方SDK(推荐)
<?php
// 首先通过 Composer 安装七牛云官方 SDK
// composer require qiniu/php-sdk
require 'vendor/autoload.php';
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
class QiniuUpload
{
private $auth;
private $bucket;
public function __construct($accessKey, $secretKey, $bucket)
{
$this->auth = new Auth($accessKey, $secretKey);
$this->bucket = $bucket;
}
/**
* 生成简单上传凭证
*/
public function getSimpleToken()
{
// 生成上传Token
$token = $this->auth->uploadToken($this->bucket);
return $token;
}
/**
* 生成指定文件名上传凭证
*/
public function getTokenWithKey($key)
{
$token = $this->auth->uploadToken($this->bucket, $key);
return $token;
}
/**
* 生成带策略的上传凭证
*/
public function getTokenWithPolicy($policy)
{
// 具体的策略参数可以看官方文档
$token = $this->auth->uploadToken($this->bucket, null, 3600, $policy);
return $token;
}
/**
* 生成带回调的上传凭证
*/
public function getCallbackToken($callbackUrl)
{
$policy = [
'callbackUrl' => $callbackUrl,
'callbackBody' => 'key=$(key)&hash=$(etag)&fsize=$(fsize)',
'callbackBodyType' => 'application/x-www-form-urlencoded'
];
$token = $this->auth->uploadToken($this->bucket, null, 3600, $policy);
return $token;
}
/**
* 生成覆盖上传凭证
*/
public function getOverwriteToken($key)
{
$policy = [
'insertOnly' => 0 // 0表示允许覆盖
];
$token = $this->auth->uploadToken($this->bucket, $key, 3600, $policy);
return $token;
}
}
// 使用示例
$uploader = new QiniuUpload(
'YOUR_ACCESS_KEY',
'YOUR_SECRET_KEY',
'YOUR_BUCKET_NAME'
);
// 生成简单上传凭证
$token = $uploader->getSimpleToken();
// 返回给前端使用
header('Content-Type: application/json');
echo json_encode(['uptoken' => $token]);
?>
前端集成示例
<!-- 前端使用上传凭证 -->
<!DOCTYPE html>
<html>
<head>七牛上传示例</title>
</head>
<body>
<input type="file" id="fileInput">
<button onclick="uploadFile()">上传</button>
<script src="https://unpkg.com/qiniu-js@3.x/dist/qiniu.min.js"></script>
<script>
// 从后端获取上传凭证
async function getUploadToken() {
const response = await fetch('/api/get-upload-token');
const data = await response.json();
return data.uptoken;
}
async function uploadFile() {
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
if (!file) {
alert('请选择文件');
return;
}
// 获取上传凭证
const token = await getUploadToken();
// 配置上传
const config = {
useCdnDomain: true, // 使用CDN加速
region: null // 自动选择上传区域
};
// 上传文件
const putExtra = {
fname: file.name,
params: {},
mimeType: null
};
// 创建上传实例
const observable = qiniu.upload(
file, // 文件
null, // key,不指定则使用七牛生成的key
token, // 上传凭证
config, // 配置
putExtra // 额外参数
);
// 订阅上传进度
const subscription = observable.subscribe({
next: (res) => {
// 上传进度
const percent = Math.floor(res.total.percent);
console.log(`上传进度: ${percent}%`);
// 更新进度条
document.getElementById('progress').style.width = percent + '%';
},
error: (err) => {
console.error('上传失败:', err);
alert('上传失败');
},
complete: (res) => {
console.log('上传成功:', res);
alert('上传成功!');
// 拼接访问URL
const domain = 'YOUR_CDN_DOMAIN'; // 你的CDN域名
const url = `http://${domain}/${res.key}`;
console.log('文件地址:', url);
}
});
}
</script>
</body>
</html>
这个方案提供了不同复杂度的实现,从基础的手动生成到使用官方SDK,以及前端集成示例,生产环境建议使用官方SDK以确保安全性和稳定性。