打印 上一主题 下一主题

Discuz 论坛Flash上传

跳转到指定楼层
楼主
SetYun 发表于 2018-10-20 10:16:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
基于版本:Discuz! X 2.0


发帖时经常使用flash 批量上传附件,来粗略的了解一下flash上传附件的过程。

在帖子中,当点击编辑器上传按纽 程序读取 ./template/default/forum/editor_menu_forum.htm 模板文件
从编辑模板源文件里面可以看到程序输出了一代码,其中的js
  • <script type="text/javascript">
  •         $('{$editorid}_multiimg').innerHTML = AC_FL_RunContent(
  •                 'width', '470', 'height', '268',
  •                 'src', '{IMGDIR}/upload.swf?site={$_G[siteroot]}misc.php%3fmod=swfupload%26type=image%26fid=$_G[fid]&type=image&random=<!--{echo random(4)}-->',
  •                 'quality', 'high',
  •                 'id', 'swfupload',
  •                 'menu', 'false',
  •                 'allowScriptAccess', 'always',
  •                 'wmode', 'transparent'
  •         );
  • </script>


[color=rgb(51, 102, 153) !important]复制代码

输出 flash

使用 AC_FL_RunContent 函数(此函数在 common.js)来输出 flash

在此函数中 使用 AC_GetArgs 函数来处理 AC_FL_RunContent  所传进来的变量以构造 flash 输出相关的信息

从以上代码的
  • 'src', '{IMGDIR}/upload.swf?site={$_G[siteroot]}misc.php%3fmod=swfupload%26type=image%26fid=$_G[fid]&type=image&random=<!--{echo random(4)}-->',

[color=rgb(51, 102, 153) !important]复制代码

可以看出 此 flash 的 src 为 论坛后台设定的 IMGDIR 目录下的 upload.swf 输出的 flash 还传进了一段参数

这里面要注意 {IMGDIR} 为后台设定图片目录 或者 ./config/config_global.php中的 $_config['output']['staticurl'] 值 , 有些站长把该值设置了远程的一个地址 于是程序请求得是远程的  upload.swf ,当文件上传完成后 upload.swf  会请求相同目录下的 misc.php 文件 这样设置可能就会上传失败
  • site={$_G[siteroot]}misc.php%3fmod=swfupload%26type=image%26fid=$_G[fid]&type=image&random=<!--{echo random(4)}-->

[color=rgb(51, 102, 153) !important]复制代码

flash 会根据该参数 请求类似 misc.php?mod=swfupload&fid=2&action=swfupload&operation=config 的地址

根据该地址我们很容易找到 misc_swfupload.php 文件,&operation=config 初始化处理后将会输出一个 xml 给 flash。此 xml  里面包括 flash 上传界面的提示文字、上传大小限制、上传文件的限制类型等等,很多时候点上传 flash 按纽空白 没有显示中文件都是因为 xml 输出出错导致

到这里 一切正常 xml 也没出错 我们就可以看到 flash 上传的界面 (终于可以开始上传了....)



点击浏览器按纽,选择需要上传的文件点上传后 flash 会请求到 misc_swfupload.php 此时文件就被php传到 php 所配置的上传的临时路径下

所以,在上传失败时可能的一条原因是 php.ini 中 upload_tmp_dir 所指定的临时上传目录或硬盘是否满了,是否有权限

  • } elseif($_G['gp_operation'] == 'upload') {

  •         require_once libfile('class/forumupload');
  •         if(empty($_G['gp_simple'])) {
  •                 $_FILES['Filedata']['name'] = addslashes(diconv(urldecode($_FILES['Filedata']['name']), 'UTF-8'));
  •                 $_FILES['Filedata']['type'] = $_G['gp_filetype'];
  •         }
  •         $upload = new forum_upload();

  • }


[color=rgb(51, 102, 153) !important]复制代码

在此实例化了一个 forum_upload 类( class_forumupload.php ) 在这个类里面使用了 discuz_upload 类( class_upload.php )对文件进行移动处理

程序首先 调用 discuz_upload 里面的 init 方法处理 $_FILES 来得到上传文件的目标路径、文件名、大小等等信息,存在其属性 $attach 数组中

init 方法会调用到 is_image_ext 来判断文件是否属于图片(该方法判断后缀有 'jpg', 'jpeg', 'gif', 'png', 'bmp');

出于安全的考虑 init 中调用到 get_target_extension 方法处理非法的文件后缀(将非 'attach', 'jpg', 'jpeg', 'gif', 'png', 'swf', 'bmp', 'txt', 'zip', 'rar', 'mp3'扩展名名的附件扩展名改成 attach)

然后根据 $attach 里面的各项值 来判断相关的 所上传文件尺寸、大小、类型、当前用户所属用户组上传限制等合法性

当程序判断该附件“合法”,则调用 discuz_upload 类的 save 方法 对图片进行移动,从php 的临时上传目录移到程序附件相对应的目录

save 方法所调用的 save_to_local 兼容使用了 copy、move_uploaded_file、fread/fwrite等三种移动方法

在此我们可以发现需要 data 目录及子目录需要可读写执行权限。

在这里如果有产生错误,

  • 'file_upload_error_-101' => '上传失败!上传文件不存在或不合法,请返回。',
  • 'file_upload_error_-102' => '上传失败!非图片类型文件,请返回。',
  • 'file_upload_error_-103' => '上传失败!无法写入文件或写入失败,请返回。',
  • 'file_upload_error_-104' => '上传失败!无法识别的图像文件格式,请返回。',


[color=rgb(51, 102, 153) !important]复制代码

根据文字所对应的数字代码,可以在 class_upload.php 中找到其相对应的判断所进入的判断代码行。

  • '-1' : '内部服务器错误',
  • '0' : '上传成功',
  • '1' : '不支持此类扩展名',
  • '2' : '服务器限制无法上传那么大的附件',
  • '3' : '用户组限制无法上传那么大的附件',
  • '4' : '不支持此类扩展名',
  • '5' : '文件类型限制无法上传那么大的附件',
  • '6' : '今日你已无法上传更多的附件',
  • '7' : '请选择图片文件(' + imgexts + ')',
  • '8' : '附件文件无法保存',
  • '9' : '没有合法的文件被上传',
  • '10' : '非法操作',
  • '11' : '今日你已无法上传那么大的附件'


[color=rgb(51, 102, 153) !important]复制代码

上传失败所示提的代码也可以在 class_forumupload.php 里面找到相对应的判断。这样就能很方便的找到问题出错在哪里。

save 成功后 如果所上传文件是图片附件,并且后台开启了生成缩略图,程序会根据上传后的图片进行处理生成缩略图

上传成功,forum_upload 类 使用 getattachnewaid 函数 向 forum_attachment 插入一条记录返回新附件的 aid

并插入一条记录到 forum_attachment_unused 表的中

点确定后返回到附件列表,程序根据aid 向 forum.php?mod=ajax&action=attachlist&aids=|7|6|5&fid=2&inajax=1&ajaxtarget=attachlist 地址请求

该地址处理程序 forum_ajax.php 使用 getattach 函数从数据库中读出附件等信息并将附件展示出来

至此附件上传成功

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|SetYun ( 辽ICP备16005250号

GMT+8, 2024-5-3 23:26 , Processed in 0.038794 second(s), 5 queries , File On.

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表