官方文档 - 【七牛云 php-SDK】
前期处理
php composer.phar require qiniu/php-sdk
实现方法
根据项目需求,在此整理几个核心的操作方法
1. 抓取 web上的图片,上传七牛云服务器
$save_path = 'uploads/'.date('Ymd',time()).'/'.microtime(true).'.png';
/**
* 抓取 web上的图片,上传七牛云服务器
* @param $imgUrl web 图片地址
* @param string $saveImgPath 保存到七牛云的地址
* @return string
*/
public function uploadWebImgToQiniu($imgUrl,$saveImgPath = '')
{
#读取网上图片内容
$imageData = self::getSslPage($imgUrl);
$auth = new Auth($this->accessKey, $this->secretKey);
$token = $auth->uploadToken($this->bucket);
$key = $saveImgPath;
$up = new UploadManager();
$mime = 'image/jpeg';
list($rest, $err) = $up->put($token, $key, $imageData, null, $mime);
if ($err) {
return '';
} else {
$host = config('cdn.Host');
return $host.'/'.$rest['key'];
}
}
/**
* 抓取网上图片 web image
* @param $url
* @return bool|string
*/
public function getSslPage($url) {
if(!empty($slika)){
file_put_contents('vest1.webp', $slika);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
2. 将服务器上的文件 上传到七牛云服务器
/**
* 将服务器上的文件 上传到七牛云服务器
* @param string $file_name
* @param string $file_from_path
* @param string $file_to_path
* @param string $ext_name
* @return mixed|string
* @throws Exception
*/
private function uploadServerFileToQiniu($file_name = '',$file_from_path = '',$file_to_path = '',$ext_name = 'txt')
{
$auth = $this->getQiniuAuth();
// 生成上传Token
$token = $auth->uploadToken($this->bucket);
// 构建 UploadManager 对象
$uploadMgr = new UploadManager();
// 上传文件到七牛
if (empty($file_name)){
$file_name = md5(uniqid(microtime(true),true));
}
if (empty($file_to_path)){}
$key = $file_to_path.'/'.$file_name.'.'.$ext_name;
list($ret, $err) = $uploadMgr->putFile($token, $key, $file_from_path);
if ($err !== null) {
//上传失败
return '';
} else {
//删除临时服务器 文件
unlink($file_from_path);
return $ret['key'];
}
}
3. 删除七牛云上的文件
/**
* 删除文件
* @param string $file_key
* @return int 1:删除成功 ,0:删除失败
*/
public function deleteQiniuFile($file_key = ''){
$auth = new Auth($this->accessKey, $this->secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
$err = $bucketManager->delete($this->bucket, $file_key);
if ($err) {
return 0;
}else{
return 1;
}
}
4. 将七牛云中的多个文件,压缩包存储
.rar
文件,方便运营人员一次性下载 /**
* 生成word稿件压缩包
* @param string $task_idstr
* @param int $index
* @param array $picture_arr
* @return array
*/
public function createWordFileRar($task_idstr = '',$index = 1,$picture_arr = []){
$zipKey = "task_words/{$task_idstr}_{$index}.zip";
//组装七牛云请求参数
$fops = 'mkzip/2';
//每十个文件,作为一个压缩包
foreach ($picture_arr as $key_ => $val) {
//添加图片重命名
$fops .= '/url/'.\Qiniu\base64_urlSafeEncode($val);
}
$key = $this->fileKey; //mode = 2时,仅仅为符合pfop操作的接口规格而存在,并没有实际的意义,但需要是操作空间中存在的资源的 key
$fops .= '|saveas/' . \Qiniu\base64_urlSafeEncode("$this->bucket:$zipKey");
$result = $this->picMkzip($key, $fops);
$result['qiniu_url'] = $zipKey;
return $result;
}
附录
根据业务开发过程中遇到的问题,在此做下梳理,方便大家避雷
问题1 . 七牛云文件上传延时
场景描述:
我指定要存储的压缩文件名为 'hello-1122337.rar';
当数据发生变动后,我先删除这个文件,然后再重新生成一份,如此一来压缩文件的名称就没必要变动了
但是我发现,执行逻辑后的压缩文件并不是最新的!
另一种情况,我要生成的压缩文件较大(500M左右)
测试生成时间要6~10秒
我想每两秒去检查下是否生成完毕
结果参考使用了网上很多的 判断web文件是否存在的方法
即便实际情况6秒生成(七牛云后台都能看到文件了,甚至可以下载),但是检测方法直到20秒后才判断生成了
这显然不能满足我的业务需求
问题分析:
- 七牛云服务器对同名文件有缓存,实际上并不会真实删除,当检测到文件同名时对已删除文件有复原的处理(猜测)
- 或者网上的判断文件是否存在的方法存在bug (排除,毕竟不可能都错吧)
- 本地设计的 while 循环判断时,同一个方法的调用存在缓存情况 (极有可能)
解决方案
回想以前的开发经验,在读取 html 页面时,后面添加个随机字符串就会避免缓存
所以,在检查文件是否存在时,
每次对文件路径加一个随机数,避免与前面的链接相同
发现,顺利的解决的判断需求
代码截图如下:
/**
* php使用 curl 判断404
* @param string $url
* @return bool
*/
function check_url($url = ''){
stream_context_set_default(
array(
'http' => array(
'timeout' => 5,
)
)
);
$header = get_headers($url,1);
if(strpos($header[0],'200')){
return true;
}
if(strpos($header[0],'404')){
return false;
}
if (strpos($header[0],'301') || strpos($header[0],'302')) {
if(is_array($header['Location'])) {
$redirectUrl = $header['Location'][count($header['Location'])-1];
}else{
$redirectUrl = $header['Location'];
}
return check_url($redirectUrl);
}
}