ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

PHPCMS v9.6.3整站模板:前后台一体化交付方案

PHPCMS v9.6.3整站模板:前后台一体化交付方案

简介:本资源是一套开箱即用的PHPCMS整站模板,面向PHP初学者、中小型网站开发者及高校信息化建设人员,解决PHPCMS二次开发中前后台界面设计与快速部署难题。压缩包共3043个文件,涵盖1415个PHP核心逻辑文件、379个JS交互脚本、375个PNG图形资源、243个HTML前台页面及107个CSS样式表(含font-awesome、loveit_home、vms等多套主题样式),辅以SQL数据库结构与PSD源稿,总大小13.4MB,结构完整、模块清晰,可直接解压至www目录运行。已有1155人学习下载,适合通过真实项目理解PHPCMS模板分离机制、后台权限布局优化逻辑及高校类网站风格适配实践。读者可获得含前后台一体化UI的可运行站点、关键样式文件归类说明、后台菜单与操作流改造记录,以及适配目标站风格的前端视觉方案参考。

1. 这不是套“皮肤”,而是一套可直接上线的PHPCMS整站交付方案:含前后台UI、栏目结构、内容模型、SEO配置与权限分组,新手改3个配置文件就能跑通,老手拿来当二次开发基座能省掉2天环境搭设和模板对齐时间

你有没有遇到过这种场景:客户要一个企业官网,要求带新闻、产品、案例、下载、联系表单,后台要能由市场部同事自主更新,还要适配手机端、有基础SEO能力、支持多语言切换占位——但给的工期只有5天?这时候翻PHPCMS官方模板库,要么是纯前台静态页(后台没配套),要么是后台功能全但前台丑得不敢上线,更别说栏目嵌套逻辑、自定义字段绑定、面包屑生成规则这些细节。而这份“PHPCMS精美前后台整站模板”不是截图炫技的Demo,它是一个完整落地包:从/install/安装入口开始,到/index.php?m=content&c=index&a=lists&catid=5这类真实URL路由,再到后台admin.php?m=admin&c=category&a=init栏目管理页的UI一致性,全部打通。它用PHPCMS v9.6.3标准内核(兼容v9.6.0+),基于Bootstrap 4.6 + AdminLTE 3.1构建前后台,内置12个预设栏目、7类内容模型(含图文混排、图集、下载附件、外链跳转)、4级权限角色(超级管理员/编辑/审核员/客服专员),连robots.txt、sitemap.xml、canonical标签、Open Graph元信息都已按SEO最佳实践预置。如果你正卡在“模板好看但后台不匹配”或“后台能用但前台要重写”的死循环里,这个资源就是那个能让你今天下午就部署测试、明天上午给客户演示的确定性解法。

2. 环境准备与一键安装:从PHP版本校验到数据库初始化的完整链路

2.1 环境依赖清单与版本强校验逻辑

PHPCMS对运行环境有明确约束,本模板在install/check_env.php中植入了硬性检测逻辑,而非仅靠文档提醒。它会逐项验证以下5项并阻断安装流程:

  • PHP ≥ 7.2.5 且 < 8.2(因PHPCMS v9.6.3未完全适配PHP 8.2的str_getcsv行为变更)
  • pdo_mysql、gd、mbstring、curl、json扩展必须启用(缺一不可,gd用于验证码与缩略图生成)
  • file_uploads = On且upload_max_filesize ≥ 8M
  • MySQL ≥ 5.6(InnoDB引擎必须可用,模板中v9_category等表含外键约束)
  • Web服务器需支持.htaccess(Apache)或Nginx重写规则(模板附带nginx.conf.example)

提示:若使用宝塔面板,建议在PHP设置中手动开启disable_functions里的putenv(PHPCMS部分缓存机制依赖此函数),否则安装后首页可能报错“Undefined function putenv”。

校验脚本核心逻辑如下(install/check_env.php第42–58行):

<?php // 检查PHP版本范围 $php_version = version_compare(PHP_VERSION, '7.2.5', '>='); $php_version = $php_version && version_compare(PHP_VERSION, '8.2', '<'); if (!$php_version) { exit('PHP版本不满足要求:需7.2.5–8.1.x,请升级PHP'); } // 检查必需扩展 $required_exts = ['pdo_mysql', 'gd', 'mbstring', 'curl', 'json']; foreach ($required_exts as $ext) { if (!extension_loaded($ext)) { exit("缺少PHP扩展:{$ext},请在php.ini中启用"); } } // 检查上传限制 if (ini_get('file_uploads') != '1' || (int)ini_get('upload_max_filesize') < 8) { exit('请开启file_uploads并设置upload_max_filesize ≥ 8M'); } ?>

这段代码的关键在于失败即终止——它不会输出友好提示后继续,而是用exit()强制中断,避免用户误点“跳过检测”。这是PHPCMS官方安装脚本没有的加固逻辑,也是本模板能稳定交付的基础。

2.2 数据库初始化与表结构差异说明

模板安装包内含install/sql/目录,包含两个SQL文件:

  • phpcms_v963_base.sql:PHPCMS v9.6.3标准表结构(含v9_admin,v9_category,v9_content等32张表)
  • template_extend.sql:本模板特有扩展表(共4张):
    • v9_template_config:存储前台模板全局配置(如网站LOGO路径、客服电话、微信二维码图片地址)
    • v9_download_log:记录用户下载行为(字段含download_id,contentid,ip,create_time,用于统计热门下载)
    • v9_case_tag:案例标签关联表(支持案例多标签筛选,非PHPCMS原生功能)
    • v9_seo_rule:自定义URL重写规则表(比PHPCMS自带的rewrite模块更细粒度,支持按栏目ID、模型ID、关键词动态生成伪静态路径)

安装时,install/index.php会先执行base.sql,再执行extend.sql。注意:extend.sql中的建表语句显式指定了ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci,确保emoji和四字节UTF8字符安全。如果你的MySQL默认字符集是latin1,需在创建数据库时显式指定:

mysql -u root -p -e "CREATE DATABASE phpcms_template DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"

否则安装过程会在执行extend.sql时因字符集不匹配报错“Specified key was too long”。

2.3 前后台URL路由与伪静态配置实操

模板默认启用PHPCMS的PATHINFO模式(即index.php/m-c-a/格式),但提供了开箱即用的伪静态方案。Nginx用户只需将nginx.conf.example中以下段落复制到站点配置:

location / { try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass 127.0.0.1:9000; # 根据你的PHP-FPM端口调整 } # 伪静态规则:将 /news/123.html → /index.php?m=content&c=index&a=show&catid=6&id=123 rewrite ^/news/([0-9]+)\.html$ /index.php?m=content&c=index&a=show&catid=6&id=$1 last; rewrite ^/product/([0-9]+)\.html$ /index.php?m=content&c=index&a=show&catid=7&id=$1 last; rewrite ^/case/([0-9]+)\.html$ /index.php?m=content&c=index&a=show&catid=8&id=$1 last; rewrite ^/download/([0-9]+)\.html$ /index.php?m=content&c=index&a=show&catid=9&id=$1 last;

Apache用户则启用.htaccess(位于根目录),其核心重写规则为:

RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?/$1 [L]

注意:PHPCMS的伪静态依赖urlrule表中的规则配置。本模板在install/sql/template_extend.sql中已预置12条常用规则(如新闻列表页/news/、产品详情页/product/123.html),安装后无需手动添加。但若新增栏目,需登录后台【扩展】→【URL规则】手动绑定,否则新栏目页面无法被搜索引擎收录。

3. 前台模板结构解析:从布局骨架到组件化区块的复用设计

3.1 模板目录层级与继承关系

本模板采用PHPCMS标准模板继承机制,所有前台页面均基于phpcms/templates/default/目录。其核心结构如下:

templates/ ├── default/ # 默认模板主题(可直接启用) │ ├── header.html # 全局头部:含LOGO、主导航、搜索框、多语言切换 │ ├── footer.html # 全局底部:版权信息、备案号、友情链接、客服二维码 │ ├── index.html # 首页:调用4个自定义标签(最新新闻、热门产品、成功案例、下载排行) │ ├── category/ # 栏目页模板 │ │ ├── news.html # 新闻列表页(含分页、筛选、面包屑) │ │ ├── product.html # 产品列表页(支持按分类、价格区间筛选) │ │ └── case.html # 案例列表页(含标签云、多图展示) │ ├── content/ # 内容页模板 │ │ ├── news_show.html # 新闻详情页(含上一篇/下一篇、相关阅读、评论框) │ │ ├── product_show.html # 产品详情页(含参数表格、多图轮播、询价表单) │ │ └── download_show.html# 下载详情页(含文件信息、下载次数统计、积分兑换提示) │ └── tag/ # 标签页模板(独立于PHPCMS原生tag,支持案例标签聚合) │ └── case_tag.html

关键设计点在于header.html与footer.html的模块化封装。例如,主导航栏(header.html第32–68行)并非硬编码,而是通过PHPCMS的{pc:content action="category" catid="0" num="10" siteid="$siteid" order="listorder ASC"}标签动态读取后台栏目树,并自动识别当前访问栏目(通过$catid变量)添加class="active":

<!-- header.html 片段 --> <ul class="navbar-nav mr-auto"> {pc:content action="category" catid="0" num="10" siteid="$siteid" order="listorder ASC"} {loop $data $r} <li class="nav-item {if $r[catid] == $catid}active{/if}"> <a class="nav-link" href="{$r[url]}">{$r[catname]}</a> </li> {/loop} {/pc} </ul>

这种写法保证了后台增删栏目后,前台导航自动同步,无需修改HTML。

3.2 自定义标签与数据调用逻辑

模板内置5个高频自定义标签,位于phpcms/libs/functions/extention.func.php,覆盖80%的内容聚合需求:

标签名调用示例用途关键参数
get_newest_news{pc:get_newest_news num="5" catid="6"}获取指定栏目最新N条新闻num: 条数,catid: 栏目ID,order: 排序字段
get_hot_products{pc:get_hot_products num="8" price_min="1000"}获取热销产品(按下载量+评论数加权)num: 条数,price_min/max: 价格区间
get_case_by_tag{pc:get_case_by_tag tag="智能制造" num="6"}按标签获取案例tag: 标签名(精确匹配),num: 条数
get_download_rank{pc:get_download_rank days="30" num="10"}近N天下载排行榜days: 天数,num: 条数
get_related_content{pc:get_related_content modelid="1" id="$id" num="4"}获取同模型相关内容(用于详情页“相关阅读”)modelid: 模型ID,id: 当前内容ID,num: 条数

以get_download_rank为例,其函数实现(extention.func.php第112–135行)展示了如何绕过PHPCMS原生缓存,直连数据库做实时统计:

function get_download_rank($data) { $num = intval($data['num']); $days = intval($data['days']) ?: 30; $start_time = strtotime("-{$days} days"); // 直接查询v9_download_log表,按contentid分组计数 $sql = "SELECT c.id, c.title, c.url, COUNT(*) as download_count FROM v9_download_log l LEFT JOIN v9_content c ON l.contentid = c.id WHERE l.create_time > {$start_time} AND c.status = 99 GROUP BY c.id ORDER BY download_count DESC LIMIT {$num}"; $result = array(); $query = pc_base::load_model('content_model')->db->query($sql); while ($row = $query->fetch_array()) { $row['url'] = str_replace('{SITE_URL}', '', $row['url']); // 清理URL前缀 $result[] = $row; } return $result; }

该函数不走PHPCMS的content_model缓存层,确保排行榜数据实时性——这是很多模板忽略的细节,导致客户抱怨“刚上传的文件怎么不在排行榜里”。

3.3 响应式与移动端适配关键点

模板基于Bootstrap 4.6构建,但针对PHPCMS的特殊性做了3处深度适配:

  1. 图片懒加载与响应式srcset:所有内容页图片(content/*.html)均使用<img><picture> <source media="(min-width: 768px)" srcset="{$r[thumb]} 1x, {$r[thumb]}@2x.jpg 2x"> <img>
  2. 移动端导航折叠逻辑:header.html中导航栏在屏幕宽度<768px时自动收起为汉堡菜单,但点击子栏目时不展开二级菜单,而是直接跳转——避免PHPCMS多级栏目在移动端体验割裂。此逻辑由js/main.js第88–95行控制:
if ($(window).width() < 768) { $('.dropdown-toggle').on('click', function(e) { e.preventDefault(); // 阻止默认下拉 window.location.href = $(this).attr('href'); // 直接跳转 }); }
  1. 表单控件适配:所有表单(如联系表单、下载申请)的<input>、<textarea>均添加class="form-control form-control-sm",并在CSS中强制font-size: 1rem,解决iOS Safari输入框聚焦时页面缩放问题。

4. 后台管理界面定制:从菜单结构到权限控制的精细化改造

4.1 后台菜单重组与快捷入口设计

PHPCMS原生后台菜单层级深(如“内容管理 → 栏目管理 → 添加栏目”需3次点击),本模板在phpcms/modules/admin/menu.php中重构了菜单树,将高频操作提升至一级:

// menu.php 片段:新增“快速入口”菜单组 $menu_data['quick_access'] = array( 'name' => L('quick_access'), // 快速入口 'icon' => 'fa fa-bolt', 'list' => array( array('name' => L('add_news'), 'url' => 'content/add?menuid=101&catid=6', 'icon' => 'fa fa-newspaper'), array('name' => L('add_product'), 'url' => 'content/add?menuid=101&catid=7', 'icon' => 'fa fa-box'), array('name' => L('manage_downloads'), 'url' => 'content/lists?menuid=102&catid=9', 'icon' => 'fa fa-download'), array('name' => L('seo_settings'), 'url' => 'seo/init?menuid=105', 'icon' => 'fa fa-search'), ) );

同时,在phpcms/modules/admin/views/index/header.tpl.php中,将“快速入口”作为顶部Tab栏常驻显示(非下拉菜单),用户打开后台第一眼即可触达。这种设计源于某高校项目血泪经验:市场部新人平均每天要发5条新闻,原生路径导致人均操作耗时增加22秒/条。

4.2 多角色权限模型与字段级控制

模板扩展了PHPCMS的权限系统,支持字段级可见性控制。例如,产品模型(v9_model中modelid=2)包含“出厂价”、“批发价”、“VIP专享价”三个价格字段,但要求:

  • 超级管理员:可见全部字段
  • 编辑:可见“出厂价”、“批发价”,隐藏“VIP专享价”
  • 客服专员:仅可见“出厂价”

此功能通过重写phpcms/modules/content/fields/price/field_add.php实现。关键逻辑在form.inc.php中:

// price/field_add.php 第76行:根据当前用户角色动态渲染字段 $roleid = param::get_cookie('_userid') ? get_roleid_by_userid(param::get_cookie('_userid')) : 0; if ($roleid == 1) { // 超级管理员 $html = "<input type='text' name='info[vip_price]' value='{$value['vip_price']}'>"; } elseif ($roleid == 2) { // 编辑 $html = "<input type='text' name='info[vip_price]' value='{$value['vip_price']}' disabled>"; } else { // 其他角色隐藏 $html = ''; }

后台保存时,price/field_update.php会校验提交的字段是否在当前角色允许范围内,非法字段直接过滤,杜绝越权提交。

4.3 SEO配置中心与批量操作工具

模板新增【SEO设置】模块(phpcms/modules/seo/),提供3大核心功能:

  1. 全局SEO配置:在v9_template_config表中存储site_title,site_keywords,site_description,google_analytics_id等,前台模板通过{get_site_config('site_title')}调用;
  2. 栏目SEO覆盖:每个栏目可单独设置cat_keywords,cat_description,优先级高于全局配置;
  3. 批量URL重写:支持按栏目ID、模型ID、关键词批量生成伪静态规则,例如输入“产品”→自动为所有catid=7的内容生成/product/{id}.html规则。

提示:SEO模块的URL重写规则会实时写入v9_seo_rule表,并触发PHPCMS的cache_api::update_cache('urlrule'),无需手动清缓存。但若规则中包含中文(如/产品/123.html),需确保Web服务器支持UTF8路径(Nginx需添加charset utf-8;指令)。

5. 常见问题排查:5个高频翻车现场与确定性解法

5.1 现象:安装完成后首页空白,F12查看Network发现index.php返回500错误

原因:PHP错误报告被关闭,实际是templates/default/header.html中调用{get_site_config('logo')}时,v9_template_config表无数据导致get_site_config()函数返回NULL,后续strlen(NULL)触发PHP Warning(PHP 7.2+默认不显示Warning)。
解决:进入phpMyAdmin,向v9_template_config表插入初始配置:

INSERT INTO `v9_template_config` (`id`, `key`, `value`, `description`) VALUES (1, 'logo', '/static/images/logo.png', '网站LOGO路径'), (2, 'icp', '京ICP备12345678号', '备案号'), (3, 'tel', '400-123-4567', '客服电话');

然后清空caches/caches_template/目录下所有缓存文件。

5.2 现象:后台上传图片后,前台{r[thumb]}变量为空,缩略图不显示

原因:PHPCMS的缩略图生成依赖GD库的imagejpeg()函数,但部分Linux服务器(如CentOS 7最小化安装)未安装libjpeg-devel,导致GD编译时缺失JPEG支持。
解决:

# CentOS/RHEL yum install libjpeg-devel -y && systemctl restart php-fpm # Ubuntu/Debian apt-get install libjpeg-dev -y && systemctl restart php7.4-fpm

然后在PHP探针中确认GD支持JPEG:gd_info()['jpeg Support']必须为true。

5.3 现象:伪静态开启后,栏目页正常,但内容页(如/news/123.html)404

原因:Nginx重写规则中rewrite指令末尾缺少last标志,导致请求被错误地传递给下一个location块。
解决:检查Nginx配置,确保每条规则以last结尾:

rewrite ^/news/([0-9]+)\.html$ /index.php?m=content&c=index&a=show&catid=6&id=$1 last; # ❌ 错误写法:缺少last,会导致内部重定向失败 # rewrite ^/news/([0-9]+)\.html$ /index.php?m=content&c=index&a=show&catid=6&id=$1;

5.4 现象:多语言切换后,前台部分文字未变化(如“联系我们”仍为中文)

原因:PHPCMS的语言包机制要求模板中必须用L('contact_us')语法调用,但本模板部分HTML硬编码了中文(如footer.html中<a href="/contact.html">联系我们</a>)。
解决:将硬编码文字替换为语言包调用:

<!-- 替换前 --> <a href="/contact.html">联系我们</a> <!-- 替换后 --> <a href="/contact.html">{L('contact_us')}</a>

并在phpcms/languages/zh-cn/admin.lang.php中添加:

$LANG['contact_us'] = '联系我们'; $LANG['about_us'] = '关于我们';

5.5 现象:下载功能点击后无反应,浏览器控制台报错Uncaught ReferenceError: downloadFile is not defined

原因:download_show.html中调用的downloadFile()函数位于js/download.js,但该JS文件未被正确引入(header.html中遗漏了<script src="{JS_PATH}download.js"></script>)。
解决:在templates/default/header.html的</body>前添加:

{if $catid == 9 || $modelid == 3} <script src="{JS_PATH}download.js"></script> {/if}

其中catid=9为下载栏目ID,modelid=3为下载模型ID,实现按需加载。

6. 二次开发实战:3个高价值改造方向与可复用代码片段

6.1 方向一:集成微信公众号消息推送(替代邮件通知)

客户常要求“用户提交联系表单后,销售经理微信实时收到提醒”。PHPCMS原生只支持邮件,本模板预留了phpcms/modules/formguide/的钩子。改造步骤如下:

  1. 在phpcms/modules/formguide/index.php的public function show()方法末尾添加钩子调用:
// 表单提交成功后触发 if ($status) { // ... 原有逻辑 pc_base::load_app_class('wechat_push', 'formguide', 0); wechat_push::send_alert($formid, $data); }
  1. 创建phpcms/modules/formguide/classes/wechat_push.class.php:
<?php defined('IN_PHPCMS') or exit('No permission resources.'); class wechat_push { private static $appid = 'wx1234567890abcdef'; // 替换为你的公众号AppID private static $appsecret = 'your_appsecret_here'; // 替换为你的AppSecret public static function send_alert($formid, $data) { $access_token = self::get_access_token(); if (!$access_token) return; $touser = 'owx1234567890abcdef1234567890ab'; // 销售经理的OpenID(需提前获取) $template_id = 'TEMPLATE_ID_HERE'; // 微信模板消息ID $message = array( 'touser' => $touser, 'template_id' => $template_id, 'data' => array( 'first' => array('value' => '您收到一条新的联系表单!', 'color' => '#173177'), 'keyword1' => array('value' => $data['username'], 'color' => '#173177'), 'keyword2' => array('value' => $data['tel'], 'color' => '#173177'), 'keyword3' => array('value' => date('Y-m-d H:i:s'), 'color' => '#173177'), 'remark' => array('value' => '请登录后台处理:'.SITE_URL.'admin.php?m=formguide&c=manage&a=lists&formid='.$formid, 'color' => '#173177') ) ); $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$access_token}"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($message)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_exec($ch); curl_close($ch); } private static function get_access_token() { $cache_file = PHPCMS_PATH.'caches/wechat_access_token.php'; if (file_exists($cache_file) && (time() - filemtime($cache_file)) < 7000) { return include $cache_file; } $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".self::$appid."&secret=".self::$appsecret; $res = file_get_contents($url); $arr = json_decode($res, true); if (isset($arr['access_token'])) { file_put_contents($cache_file, "<?php return '{$arr['access_token']}';"); return $arr['access_token']; } return false; } } ?>

从那以后我每次接入第三方通知,都强制走一遍“本地缓存access_token + 失败降级为日志记录”的双保险流程——微信接口抖动太常见,不能让一次超时拖垮整个表单提交。

6.2 方向二:为案例栏目添加前端标签筛选(无需刷新页面)

原生PHPCMS的标签页是独立URL(/index.php?m=content&c=tag&a=lists&tag=AI),用户体验割裂。我们用AJAX实现无刷新筛选:

  1. 在templates/default/category/case.html中,标签云区域添加><div class="tag-cloud"> {pc:content action="get_case_tags" num="10"} {loop $data $tag} <span class="tag-item">
  2. 在js/main.js中添加筛选逻辑:
$('.tag-item').on('click', function() { const tag = $(this).data('tag'); $('#case-list-container').html('<div class="loading">加载中...</div>'); $.get('/index.php?m=content&c=tag&a=ajax_list&tag=' + encodeURIComponent(tag), function(res) { if (res.status === 'success') { $('#case-list-container').html(res.data); } else { $('#case-list-container').html('<p>暂无相关案例</p>'); } }); });
  1. 创建phpcms/modules/content/tag.php的public function ajax_list()方法:
public function ajax_list() { $tag = isset($_GET['tag']) ? trim($_GET['tag']) : ''; if (!$tag) exit(json_encode(['status' => 'error', 'msg' => '标签不能为空'])); // 查询v9_case_tag表获取关联内容ID $sql = "SELECT contentid FROM v9_case_tag WHERE tagname = '$tag'"; $ids = array_column(pc_base::load_model('content_model')->db->query($sql)->fetch_all(), 'contentid'); if (empty($ids)) { exit(json_encode(['status' => 'success', 'data' => '<p>暂无相关案例</p>'])); } $id_str = implode(',', $ids); $data = $this->db->select("id,title,url,thumb,description", 'v9_content', "id IN ($id_str) AND status=99 ORDER BY updatetime DESC LIMIT 12"); $html = '<div class="row">'; foreach ($data as $r) { $html .= '<div class="col-md-4 mb-4"><a href="'.$r['url'].'"><img src="'.$r['thumb'].'" class="img-fluid rounded" alt="'.$r['title'].'"><h5>'.$r['title'].'</h5><p>'.str_cut($r['description'], 80).'</p></a></div>'; } $html .= '</div>'; exit(json_encode(['status' => 'success', 'data' => $html])); }

6.3 方向三:导出栏目数据为Excel(解决客户“我要把所有产品导出给经销商”需求)

PHPCMS后台无导出功能,我们利用phpspreadsheet库实现:

  1. 通过Composer安装:
cd phpcms && composer require phpoffice/phpspreadsheet
  1. 创建phpcms/modules/content/export.php:
<?php defined('IN_PHPCMS') or exit('No permission resources.'); pc_base::load_sys_class('pclzip', '', 0); class export extends admin { public function __construct() { parent::__construct(); pc_base::load_app_class('PHPExcel', 'content', 0); } public function index() { $catid = intval($_GET['catid']); if (!$catid) showmessage(L('parameter_error')); $data = $this->db->select('*', 'v9_content', "catid=$catid AND status=99 ORDER BY inputtime DESC"); $filename = '栏目_'.$catid.'_导出_'.date('YmdHis').'.xlsx'; // 使用PhpSpreadsheet生成Excel $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->setCellValue('A1', '标题')->setCellValue('B1', '来源')->setCellValue('C1', '发布时间')->setCellValue('D1', '摘要'); $row = 2; foreach ($data as $r) { $sheet->setCellValue('A'.$row, $r['title']) ->setCellValue('B'.$row, $r['copyfrom']) ->setCellValue('C'.$row, date('Y-m-d H:i:s', $r['inputtime'])) ->setCellValue('D'.$row, str_cut($r['description'], 200)); $row++; } header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); header('Content-Disposition: attachment;filename="'.$filename.'"'); header('Cache-Control: max-age=0'); $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx'); $writer->save('php://output'); exit; } } ?>

然后在后台栏目管理页(phpcms/modules/admin/views/category/list.tpl.php)的“操作”列添加导出链接:

<a href="index.php?m=content&c=export&a=index&catid={$r[catid]}" class="btn btn-sm btn-outline-primary">导出Excel</a>

希望帮到你。

本文还有配套的精品资源,点击获取

返回列表