这里的“自动打包”通常有两种理解:

(图片来源网络,侵删)
- 前端打包(用户体验优化):用户在浏览图集时,可以一键将所有图片打包成一个 ZIP 压缩包下载,这是最常见的需求。
- 后端打包(管理效率优化):在后台发布或更新图集时,系统自动将图片打包,并可能附加到文章内容或进行其他处理,这个需求比较特殊,通常需要定制开发。
我将重点讲解第一种,也是最实用的前端自动打包功能,并提供详细的步骤和代码。
核心思路
实现这个功能主要分为三步:
- 修改图集内容页模板:在模板中添加一个“打包下载”的按钮或链接。
- 编写下载处理程序:创建一个 PHP 文件,该文件负责读取图集中的所有图片地址,将它们临时打包成 ZIP 文件,然后提供给用户下载。
- 安全与优化:确保下载过程安全,并处理好临时文件的清理。
详细操作步骤
第一步:修改图集内容页模板 (article_image.htm)
-
找到模板文件: 登录织梦后台,进入【模板】->【默认模板管理】->【内容页模板】,找到你当前使用的图集内容页模板,文件名通常是
article_image.htm。 -
添加下载按钮: 在模板中你希望显示下载按钮的位置(图片轮播器的下方、图集描述的旁边等),添加如下代码:
(图片来源网络,侵删)<div class="dede_pages"> <ul class="pagelist"> <!-- 这里是织梦原有的分页代码,保持不变 --> {dede:field name='imgurls' runphp='yes'} if(@me!=''){ @me = '<li><a href="/plus/download.php?aid=".urlencode(@me)."&action=zip" class="download-btn">打包下载全部图片</a></li>'; }else{ @me = ''; } {/dede:field} </ul> </div> <style> .download-btn { display: inline-block; padding: 8px 15px; background-color: #007bff; color: #ffffff; text-decoration: none; border-radius: 4px; font-size: 14px; transition: background-color 0.3s; } .download-btn:hover { background-color: #0056b3; color: #ffffff; text-decoration: none; } </style>代码解释:
- 我们使用了
{dede:field name='imgurls'}来获取当前图集的完整图片集信息(包含所有图片的地址、说明等)。 runphp='yes'允许我们在模板中执行 PHP 代码。urlencode(@me)对图集ID进行URL编码,确保在URL中传递正确。- 我们创建了一个新的链接,指向
/plus/download.php(这是织梦默认的下载程序目录),并传递了两个参数:aid(文章ID)和action=zip(自定义动作,表示要执行打包操作)。 - 顺便添加了一些CSS样式,让按钮更好看。
- 我们使用了
第二步:创建并编写下载处理程序 (download.php)
-
找到并备份原文件: 在你的网站根目录下的
/plus/文件夹中,找到download.php文件。在修改之前,请务必先备份这个原始文件! 因为这个文件是织梦处理所有下载请求的核心文件。 -
修改
download.php文件: 用代码编辑器打开备份后的download.php文件,在文件末尾的?>之前,添加如下代码:// ============================================== // 织梦图集自动打包下载功能 // ============================================== if ($action == 'zip' && is_numeric($aid)) { // 1. 引入数据库配置 require_once(dirname(__FILE__) . "/../include/config_base.php"); require_once(DEDEINC . "/dedetag.class.php"); // 2. 获取图集内容 $arcRow = $dsql->GetOne("SELECT * FROM `#@__archives` WHERE id = '$aid'"); if (!is_array($arcRow)) { die('图集不存在或已被删除!'); } $addRow = $dsql->GetOne("SELECT * FROM `#@__addonarticle` WHERE aid = '$aid'"); if (!is_array($addRow)) { die('图集附加信息不存在!'); } $imgurls = $addRow['imgurls']; if (empty($imgurls)) { die('图集中没有图片!'); } // 3. 解析图片地址 // 使用正则表达式匹配所有图片的真实URL // 注意:这里匹配的是原始图片地址,如果你需要缩略图,请修改 '/uploads/' 和 '/litimg/' 的路径 preg_match_all('/<img[^>]*src\s*=\s*["|\']([^"|\']*(\/uploads\/[^"|\']*\.(jpg|jpeg|gif|png|webp)))[^>]*>/i', $imgurls, $matches); if (empty($matches[1])) { die('未能从图集中解析出有效的图片地址!'); } $imageUrls = $matches[1]; // 4. 创建临时ZIP文件 $zipFileName = 'album_' . $aid . '_' . time() . '.zip'; $zipFilePath = dirname(__FILE__) . '/temp/' . $zipFileName; // 将临时文件放在 /plus/temp/ 目录下 // 确保临时目录存在 if (!is_dir(dirname($zipFilePath))) { @mkdir(dirname($zipFilePath), 0777); } // 引入ZipArchive类 (PHP自带) $zip = new ZipArchive(); if ($zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) { die('无法创建ZIP文件!'); } // 5. 下载并添加图片到ZIP包 foreach ($imageUrls as $url) { // 为了安全,我们只允许下载本站的图片 if (strpos($url, 'http') === 0 && strpos($url, $cfg_basehost) === false) { continue; // 跳过外部链接 } // 获取文件名 $fileName = basename($url); $filePathOnServer = str_replace($cfg_basehost, '', $url); // 去掉域名,得到服务器上的相对路径 // 检查文件是否存在 if (file_exists($filePathOnServer)) { $zip->addFile($filePathOnServer, $fileName); } else { // 如果图片不存在,可以跳过或记录日志 // echo "图片不存在: " . $filePathOnServer . "<br>"; } } $zip->close(); // 6. 提供下载 if (file_exists($zipFilePath)) { header('Content-Type: application/zip'); header('Content-Disposition: attachment; filename="' . $zipFileName . '"'); header('Content-Length: ' . filesize($zipFilePath)); readfile($zipFilePath); // 7. 下载完成后删除临时文件 unlink($zipFilePath); exit; } else { die('打包失败,临时文件未生成。'); } } -
代码逻辑解释:
- 安全检查:首先检查
$action是否为zip$aid是否为数字,防止恶意访问。 - 获取数据:从
#@__archives和#@__addonarticle这两个表中获取图集的基本信息和图片集内容。 - 解析图片:使用
preg_match_all正则表达式,从$imgurls字段的HTML字符串中提取出所有<img>标签的src属性值,即图片的真实URL。 - 创建ZIP:使用PHP内置的
ZipArchive类来创建一个名为album_[ID]_[时间戳].zip的临时文件。 - 添加文件:遍历所有图片URL,检查文件是否存在于服务器上,如果存在则添加到ZIP压缩包中,这里做了安全检查,只允许下载本站域名下的图片。
- 提供下载:设置正确的HTTP头信息(
Content-Type,Content-Disposition等),将ZIP文件的内容输出给浏览器。 - 清理:下载完成后,立即删除服务器上的临时ZIP文件,避免占用磁盘空间。
- 安全检查:首先检查
第三步:创建临时目录并设置权限
为了让 download.php 能够成功创建和写入临时ZIP文件,我们需要在 /plus/ 目录下创建一个名为 temp 的文件夹,并给予它足够的写入权限。
- 创建文件夹:通过FTP或文件管理器,在
/plus/目录下新建一个文件夹,命名为temp。 - 设置权限:将
temp文件夹的权限设置为755或777。777权限最保险,但存在一定安全风险,如果网站在Linux主机上,755通常就足够了。
最终效果
当你访问任何一个图集内容页时,会在分页区域看到一个“打包下载全部图片”的按钮,点击这个按钮,浏览器就会开始下载一个包含该图集所有图片的ZIP压缩包。
注意事项与扩展
- 安全性:上述代码已经做了基本的安全处理(检查
aid、限制本站域名下载),但对于高安全要求的网站,还可以进一步检查用户权限,比如只有登录用户才能下载等。 - 大图集处理:如果一个图集的图片非常多(例如几百张),或者图片体积非常大(例如高清原图),生成ZIP包的过程可能会比较耗时,并且会消耗较多服务器内存,这可能导致页面超时或服务器负载过高,对于这种情况,可以考虑:
- 限制单个图集的打包数量。
- 使用异步任务(如队列)在后台生成ZIP,然后通过邮件或站内信通知用户下载链接(这需要更复杂的开发)。
- 路径匹配:代码中的正则表达式
/\/uploads\/[^"|\']*\.(jpg|jpeg|gif|png|webp)/是根据织梦默认的图片上传路径/uploads/来匹配的,如果你的网站图片存放在其他目录(如/images/),请相应地修改正则表达式。 - 图片防盗链:如果你的网站开启了图片防盗链功能,
ZipArchive::addFile()方法在读取服务器本地文件时通常不受影响,但如果图片是通过URL远程获取的(代码中没有这样做),防盗链可能会导致图片无法被打包,本方案是直接读取服务器文件,所以没有这个问题。
通过以上步骤,你就可以成功地为织梦图集添加一个非常实用的“自动打包下载”功能了。
