织梦图集生成自动打包,如何实现高效批量处理?

99ANYc3cd6
预计阅读时长 23 分钟
位置: 首页 织梦建站 正文

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

织梦图集生成自动打包
(图片来源网络,侵删)
  1. 前端打包(用户体验优化):用户在浏览图集时,可以一键将所有图片打包成一个 ZIP 压缩包下载,这是最常见的需求。
  2. 后端打包(管理效率优化):在后台发布或更新图集时,系统自动将图片打包,并可能附加到文章内容或进行其他处理,这个需求比较特殊,通常需要定制开发。

我将重点讲解第一种,也是最实用的前端自动打包功能,并提供详细的步骤和代码。


核心思路

实现这个功能主要分为三步:

  1. 修改图集内容页模板:在模板中添加一个“打包下载”的按钮或链接。
  2. 编写下载处理程序:创建一个 PHP 文件,该文件负责读取图集中的所有图片地址,将它们临时打包成 ZIP 文件,然后提供给用户下载。
  3. 安全与优化:确保下载过程安全,并处理好临时文件的清理。

详细操作步骤

第一步:修改图集内容页模板 (article_image.htm)

  1. 找到模板文件: 登录织梦后台,进入【模板】->【默认模板管理】->【内容页模板】,找到你当前使用的图集内容页模板,文件名通常是 article_image.htm

  2. 添加下载按钮: 在模板中你希望显示下载按钮的位置(图片轮播器的下方、图集描述的旁边等),添加如下代码:

    织梦图集生成自动打包
    (图片来源网络,侵删)
    <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)

  1. 找到并备份原文件: 在你的网站根目录下的 /plus/ 文件夹中,找到 download.php 文件。在修改之前,请务必先备份这个原始文件! 因为这个文件是织梦处理所有下载请求的核心文件。

  2. 修改 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('打包失败,临时文件未生成。');
        }
    }
  3. 代码逻辑解释

    • 安全检查:首先检查 $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 的文件夹,并给予它足够的写入权限。

  1. 创建文件夹:通过FTP或文件管理器,在 /plus/ 目录下新建一个文件夹,命名为 temp
  2. 设置权限:将 temp 文件夹的权限设置为 755777777 权限最保险,但存在一定安全风险,如果网站在Linux主机上,755 通常就足够了。

最终效果

当你访问任何一个图集内容页时,会在分页区域看到一个“打包下载全部图片”的按钮,点击这个按钮,浏览器就会开始下载一个包含该图集所有图片的ZIP压缩包。


注意事项与扩展

  1. 安全性:上述代码已经做了基本的安全处理(检查aid、限制本站域名下载),但对于高安全要求的网站,还可以进一步检查用户权限,比如只有登录用户才能下载等。
  2. 大图集处理:如果一个图集的图片非常多(例如几百张),或者图片体积非常大(例如高清原图),生成ZIP包的过程可能会比较耗时,并且会消耗较多服务器内存,这可能导致页面超时或服务器负载过高,对于这种情况,可以考虑:
    • 限制单个图集的打包数量。
    • 使用异步任务(如队列)在后台生成ZIP,然后通过邮件或站内信通知用户下载链接(这需要更复杂的开发)。
  3. 路径匹配:代码中的正则表达式 /\/uploads\/[^"|\']*\.(jpg|jpeg|gif|png|webp)/ 是根据织梦默认的图片上传路径 /uploads/ 来匹配的,如果你的网站图片存放在其他目录(如 /images/),请相应地修改正则表达式。
  4. 图片防盗链:如果你的网站开启了图片防盗链功能,ZipArchive::addFile() 方法在读取服务器本地文件时通常不受影响,但如果图片是通过URL远程获取的(代码中没有这样做),防盗链可能会导致图片无法被打包,本方案是直接读取服务器文件,所以没有这个问题。

通过以上步骤,你就可以成功地为织梦图集添加一个非常实用的“自动打包下载”功能了。

-- 展开阅读全文 --
头像
织梦模板是html吗
« 上一篇 03-21
c语言graphics.h
下一篇 » 03-21

相关文章

取消
微信二维码
支付宝二维码

目录[+]