why.xingtongworld.com项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

371 lines
12 KiB

<?php
//------------------------
// 七牛上传和token生成
//-------------------------
class Qiniu
{
/**
* 默认上传配置
*/
private $config = [
'mimes' => [], // 允许上传的文件 mime 类型
'max_size' => 0, // 上传的文件大小限制 (0-不做限制)
'exts' => [], // 允许上传的文件后缀
'url' => "http://upload.qiniu.com/", // 上传的地址
'param' => [], // 参数
];
private $error = ''; //上传错误信息
//单例
private static $instance;
public static function instance($config = [])
{
if (self::$instance === null) {
self::$instance = new static($config);
}
return self::$instance;
}
/**
* 构造方法,用于构造上传实例
* @param array $config 配置
*/
public function __construct($config = [])
{
$this->config($config);
}
/**
* 设置
* @param array $config
* @return $this
*/
public function config($config = [])
{
/* 获取配置 */
if(config('upload_validate.size')) $conf['max_size']=config('upload_validate.size');
if(config('upload_validate.ext')) $conf['exts']=config('upload_validate.ext');
$this->config = array_merge($this->config, $conf);
$this->config = array_merge($this->config, $config);
/* 调整配置,把字符串配置参数转换为数组 */
if (!empty($this->config['mimes'])) {
if (is_string($this->config['mimes'])) {
$this->config['mimes'] = explode(',', $this->config['mimes']);
}
$this->config['mimes'] = array_map('strtolower', $this->config['mimes']);
}
if (!empty($this->config['exts'])) {
if (is_string($this->config['mimes'])) {
$this->config['exts'] = explode(',', $this->config['mimes']);
}
$this->config['exts'] = array_map('strtolower', $this->config['mimes']);
}
return $this;
}
private static $instance_manager; //\Qiniu\Storage\UploadManager的单例
/**
* 单例化\Qiniu\Storage\UploadManager
* @return \Qiniu\Storage\UploadManager
*/
public static function manager()
{
if (self::$instance_manager === null) {
self::$instance_manager = new \Qiniu\Storage\UploadManager();
}
return self::$instance_manager;
}
/**
* 生成token
* @param int $expires
* @param null $bucket
* @param null $key
* @param null $policy
* @param bool $strictPolicy
* @return string
*/
public static function token($expires = 3600, $bucket = null, $key = null, $policy = null, $strictPolicy = true)
{
if (empty($bucket)) $bucket = config("storage.bucket");
// 初始化签权对象
$auth = new \Qiniu\Auth(config("storage.accesskey"), config("storage.secretkey"));
$token = $auth->uploadToken($bucket, $key, $expires, $policy, $strictPolicy);
return $token;
}
/**
* 上传单个文件,文件直传
* @param $file_path
* @param string $prefix 文件名前缀,可以模拟目录
* @param null $name
* @param string $ext 后缀
* @param null $token
* @param null $params
* @param string $mime
* @param bool $checkCrc
* @return bool
*/
public function uploadOne($file_path, $prefix = "", $name = null,$ext="", $token = null, $params = null, $mime = 'application/octet-stream', $checkCrc = false)
{
if(empty($name)){
if(empty($ext)) $ext=pathinfo($file_path, PATHINFO_EXTENSION);
}else{
if(empty($ext)) $ext=pathinfo($name, PATHINFO_EXTENSION);
}
//$ext不为空,且未指定$prefix时,根据$ext判断
if($ext && empty($prefix)){
if(in_array(strtolower($ext),array('jpg', 'gif', 'png', 'jpeg','bmp'))){
$prefix='image/';
}elseif(in_array(strtolower($ext),array('mp4', 'avi', 'wmv','rm','rmvb','mkv'))){
$prefix='video/';
}else{
$prefix='file/';
}
if(!empty($name)) $name=$prefix.$name;
}
if (empty($name)) $name = $prefix . base_convert(time() * 1000, 10, 36) . "_" . base_convert(microtime(), 10, 36) . uniqid() .($ext?'.'.$ext:'');
if (empty($token)) $token = self::token();
if (empty($mime)) $mime = 'application/octet-stream';
$this->error = null;
list($ret, $error) = self::manager()->putFile($token, $name, $file_path, $params, $mime, $checkCrc);
if ($error !== null) {
$this->error = $error->message();
return false;
} else {
return $ret;
}
}
/**
* 上传文件,包含$_FILES的上传
* 返回数据包含上传信息部分如果是字符串表示错误信息,如果是数组表示成功
* @param string $prefix
* @param null $params
* @param bool $checkCrc
* @return array|bool
*/
public function upload($prefix = "", $params = null, $checkCrc = false)
{
if (!isset($_FILES) || empty($_FILES)) {
$this->error = '没有上传的文件!';
return false;
}
// 逐个检测并上传文件
$info = []; //文件上传信息数组
foreach ($_FILES as $key => $files) {
foreach ($this->reArrayFiles($files) as $file) {
//文件上传检测
if (!$this->check($file)) {
$info[$key][] = $this->error;
continue;
}
//文件名生成
if (isset($file['name'])) {
$name = $prefix . base_convert(time() * 1000, 10, 36) . "_" . base_convert(microtime(), 10, 36) . uniqid() . "." . pathinfo($file['name'], PATHINFO_EXTENSION);
} else {
$name = $prefix . base_convert(time() * 1000, 10, 36) . "_" . base_convert(microtime(), 10, 36) . uniqid();
}
//文件上传
if ($ret = $this->uploadOne($file['tmp_name'], $prefix, $name,"", null, $params, isset($file['type']) ? $file['type'] : null, $checkCrc)) {
$info[$key][] = array_merge($ret, $file);
} else {
$info[$key][] = $this->error;
}
}
}
//简化返回数据格式
return count($_FILES) == 1 ? end($info) : $info;
}
/**
* 抓取远程url资源
* @param string $url 远程资源url
* @param string $prefix
* @param string $name 保存文件名
* @param string $ext
* @param string $bucket 空间
* @return array
*/
public function uploadcatch($url,$prefix="",$name="",$ext="",$bucket="")
{
if(empty($ext)) $ext=pathinfo($url, PATHINFO_EXTENSION);
//$ext不为空,且未指定$prefix时,根据$ext判断
if($ext && empty($prefix)){
if(in_array(strtolower($ext),array('jpg', 'gif', 'png', 'jpeg','bmp'))){
$prefix='image/';
}elseif(in_array(strtolower($ext),array('mp4', 'avi', 'wmv','rm','rmvb','mkv'))){
$prefix='video/';
}else{
$prefix='file/';
}
}
if (empty($name)) $name = $prefix . base_convert(time() * 1000, 10, 36) . "_" . base_convert(microtime(), 10, 36) . uniqid().($ext?'.'.$ext:'');
if (empty($bucket)) $bucket =config('storage.bucket');
$auth = new \Qiniu\Auth(config("storage.accesskey"), config("storage.secretkey"));
$bucketMgr=new \Qiniu\Storage\BucketManager($auth);
$info=$bucketMgr->fetch($url,$bucket,$name);
return $info;
}
/**
* 列表文件
* @param string
* @param string
* @param string
* @param int
* @return array
*/
public function listfile($prefix='',$bucket='', $marker='', $limit=1000)
{
if (empty($bucket)) $bucket =config('storage.bucket');
$auth = new \Qiniu\Auth(config("storage.accesskey"), config("storage.secretkey"));
$bucketMgr=new \Qiniu\Storage\BucketManager($auth);
list($iterms, $marker, $err) = $bucketMgr->listFiles($bucket, $prefix, $marker, $limit);
if ($err !== null) {
return $err;
}else{
return $iterms;
}
}
/**
* 对文件信息进行处理
* @param $file_post
* @return array
*/
private function reArrayFiles($file_post)
{
$file_ary = [];
if (is_array($file_post['tmp_name'])) {
$file_count = count($file_post['tmp_name']);
$file_keys = array_keys($file_post);
for ($i = 0; $i < $file_count; $i++) {
foreach ($file_keys as $key) {
$file_ary[$i][$key] = $file_post[$key][$i];
}
}
} else {
$file_ary[] = $file_post;
}
return $file_ary;
}
/**
* 获取最后一次上传错误信息
* @return string 错误信息
*/
public function getError()
{
return $this->error;
}
/**
* 检查上传的文件
* @param array $file 文件信息
* @return boolean
*/
private function check($file)
{
if (!isset($file['tmp_name']) || !file_exists($file['tmp_name'])) {
$this->error = '上传的文件不存在';
return false;
}
// 文件上传失败,捕获错误代码
if (isset($file['error']) && $file['error']) {
$this->error($file['error']);
return false;
}
// 检查文件大小
if (isset($file['size']) && !$this->checkSize($file['size'])) {
$this->error = '上传文件大小不符!';
return false;
}
// 检查文件Mime类型
if (isset($file['type']) && $file['type']) {
if (!$this->checkMime($file['type'])) {
$this->error = '上传文件MIME类型不允许!';
return false;
}
}
// 检查文件后缀
if (isset($file['ext']) && !$this->checkExt($file['ext'])) {
$this->error = '上传文件后缀不允许';
return false;
}
// 通过检测
return true;
}
/**
* 获取错误代码信息
* @param string $errorNo 错误号
*/
private function error($errorNo)
{
switch ($errorNo) {
case 1:
$this->error = '上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值!';
break;
case 2:
$this->error = '上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值!';
break;
case 3:
$this->error = '文件只有部分被上传!';
break;
case 4:
$this->error = '没有文件被上传!';
break;
case 6:
$this->error = '找不到临时文件夹!';
break;
case 7:
$this->error = '文件写入失败!';
break;
default:
$this->error = '未知上传错误!';
}
}
/**
* 检查文件大小是否合法
* @param integer $size 数据
* @return boolean
*/
private function checkSize($size)
{
return !($size > $this->config['max_size']) || (0 == $this->config['max_size']);
}
/**
* 检查上传的文件MIME类型是否合法
* @param string $mime 数据
* @return boolean
*/
private function checkMime($mime)
{
return empty($this->config['mimes']) ? true : in_array(strtolower($mime), $this->config['mimes']);
}
/**
* 检查上传的文件后缀是否合法
* @param string $ext 后缀
* @return boolean
*/
private function checkExt($ext)
{
return empty($this->config['exts']) ? true : in_array(strtolower($ext), $this->config['exts']);
}
}