verot / class.upload.php
这个PHP类可以非常容易地上传文件和操作图像。
Requires
- php: >=5.3
README
主页 : http://www.verot.net/php_class_upload.htm
演示 : http://www.verot.net/php_class_upload_samples.htm
捐赠: http://www.verot.net/php_class_upload_donate.htm
商业用途: http://www.verot.net/php_class_upload_license.htm
它做什么?
该类为您管理文件上传。简而言之,它管理上传的文件,并允许您对文件进行任何操作,尤其是如果它是图像,并且可以重复任意次数。
它是将文件上传快速集成到您的网站中的理想类。如果文件是图像,您可以以多种方式转换、调整大小、裁剪它。您还可以应用过滤器、添加边框、文字、水印等... 这对于实例中的画廊脚本等都是所需的全部。支持的格式是PNG、JPG、GIF、WEBP和BMP。
您还可以使用该类来处理本地文件,这对于使用图像处理功能非常有用。该类还支持Flash上传器和XMLHttpRequest。
该类与PHP 5.3+、PHP 7和PHP 8(使用版本1.x以支持PHP 4)兼容,并且其错误消息可以任意本地化。
通过composer安装
编辑您的composer.json文件,包含以下内容
{
"require": {
"verot/class.upload.php": "*"
}
}
或者直接安装
composer require verot/class.upload.php
演示和示例
查看test/
目录,您可以在浏览器中加载它。您可以测试类及其不同的实例化方式,查看一些代码示例,并运行一些测试。
如何使用它?
创建一个简单的HTML文件,包含一个表单,例如
<form enctype="multipart/form-data" method="post" action="upload.php"> <input type="file" size="32" name="image_field" value=""> <input type="submit" name="Submit" value="upload"> </form>
创建一个名为upload.php的文件(其中首先已加载类)
$handle = new \Verot\Upload\Upload($_FILES['image_field']); if ($handle->uploaded) { $handle->file_new_name_body = 'image_resized'; $handle->image_resize = true; $handle->image_x = 100; $handle->image_ratio_y = true; $handle->process('/home/user/files/'); if ($handle->processed) { echo 'image resized'; $handle->clean(); } else { echo 'error : ' . $handle->error; } }
它是如何工作的?
您使用$_FILES['my_field']
数组实例化类,其中my_field是您的上传表单中的字段名称。该类将检查原始文件是否已上传到其临时位置(您也可以使用本地文件名来实例化类)。
然后,您可以设置多个处理变量来对文件进行操作。例如,您可以重命名文件,如果它是图像,则可以以多种方式转换和调整大小。您还可以设置如果文件已存在,类将执行什么操作。
然后,您调用函数process()
以执行上述设置的处理参数。它将创建原始文件的新实例,因此原始文件在每个处理过程中都保持不变。文件将被操作并复制到指定的位置。处理变量在完成后将被重置。
您可以重复设置一组新的处理变量,并多次调用process()
。完成之后,您可以调用clean()
来删除原始上传的文件。
如果您未设置任何处理参数,并在实例化类后立即调用process()
,则上传的文件将被简单地复制到指定的位置,而不会进行任何更改或检查。
不要忘记在你的表单标签 <form>
中添加 enctype="multipart/form-data"
,如果你想让表单上传文件。
命名空间
现在类在 Verot/Upload
命名空间中。如果你遇到错误 致命错误:找不到类 'Upload',则使用类的完全限定名称,或者用完全限定名称实例化类
use Verot\Upload\Upload; $handle = new Upload($_FILES['image_field']);
或者
$handle = new \Verot\Upload\Upload($_FILES['image_field']);
如何处理本地文件?
用本地文件名实例化类,如下所示
$handle = new Upload('/home/user/myfile.jpg');
如何处理通过 XMLHttpRequest 上传的文件?
用特殊的 php: 关键字实例化类,如下所示
$handle = new Upload('php:'.$_SERVER['HTTP_X_FILE_NAME']);
在参数前加上 php: 告诉类在 php://input 中检索上传数据,其余的是流的文件名,通常在 $_SERVER['HTTP_X_FILE_NAME']
中。但你可以使用任何你认为合适的名字
$handle = new Upload('php:mycustomname.ext');
如何处理原始文件数据?
用特殊的 data: 关键字实例化类,如下所示
$handle = new Upload('data:'.$file_contents);
如果你的数据是 base64 编码的,类提供了一个简单的 base64: 关键字,它会在使用之前解码你的数据
$handle = new Upload('base64:'.$base64_file_contents);
如何设置语言?
用语言代码作为第二个参数实例化类
$handle = new Upload($_FILES['image_field'], 'fr_FR'); $handle = new Upload('/home/user/myfile.jpg', 'fr_FR');
如何直接将结果文件或图片输出到浏览器?
只需不带参数(或以 null 作为第一个参数)调用 process()
$handle = new Upload($_FILES['image_field']); header('Content-type: ' . $handle->file_src_mime); echo $handle->process(); die();
或者,如果你想强制下载文件
$handle = new Upload($_FILES['image_field']); header('Content-type: ' . $handle->file_src_mime); header("Content-Disposition: attachment; filename=".rawurlencode($handle->file_src_name).";"); echo $handle->process(); die();
安全警告
默认情况下,该类依赖于 MIME 类型检测来评估文件是否可以上传。根据服务器配置,使用了几种 MIME 类型检测方法。该类依赖于危险文件扩展名的黑名单来防止上传(或将危险脚本重命名为文本文件),以及接受 MIME 类型的白名单。
但这个类不是用来进行深度检查和启发式算法来尝试检测恶意构造的文件的。例如,攻击者可以构造一个具有正确 MIME 类型的文件,但它会携带恶意负载,例如一个有效的 GIF 文件,其中包含一些导致 XSS 漏洞的代码。如果这个 GIF 文件有 .html 扩展名,它可能被上传(取决于类的设置)并显示 XSS 漏洞。
然而,你可以通过使用 allowed
和 forbidden
来限制可以上传的文件类型,根据其 MIME 类型或扩展名进行白名单和黑名单操作。最安全的选项是只将你希望允许通过的扩展名添加到白名单中,然后确保服务器总是根据文件扩展名提供基于内容的类型。
例如,如果你只想允许一种类型的文件,你可以只将其文件扩展名添加到白名单中。在以下示例中,只有 .html 文件被允许通过,并且不会被转换为文本文件
$handle->allowed = array('html'); $handle->forbidden = array(); $handle->no_script = false;
最后,确保正确上传文件是你的责任。但更重要的是,确保正确地提供上传文件,例如通过强制服务器总是根据文件扩展名提供内容类型。
故障排除
如果类没有按预期工作,你可以显示日志,以便详细了解类做了什么。要获取日志,只需在代码末尾添加此行
echo $handle->log;
你的问题可能已经在常见问题解答中讨论过: http://www.verot.net/php_class_upload_faq.htm
如果没有,你可以在论坛中搜索,并在那里提问: http://www.verot.net/php_class_upload_forum.htm。请勿使用 Github issues 来请求帮助。
处理参数
注意:本节中所有参数在每个进程后都会重置。
文件处理
- file_new_name_body 替换名称主体(默认:null)
$handle->file_new_name_body = 'new name';
- file_name_body_add 追加到名称主体(默认:null)
$handle->file_name_body_add = '_uploaded';
- file_name_body_pre 预加到名称主体(默认:null)
$handle->file_name_body_pre = 'thumb_';
- file_new_name_ext 替换文件扩展名(默认:null)
$handle->file_new_name_ext = 'txt';
- file_safe_name 格式化文件名(空格替换为_等)(默认:true)
$handle->file_safe_name = true;
- file_force_extension 如果没有扩展名则强制添加(默认:true)
$handle->file_force_extension = true;
- file_overwrite 如果文件已存在,则设置行为(默认:false)
$handle->file_overwrite = true;
- file_auto_rename 如果文件已存在则自动重命名(默认:true)
$handle->file_auto_rename = true;
- dir_auto_create 如果缺少目标目录则自动创建(默认:true)
$handle->dir_auto_create = true;
- dir_auto_chmod 如果目标目录不可写则自动尝试更改权限(默认:true)
$handle->dir_auto_chmod = true;
- dir_chmod 创建目录或目录不可写时使用的chmod(默认:0777)
$handle->dir_chmod = 0777;
- file_max_size 设置最大上传大小(默认:来自php.ini的upload_max_filesize)
$handle->file_max_size = '1024'; // 1KB
- mime_check 设置类是否检查MIME与
allowed
列表的匹配(默认:true)
$handle->mime_check = true;
- no_script 设置类是否将危险脚本转换为文本文件(默认:true)
$handle->no_script = false;
- allowed 允许的MIME类型或文件扩展名数组(或一个字符串)。接受通配符,如image/*(默认:检查
init()
)
$handle->allowed = array('application/pdf','application/msword', 'image/*');
- forbidden 禁止的MIME类型或文件扩展名数组(或一个字符串)。接受通配符,如image/*(默认:检查
init()
)
$handle->forbidden = array('application/*');
图像处理
- image_convert 如果设置,则将图像转换(可能的值:''|'png'|'webp'|'jpeg'|'gif'|'bmp';默认:'')
$handle->image_convert = 'jpg';
- image_background_color 如果设置,将以十六进制颜色强制填充透明区域(默认:null)
$handle->image_background_color = '#FF00FF';
- image_default_color 对于JPEG或BMP等非alpha透明输出格式,为后备颜色背景色,以十六进制表示(默认:#FFFFFF)
$handle->image_default_color = '#FF00FF';
- png_compression 设置PNG图像的压缩级别,介于1(快速但文件大)和9(慢但文件小)之间(默认:null(Zlib默认))
$handle->png_compression = 9;
- webp_quality 设置WEBP图像的压缩质量(默认:85)
$handle->webp_quality = 50;
- jpeg_quality 设置JPEG图像的压缩质量(默认:85)
$handle->jpeg_quality = 50;
- jpeg_size 如果设置为字节数,将近似
jpeg_quality
以使输出图像适合该大小(默认:null)
$handle->jpeg_size = 3072;
- image_interlace 如果设置为true,则图像将被交错保存(如果它是JPEG,则保存为渐进式PEG)(默认:false)
$handle->image_interlace = true;
图像检查
以下八个设置可以用于在文件是图像时使上传无效(请注意,open_basedir限制防止使用这些设置)
- image_max_width 如果设置为像素尺寸,则如果图像宽度更大,则上传将无效(默认:null)
$handle->image_max_width = 200;
- image_max_height 如果设置为像素尺寸,则如果图像高度更大,则上传将无效(默认:null)
$handle->image_max_height = 100;
- image_max_pixels 如果设置为像素数,则如果图像像素数更大,则上传将无效(默认:null)
$handle->image_max_pixels = 50000;
- image_max_ratio 如果设置为宽高比(宽度/高度),则如果图像宽高比更大,则上传将无效(默认:null)
$handle->image_max_ratio = 1.5;
- image_min_width 如果设置为像素尺寸,则如果图像宽度更小,则上传将无效(默认:null)
$handle->image_min_width = 100;
- image_min_height 如果设置为像素尺寸,则如果图像高度更小,则上传将无效(默认:null)
$handle->image_min_height = 500;
- image_min_pixels 如果设置为像素数,则如果图像像素数更小,则上传将无效(默认:null)
$handle->image_min_pixels = 20000;
- image_min_ratio 如果设置为宽高比(宽度/高度),则如果图像宽高比更小,则上传将无效(默认:null)
$handle->image_min_ratio = 0.5;
图像缩放
- image_resize 确定图像是否将被缩放(默认:false)
$handle->image_resize = true;
以下变量仅在image_resize == true时使用
- image_x 目标图像宽度(默认:150)
$handle->image_x = 100;
- image_y 目标图像高度(默认:150)
$handle->image_y = 200;
选择以下之一
- image_ratio 如果为真,保持原始尺寸比例调整图像大小,使用
image_x
和image_y
作为最大尺寸(默认:false)
$handle->image_ratio = true;
- image_ratio_crop 如果为真,保持原始尺寸比例调整图像大小,使用
image_x
和image_y
作为最大尺寸,并裁剪多余部分。设置也可以是字符串,包含一个或多个来自 'TBLR' 的字符,表示裁剪时保留图像的哪一边(默认:false)
$handle->image_ratio_crop = true;
- image_ratio_fill 如果为真,保持原始尺寸比例调整图像大小,使用
image_x
和image_y
作为最大尺寸,填充空间并着色剩余部分。设置也可以是字符串,包含一个或多个来自 'TBLR' 的字符,表示图像将在空间中的哪一边(默认:false)
$handle->image_ratio_fill = true;
- image_ratio_x 如果为真,调整图像大小,从
image_y
计算出image_x
并保持原始尺寸比例(默认:false)
$handle->image_ratio_x = true;
- image_ratio_y 如果为真,调整图像大小,从
image_x
计算出image_y
并保持原始尺寸比例(默认:false)
$handle->image_ratio_y = true;
- image_ratio_pixels 如果设置为长整数,调整图像大小,使
image_y
和image_x
与像素数匹配(默认:false)
$handle->image_ratio_pixels = 25000;
并最终防止图像放大或缩小
- image_no_enlarging 如果调整大小后的图像大于原始图像,取消调整大小以防止放大(默认:false)
$handle->image_no_enlarging = true;
- image_no_shrinking 如果调整大小后的图像小于原始图像,取消调整大小以防止缩小(默认:false)
$handle->image_no_shrinking = true;
图像效果
以下图像操作需要 GD2+
- image_brightness 如果设置,校正亮度。值在 -127 到 127 之间(默认:null)
$handle->image_brightness = 40;
- image_contrast 如果设置,校正对比度。值在 -127 到 127 之间(默认:null)
$handle->image_contrast = 50;
- image_opacity 如果设置,改变图像不透明度。值在 0 到 100 之间(默认:null)
$handle->image_opacity = 50;
- image_tint_color 如果设置,将颜色调色图像,值作为十六进制 #FFFFFF(默认:null)
$handle->image_tint_color = '#FF0000';
- image_overlay_color 如果设置,将添加彩色覆盖,值作为十六进制 #FFFFFF(默认:null)
$handle->image_overlay_color = '#FF0000';
- image_overlay_opacity 当
image_overlay_color
设置时使用,确定不透明度(默认:50)
$handle->image_overlay_opacity = 20;
- image_negative 反转图像中的颜色(默认:false)
$handle->image_negative = true;
- image_greyscale 将图像转换为灰度(默认:false)
$handle->image_greyscale = true;
- image_threshold 应用阈值过滤器。值在 -127 到 127 之间(默认:null)
$handle->image_threshold = 20;
- image_pixelate 像素化图像,值是块大小(默认:null)
$handle->image_pixelate = 10;
- image_unsharp 应用未锐化掩码,支持 alpha 透明度(默认:false)
$handle->image_unsharp = true;
- image_unsharp_amount 未锐化掩码量,通常 50 - 200(默认:80)
$handle->image_unsharp_amount = 120;
- image_unsharp_radius 未锐化掩码半径,通常 0.5 - 1(默认:0.5)
$handle->image_unsharp_radius = 1;
- image_unsharp_threshold 未锐化掩码阈值,通常 0 - 5(默认:1)
$handle->image_unsharp_threshold = 0;
图像文字
- image_text 在图像上创建文本标签,值是一个字符串,包含可能的替换令牌(默认:null)
$handle->image_text = 'test';
- image_text_direction 文本标签方向,'h' 水平或 'v' 垂直(默认:'h')
$handle->image_text_direction = 'v';
- image_text_color 文本标签的颜色,十六进制(默认:#FFFFFF)
$handle->image_text_color = '#FF0000';
- image_text_opacity 文本标签上的不透明度,介于 0 和 100 之间的整数(默认:100)
$handle->image_text_opacity = 50;
- image_text_background 文本标签背景颜色,十六进制(默认:null)
$handle->image_text_background = '#FFFFFF';
- image_text_background_opacity 文本标签背景不透明度,介于 0 和 100 之间的整数(默认:100)
$handle->image_text_background_opacity = 50;
- image_text_font 文本标签的内置字体,从 1 到 5。1 是最小的(默认:5)。值也可以是字符串,表示 GDF 或 TTF 字体的路径(TrueType)。
$handle->image_text_font = 4; // or './font.gdf' or './font.ttf'
- image_text_size TrueType字体字体大小,以像素(GD1)或点(GD1)为单位(默认:16)(仅TrueType字体)
$handle->image_text_size = 24;
- image_text_angle TrueType字体文本角度,以度为单位,0度表示从左到右阅读的文本(默认:null)(仅TrueType字体)
$handle->image_text_angle = 45;
- image_text_x 绝对文本标签位置,从左边框的像素数。可以是负数(默认:null)
$handle->image_text_x = 5;
- image_text_y 绝对文本标签位置,从上边框的像素数。可以是负数(默认:null)
$handle->image_text_y = 5;
- image_text_position 图像内文本标签位置,可以是'TBLR'中一个或两个的组合:顶部、底部、左侧、右侧(默认:null)
$handle->image_text_position = 'LR';
- image_text_padding 文本标签填充,以像素为单位。可以被
image_text_padding_x
和image_text_padding_y
覆盖(默认:0)
$handle->image_text_padding = 5;
- image_text_padding_x 文本标签水平填充(默认:null)
$handle->image_text_padding_x = 2;
- image_text_padding_y 文本标签垂直填充(默认:null)
$handle->image_text_padding_y = 10;
- image_text_alignment 文本多行时的对齐方式,可以是'L'、'C'或'R'(默认:'C')(仅GD字体)
$handle->image_text_alignment = 'R';
- image_text_line_spacing 文本多行时行间距,以像素为单位(默认:0)(仅GD字体)
$handle->image_text_line_spacing = 3;
图像变换
- image_auto_rotate 根据EXIF数据自动旋转图像(仅JPEG)(默认:true,即使没有图像操作也会应用)
$handle->image_auto_rotate = false;
- image_flip 翻转图像,'h'表示水平翻转,'v'表示垂直翻转(默认:null)
$handle->image_flip = 'h';
- image_rotate 旋转图像。可能的值是90、180和270(默认:null)
$handle->image_rotate = 90;
- image_crop 裁剪图像。接受4、2或1个值作为'T R B L'或'TB LR'或'TBLR'。尺寸可以是20,或20px或20%(默认:null)
$handle->image_crop = array(50,40,30,20); OR '-20 20%'...
- image_precrop 在可能的调整大小之前裁剪图像。接受4、2或1个值作为'T R B L'或'TB LR'或'TBLR'。尺寸可以是20,或20px或20%(默认:null)
$handle->image_precrop = array(50,40,30,20); OR '-20 20%'...
图像边框
- image_bevel 向图像添加斜边框。值是像素厚度(默认:null)
$handle->image_bevel = 20;
- image_bevel_color1 顶部和左侧斜边框颜色,十六进制表示(默认:#FFFFFF)
$handle->image_bevel_color1 = '#FFFFFF';
- image_bevel_color2 底部右侧斜边框颜色,十六进制表示(默认:#000000)
$handle->image_bevel_color2 = '#000000';
- image_border 向图像添加单色边框。接受4、2或1个值作为'T R B L'或'TB LR'或'TBLR'。尺寸可以是20,或20px或20%(默认:null)
$handle->image_border = '3px'; OR '-20 20%' OR array(3,2)...
- image_border_color 边框颜色,十六进制表示(默认:#FFFFFF)
$handle->image_border_color = '#FFFFFF';
- image_border_opacity 边框不透明度,介于0到100之间的整数(默认:100)
$handle->image_border_opacity = 50;
- image_border_transparent 向图像添加渐变到透明的边框。接受4、2或1个值作为'T R B L'或'TB LR'或'TBLR'。尺寸可以是20,或20px或20%(默认:null)
$handle->image_border_transparent = '3px'; OR '-20 20%' OR array(3,2)...
- image_frame 框架类型:1=平面 2=交叉(默认:null)
$handle->image_frame = 2;
- image_frame_colors 十六进制颜色的列表,为数组或空格分隔的字符串(默认:'#FFFFFF #999999 #666666 #000000')
$handle->image_frame_colors = array('#999999', '#FF0000', '#666666', '#333333', '#000000');
- image_frame_opacity 框架不透明度,介于0到100之间的整数(默认:100)
$handle->image_frame_opacity = 50;
图像水印
- image_watermark 在图像上添加水印,值是本地文件名。接受的文件是GIF、JPG、BMP、WEBP、PNG和PNG alpha(默认:null)
$handle->image_watermark = 'watermark.png';
- image_watermark_x 绝对水印位置,从左边框的像素数。可以是负数(默认:null)
$handle->image_watermark_x = 5;
- image_watermark_y 绝对水印位置,从上边框的像素数。可以是负数(默认:null)
$handle->image_watermark_y = 5;
- image_watermark_position 水印在图像中的位置,可以是'TBLR'中一个或两个的组合:顶部、底部、左侧、右侧(默认:null)
$handle->image_watermark_position = 'LR';
- image_watermark_no_zoom_in 防止水印在小于图像时被放大(默认:true)
$handle->image_watermark_no_zoom_in = false;
- image_watermark_no_zoom_out 防止水印在比图像大时被缩小(默认:false)
$handle->image_watermark_no_zoom_out = true;
图像反射
- image_reflection_height 如果设置,将添加反射。格式为像素或百分比,例如40, '40', '40px' 或 '40%'(默认:null)
$handle->image_reflection_height = '25%';
- image_reflection_space 源图像与反射之间的像素空间,可以是负数(默认:null)
$handle->image_reflection_space = 3;
- image_reflection_color 反射背景颜色,十六进制格式。现在已弃用,建议使用
image_default_color
(默认:#FFFFFF)
$handle->image_default_color = '#000000';
- image_reflection_opacity 反射开始时的透明度级别,介于0和100之间的整数(默认:60)
$handle->image_reflection_opacity = 60;
在调用 process()
之前可以读取的值
- file_src_name 源文件名
- file_src_name_body 源文件名主体
- file_src_name_ext 源文件扩展名
- file_src_pathname 源文件的完整路径和名称
- file_src_mime 源文件的MIME类型
- file_src_size 源文件大小(字节)
- file_src_error 上传错误代码
- file_is_image 布尔标志,如果文件是受支持的图像类型则为true
如果文件是受支持的图像类型(并且 open_basedir 限制允许)
- image_src_x 源文件宽度(像素)
- image_src_y 源文件高度(像素)
- image_src_pixels 源文件的像素数
- image_src_type 源文件类型(png, webp, jpg, gif 或 bmp)
- image_src_bits 源文件颜色深度
在调用 process()
之后可以读取的值
- file_dst_path 目标文件路径
- file_dst_name_body 目标文件名主体
- file_dst_name_ext 目标文件扩展名
- file_dst_name 目标文件名
- file_dst_pathname 目标文件的完整路径和名称
如果文件是受支持的图像类型
- image_dst_type 目标文件类型(png, webp, jpg, gif 或 bmp)
- image_dst_x 目标文件宽度
- image_dst_y 目标文件高度
要求
大多数图像操作都需要GD。强烈推荐使用GD2
1.x版本支持PHP 4、5和7,但没有命名空间。如果您需要支持PHP <5.3,请使用它
2.x版本支持PHP 5.3+、PHP 7和PHP 8。