Repository navigation
Expand file tree
/
Copy pathImage.php
More file actions
252 lines (208 loc) · 7.7 KB
/
Copy pathImage.php
File metadata and controls
252 lines (208 loc) · 7.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
<?php
/**
* Created by PhpStorm.
* User: haier
* Date: 2018-2-24
* Time: 21:07
*
* MIT License
*
* Copyright (c) 2018 ParrySMS
*
* 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 Image;
use \Exception;
class Image
{
private $inputFile;
private $fileName;
private $fileTmpname;
/**
* @return mixed
*/
public function getFileTmpname()
{
return $this->fileTmpname;
}
/**
* @return mixed
*/
public function getFileName()
{
return $this->fileName;
}
/**
* Image constructor.
*/
public function __construct($inputFile)
{
$this->inputFile = $inputFile;
}
/** 基本的检查(空与异常),接着进行自定义的图片检查
* @throws Exception
*/
public function check()
{
//清除文件缓存
clearstatcache();
//文件空检查
if (empty($_FILES)) {
throw new Exception('未检查到图片文件,请检查是否成功上传', 500);
}
//获得文件数据
$image = $_FILES[$this->inputFile];
//文件数据异常
if ($image['error'] != 0) {
$error = $image['error'];
throw new Exception($error, 500);
}
//进入自定义图片检查
$this->imageCheck($image);
}
/** 自定义图片检查
* @param $image
* @throws Exception
*/
private function imageCheck($image)
{
//文件不是通过HTTP post 上传的
$filetmpname = $image['tmp_name'];
if (!is_uploaded_file($filetmpname)) {
throw new Exception('文件非法上传', 500);
}
//上传文件过大 报错
$size = $image['size'];
if ($size > UPLOAD_FILE_MAX_B) {
$sizeM = UPLOAD_FILE_MAX_B/1024/1024;
throw new Exception('文件大小不得超过' . $sizeM . 'M。 当前文件大小为 $size', 500);
}
//上传文件的文件类型检查
//后缀名检查
$type = $image['type'];
$typeRegion = eval(ALLOW_FILE_TYPES);
if (!array_key_exists($type, $typeRegion)) {
throw new Exception("不支持 $type 类型的文件", 500);
}
//文件内容检查
if (!is_array(getimagesize($filetmpname))) {
//文件为图片后缀 但无法识别不出图片 可能是冒充图片的文件
throw new Exception("无法识别该图片文件", 200);
}
list($width, $height, $attrNum) = getimagesize($filetmpname);
/** 注意:这段注释非常重要 请不要删除
* 文件类型检查。
* 当限制的文件类型都出现再下面的标记中时,可开启该检查。
* 索引 2 attrNum 是图像类型的标记:
* 1 = GIF,2 = JPG,3 = PNG,4 = SWF,
* 5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),
* 9 = JPC,10 = JP2,11 = JPX,12 = JB2,
* 13 = SWC,14 = IFF,15 = WBMP,16 = XBM
*/
//只允许的类型标记 2 = JPG,3 = PNG
$attrArray = [2, 3];
//支持格式较少 若允许的文件类型并未全部出现在类型标记中 则暂不启用 注释掉attrTypeCheck函数所在行即可
$this->attrTypeCheck($attrNum,$attrArray);
/*
* 自定义的图片比例要求 默认关闭
* 如果页面有固定的图片裁切器
* 例如:用户上传图片后,再网页上会进行一个1:1矩形的裁切操作后,才能上传图片(常见于头像上传)
* 则下面的检查能够保证图片的比例
*/
//宽高比例为 1:1
//$this->RatioCheck($width,$height,1,1);
/**
* 文件改名以具体情况具体分析
* 此处为避免图片重名问题
* 取文件名改名为 时间参数.后缀名
*/
// 获取略去后缀名的文件名:
// $filename = substr($filename, 0, strrpos($filename, '.'));
// 添加时间与后缀名的改名
$filename = date('Ymd_His') . $typeRegion[$image['type']];
//保存到参数中
$this->fileTmpname = $filetmpname;
$this->fileName = $filename;
}
/** 图片类型标记检查
* @param $attrNum
* @param $attrArray
* @throws Exception
*/
private function attrTypeCheck($attrNum,$attrArray){
//将图片类型标记存入数组,键表示attrNum,值表示类型
$attr =['unknown',
'GIF','JPG','PNG', 'SWF',
'PSD','BMP','TIFF(intel byte order)','TIFF(motorola byte order)',
'JPC','JP2','JPX','JB2',
'SWC','IFF','WBMP','XBM'
];
if (!in_array($attrNum, $attrArray)) {
//不在类型标记的未知类型
if($attrNum<0||$attrNum>16){
$attrNum = 0;
}
throw new Exception("不支持的文件类型:$attr[$attrNum]",500);
}
}
/** 图片比例检查
* @param $width
* @param $height
* @param $ratio
* @throws Exception
*/
public function RatioCheck($width,$height,$widthNum,$heightNum)
{
if($width/$height - $widthNum/$heightNum > 0.001){
//不符合比例
throw new Exception("不符合图片比例要求,要求宽高比例为 $widthNum :$heightNum",500);
}
}
/** 移动图片并保存
* @param $dir
* @param null $tmpname
* @param null $filename
* @throws Exception
*/
public function move($dir, $tmpname = null , $filename = null )
{
//默认取本类的文件参数
$tmpname = empty($tmpname)?$this->fileTmpname:$tmpname;
$filename = empty($filename)?$this->fileName:$filename;
//中文转码
$filename=iconv("utf-8","gbk",$filename);
//无目录则创建目录
if (!is_dir('./'.$dir)) {
if (!mkdir('./'.$dir, 0777, true)) {
throw new Exception('图片路径错误', 500);
}
}
//中文转码
$dirFilename =iconv("utf-8","gbk",$dir.$filename);
if(!move_uploaded_file($tmpname, './'.$dirFilename)){
throw new Exception('图片转移失败 ' , 500);
}
if (!is_file($dirFilename)) {
throw new Exception('图片保存失败 ' , 500);
}
// 获取文件类型
// $filetype = mime_content_type($filename);
}
}