本文探讨下如何在论坛里的普通上传(即在不支持Flash或没激活Flash的情形)中支持一次选择多个文件。 Discuz的这个功能允许多次选择多个文件后上传,但每次选择只能选择一个文件。在PHP里支持一次选择多个文件的要点参见网页
http://php.net/manual/zh/features.file-upload.multiple.php 上的解释。
首先是图示:
1。点击工具栏里的图片图标后,出现选择图片对话框:
2。点击选择按钮后,在选择文件对话框里可以选择多个文件:
3。显示所有选中的图片名:
4。点击上传后:
下面介绍下要修改的代码:
1) 需要改变file元素的属性使之能同时选择多个文件
在 template/default/forum/editor_menu_forum.htm里,有两个file元素,一个用于上传图片
另一个用于上传附件
都改为
其中添加multiple属性是为了在选择文件框里能选择多个文件,name的修改是PHP的要求使得在服务器端能得到上传的多个文件。
2) 当选择完成后要在网页上要显示所有选择的文件
在 static/js/forum_post.js 的函数addAttach中,需要做两处修改。首先由于我们上面改了file元素的name,所以在函数 addAttach 里需要将下面这句
if(tags[i].name == 'Filedata') {
改成
if(tags[i].name == 'Filedata[]') {
其次函数insertAttach是用于在网页上显示选择后的文件的,原来的代码从file元素的value值中得到选择的文件名,这种方式得不到多个文件名。在多选的情况下,它还是只含有一个文件名。而file元素的files值是一个数组,其中每个元素对应了选择的一个文件。我们要将这个函数里的下面部分
var path = $(prefix + 'attachnew_' + id).value;
var extpos = path.lastIndexOf('.');
var ext = extpos == -1 ? '' : path.substr(extpos + 1, path.length).toLowerCase();
var re = new RegExp("(^|\\s|,)" + ext + "($|\\s|,)", "ig");
var localfile = $(prefix + 'attachnew_' + id).value.substr($(prefix + 'attachnew_' + id).value.replace(/\\/g, '/').lastIndexOf('/') + 1);
var filename = mb_cutstr(localfile, 30);
if(path == '') {
return;
}
if(extensions != '' && (re.exec(extensions) == null || ext == '')) {
reAddAttach(prefix, id);
showError('对不起,不支持上传此类扩展名的附件。');
return;
}
if(prefix == 'img' && imgexts.indexOf(ext) == -1) {
reAddAttach(prefix, id);
showError('请选择图片文件(' + imgexts + ')');
return;
}
改成
var files = $(prefix + 'attachnew_' + id).files;
if (!files) return;
var filename = '';
var localfile = '';
for (var i = 0; i < files.length; i++) {
var path = files[i].name;
var extpos = path.lastIndexOf('.');
var ext = extpos == -1 ? '' : path.substr(extpos + 1, path.length).toLowerCase();
var re = new RegExp("(^|\\s|,)" + ext + "($|\\s|,)", "ig");
if (extensions != '' && (re.exec(extensions) == null || ext == '')) {
reAddAttach(prefix, id);
showError('对不起,不支持上传此类扩展名的附件。');
return;
}
if (prefix == 'img' && imgexts.indexOf(ext) == -1) {
reAddAttach(prefix, id);
showError('请选择图片文件(' + imgexts + ')');
return;
}
if (i > 0) filename += '; ';
filename += path;
if (i > 0) localfile += '; ';
localfile += path.substr(path.replace(/\\/g, '/').lastIndexOf('/') + 1);
}
3) 需要修改当点击上传后接受上传的代码
由于上面对客户端添加了上传多个文件的支持,在服务器端收到的诸如$_FILES['Filedata']['name'],$_FILES['Filedata']['type']等值不再是字符串,而成了数组。数组的长度由上传文件的个数决定,其中每个元素记载了一个文件的相应属性。所以我们需要对PHP代码做些调整,来支持保存多个文件。需要修改两个PHP文件。
3a) 在source/module/misc/misc_swupload.php中将下面这句
$upload = new forum_upload();
改为
if (is_array($_FILES['Filedata']['name'])) {
$count = count($_FILES['Filedata']['name']);
$file_keys = array_keys($_FILES['Filedata']);
for($i=0; $i<$count; $i++) {
$fd = array();
foreach ($file_keys as $key) {
$fd[$key] = $_FILES['Filedata'][$key][$i];
}
$upload = new forum_upload(0, $fd);
}
}
else {
$upload = new forum_upload();
}
exit;
3b) 在文件 source/class/forum/forum_upload.php 里,将下面这句
function forum_upload($getaid = 0) {
改为
function forum_upload($getaid = 0, $filedata = null) {
然后将下面这段
$upload = new discuz_upload();
$upload->init($_FILES['Filedata'], 'forum');
改为
if (empty($filedata)) $filedata = $_FILES['Filedata'];
$upload = new discuz_upload();
$upload->init($filedata, 'forum');
最后将函数uploadmsg里的最后一句
exit;
改成
if ($statusid) exit;