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.
 
 
 

219 lines
6.5 KiB

<?php
/*
* The MIT License
*
* Copyright 2019 Blobt.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
namespace iron\actions;
use yii\base\Action;
use Yii;
use yii\base\Exception;
use yii\web\NotFoundHttpException;
use yii\web\Response;
use yii\web\ServerErrorHttpException;
use yii\web\UploadedFile;
/***
* @author iron <weiriron@gmail.com>
* @created Sep 11, 2019
*/
class UploadAction extends Action
{
/**
* 常量:表单数据类型
*/
const DATA_TYPE_FORM = 1;
/**
* 常量: 二进制数据类型
*/
const DATA_TYPE_BINARY = 2;
public $keyName = 'file';
/**
* @var function
*
*/
public $saveInDatabase;
/**
* @var integer 限制的最大尺寸
*/
public $maxSize;
/**
* @var array 允许的文件类型(扩展名)
*/
public $allowType;
/**
* @var string 文件保存路径
* template /image/jpg/
*/
public $path;
/**
* @var string 数据类型
*/
public $dataType;
/**
* @var bool 是否随机文件名(默认为随机,推荐为随机避免中文文件名导致的问题)
*/
public $randName = true;
/**
* @var integer 默认单次最大上传数量(1-20)
*/
public $maxCount;
public function init()
{
if ($this->maxSize === null) {
$this->maxSize = 2048;//默认最大尺寸为2M
}
if ($this->allowType === null) {
$this->allowType = ['*'];//默认允许任何图片类型
}
if ($this->maxCount === null) {
$this->maxCount = 5;//默认单次最大上传数量为5
}
if ($this->dataType === null) {
$this->dataType = self::DATA_TYPE_FORM;//默认上传数据类型为表单数据
}
}
public function run()
{
Yii::$app->response->format = Response::FORMAT_JSON;
$data = [];
try {
if ($this->dataType == self::DATA_TYPE_FORM) {
$file = UploadedFile::getInstanceByName($this->keyName);
$this->checkType($file->extension);
$this->checkSize($file->size);
$savePath = $this->getSavePath();
$fileName = $this->getFileName($file->baseName);
$filePath = "$savePath$fileName.{$file->extension}";
$file->saveAs($filePath);
// $data[] = ["uploads/$this->path/$fileName.{$file->extension}"];
} else {
//TODO 非表单类型的文件上传
throw new NotFoundHttpException('未实现');
// $bin = Yii::$app->request->post('file');
// $head = substr($bin, 0, 2);
// $fileExtension = $this->getExtension($head);
// $fileName = $this->getFileName();
// $savePath = $this->getSavePath();
// $filePath = "$savePath/$fileName.{$fileExtension}";
// file_put_contents($filePath, $bin);
}
return ['status' => true, 'path' => "uploads/$this->path$fileName.{$file->extension}", 'alias' => $fileName . '.' . $file->extension];
} catch (\Error $e) {
throw new ServerErrorHttpException($e->getMessage());
// return ['status' => false, 'info' => $e->getMessage()];
}
}
protected function saveData()
{
}
/**
* 检查文件类型是否允许上传
* @param $extension 文件扩展名
* @return bool
* @throws Exception
*/
protected function checkType($extension)
{
if (in_array('*', $this->allowType)) {
return true;
}
if (!in_array($extension, $this->allowType)) {
throw new Exception("类型【{$extension}】不被允许,请在配置项中添加该类型");
}
}
/**
* 检查文件尺寸是否超过最大允许上传尺寸
* @param $size 文件尺寸
* @throws Exception
*/
protected function checkSize($size)
{
if ($size / 1024 > $this->maxSize) {
throw new Exception("文件大于允许的最大尺寸【{$this->maxSize}】,请修改配置或压缩文件");
}
}
/**
* 根据二进制流头大小判断文件类型
* @param $head
* @return mixed
* @throws NotFoundHttpException
*/
protected function getExtension($head)
{
$fileTypes = array(
7790 => 'exe',
7784 => 'midi',
8297 => 'rar',
255216 => 'jpg',
7173 => 'gif',
6677 => 'bmp',
13780 => 'png'
);
if (isset($fileTypes[$head])) {
return $fileTypes[$head];
} else {
throw new NotFoundHttpException('未找到该文件类型');
}
}
/**
* 获取文件保存路径并创建文件夹
* @return string 文件保存的完成路径
*/
protected function getSavePath()
{
$dirs = explode('/', $this->path);
$savePath = Yii::getAlias('@app') . '/web/uploads';
if (!is_dir($savePath)) {
mkdir($savePath, 0755);
}
foreach ($dirs as $dir) {
$savePath .= "/$dir";
if (!is_dir($savePath)) {
mkdir($savePath, 0755);
}
}
return $savePath;
}
/**
* 利用时间戳加随机数构建新文件名
* @param $originName 源文件名
* @return string
*/
//TODO 利用原文件名生成新文件名
protected function getFileName($originName = '')
{
return time() . rand(0, 9999);
}
}