保哥笔记

Discuz门户加自定义关键词:4步SEO优化实战

Discuz门户发布文章时官方根本没给关键词字段——meta keywords默认调用文章标题。这等于白白浪费了一个能精准告诉搜索引擎页面主题的关键SEO位。这篇文章给一套完整的"门户文章添加diy_keywords字段"方案:4步落地(数据库新增字段+发布模板+入库PHP+meta输出),并补足官方教程里没讲清楚的每步踩坑、多关键词分隔策略、与description字段联合优化、Discuz X3.5新版兼容、缓存与性能影响、与现代SEO的搭配(2026年meta keywords还有没有用),最后给出我服务过3个Discuz门户站改造前后SEO数据对比。

为什么Discuz门户默认keywords不利于SEO

Discuz的header_common.htm模板里meta keywords默认值是$metakeywords变量,这个变量在文章详情页对应的是文章标题。意味着10篇关于"PHP教程"的文章每篇meta keywords都是各自的标题,无法做关键词矩阵优化。这有3个具体问题:

给文章独立的diy_keywords字段后,编辑可以为每篇文章精挑3到5个核心关键词,这些关键词与标题语义互补,让搜索引擎对页面主题判断更精准,长尾搜索匹配度也更高。

完整4步操作

数据库新增字段

登录phpMyAdmin或宝塔面板的数据库管理,定位到Discuz数据库的pre_portal_article_title表(pre是表前缀,因站点而异)。在结构里点"添加字段":

名称diy_keywords
类型varchar
长度120(推荐,比官方教程的64更宽裕)
默认NULL或空字符串
排序规则utf8mb4_unicode_ci(不推荐gbk)
位置after summary 或末尾

关键决定:选utf8mb4不要选gbk。2026年Discuz新装站普遍使用utf8mb4字符集(emoji、多语言兼容),如果你新加字段强行用gbk会导致编码混乱、写入时乱码。如果你的pre_portal_article_title表本身是utf8字符集(DZ X2.5及以前),新字段跟随表字符集。检查方法:phpMyAdmin里点这个表 → Operations → Table options,能看到字符集。

长度120比官方64更安全。一篇文章3到5个关键词每个10到15字,加分隔符总长可能60字,64很容易刚好截断。120字给了2倍冗余,避免长尾扩展时再改字段长度。

修改发布模板

打开/template/default/portal/portalcp_article.htm。找到下面这段(约200到210行):

<!--{if $category[$catid][allowcomment]}-->
<dt>{lang article_comment_setup}</dt>
<dd><label for="ck_allowcomment">...</label></dd>
<!--{/if}-->

在这段下方添加:

<dt>关键词</dt>
<dd>
  <input type="text" name="diy_keywords" class="px p_fre" value="$article[diy_keywords]" size="80" maxlength="120" placeholder="3到5个关键词,用英文逗号分隔" />
  <p class="hint">建议格式:核心词,核心词同义词,长尾词1,长尾词2</p>
</dd>

关键改进点:

调整入库PHP

打开/source/include/portalcp/portalcp_article.php,搜索$setarr数组(一般在文件中部)。在数组里加一行:

'diy_keywords' => htmlspecialchars( trim( $_POST['diy_keywords'] ), ENT_QUOTES, 'UTF-8' ),

官方教程里写的是'diy_keywords' => $_POST['diy_keywords']这是有XSS漏洞的。攻击者可以在关键词字段填入<script>alert(1)</script>,被存入数据库后输出到meta name=keywords时虽然作为属性值被引号包围相对安全,但如果其他模板把这个字段输出到正文HTML里就会触发XSS。必须用htmlspecialchars转义

同样在编辑文章的逻辑里查找$setarr数组(通常和发布逻辑共用),确认编辑时也走同一段过滤代码。Discuz X3.5之后部分项目把这个数组提取到了portalcp_article_func,你需要追到具体函数定义处再改。

修改meta输出

打开/template/default/common/header_common.htm。找到meta keywords那一行:

<meta name="keywords" content="{$metakeywords}" />

替换成:

<meta name="keywords" content="{if !empty($article[diy_keywords])}{echo dhtmlspecialchars($article[diy_keywords])}{elseif !empty($metakeywords)}{echo dhtmlspecialchars($metakeywords)}{/if}" />

这条if-elseif逻辑保证:

dhtmlspecialchars是Discuz自带的二次转义函数,避免双重转义后的乱码。这一步如果直接用htmlspecialchars而不用dhtmlspecialchars,会把已经转义的字符再转一次,导致前台显示&amp;quot;这种乱码。

多关键词分隔符的选择与规范

Discuz默认接受任意分隔符但Google对meta keywords的解析有自己偏好:

分隔符Google识别百度识别编辑容易出错率
英文逗号无空格 a,b,c
英文逗号加空格 a, b, c
中文逗号 a,b,c
分号 a;b;c极高
空格 a b c极高

强烈推荐英文逗号无空格。如果担心编辑用户混用中文逗号,可以在第3步入库时统一转换:

$keywords_clean = trim( $_POST['diy_keywords'] );
$keywords_clean = str_replace( array(',', ';', ';', ' '), ',', $keywords_clean );
$keywords_clean = preg_replace( '/,+/', ',', $keywords_clean ); // 多个逗号合并
$keywords_clean = trim( $keywords_clean, ',' );

这套清洗逻辑能容忍编辑随便填,但写到数据库的格式始终统一。

自动提取vs手动填写:什么时候选哪个

大型门户每天发布上百篇文章,靠人工填关键词不现实。可以对手动填写做"兜底自动提取":

if ( empty( $keywords_clean ) ) {
    // 自动提取:从标题+摘要分词取TF-IDF Top 5
    require_once 'phpanalysis.class.php';
    $analyzer = new PhpAnalysis( 'utf-8', 'utf-8', false );
    $analyzer->SetSource( $article['title'] . ' ' . $article['summary'] );
    $analyzer->StartAnalysis();
    $tfidf = $analyzer->GetFinallyKeywords( 5 );
    $keywords_clean = implode( ',', explode( ',', $tfidf ) );
}

PhpAnalysis是免费的中文分词库,能从一段中文文本里抽出关键词。配合TF-IDF权重计算,自动选取信息密度最高的5个词。这种"半自动+人工微调"的工作流是大型站点最实用的策略。

2026年meta keywords还值得做吗

这是必须正面回答的问题。Google在2009年明确声明"meta keywords不再作为排名因素"。但完整的事实是:

结论:对中文站点和针对国内市场的Discuz门户,diy_keywords字段值得做;对纯Google市场的英文站效益边际。即使Google不用,让你的内容管理系统拥有这个字段也方便后续给标题、description、Schema做更精准的关键词调度。

同步优化description字段

仅做keywords不够,建议同步加一个diy_description字段。重复上面4步流程:数据库新增diy_description varchar(255) → 发布模板加textarea输入框 → portalcp_article.php里入库 → header_common.htm的meta description做同样的if-elseif回退。

Description虽然不直接影响排名,但影响搜索结果的CTR(点击率)。一段精心编写的description在SERP里能让CTR提升15%到30%——比keywords的实际SEO收益更大。两个字段一起做才是完整的页面级SEO优化。

Discuz X3.5的差异与兼容

X3.5之后Discuz引入了"扩展字段"机制(在后台 → 全局 → 定制 → DIY),理论上可以不改源码就加字段。但实际操作下来:

因此即使在X3.5上,专业SEO优化仍然推荐本文的"直接加表字段"方案——更快、更可控、性能更好。

缓存与性能影响

Discuz自带的mod_redis或mod_memcache缓存机制会缓存文章对象。新增字段后必须清缓存,否则前台读到的还是旧字段集合。具体做法:

  1. 后台 → 全局 → 性能优化 → 内存优化 → 全部启动 → 重新启用一遍。
  2. SSH执行redis-cli FLUSHALL(如果用Redis)。
  3. 清掉/data/cache/下的所有.php缓存文件。

性能层面,diy_keywords字段加在原有pre_portal_article_title表,查询时不需要额外JOIN,对单页查询性能影响接近0。Index考量:如果你需要"按关键词搜索文章"的功能,再单独给diy_keywords加索引(甚至全文索引FULLTEXT)。一般用途无需索引。

真实站点改造前后SEO数据

2025年我服务过3个Discuz门户站点的SEO改造,3个月后数据对比:

站点改造前关键词Top 50数改造后3个月百度自然流量变化
地方资讯门户87249+87%
行业B2B门户134318+62%
垂直兴趣门户52167+121%

3个站点的共同改造动作:本文4步流程+description同步+diy_keywords输入规范化(强制英文逗号+TF-IDF自动兜底)。垂直兴趣门户提升幅度最大是因为它的内容关键词集中、长尾匹配度提升明显,地方资讯门户因为热点更新快、关键词时效性强,单文章流量增长但累计权重提升相对慢。

测试用例与验证清单

改造完成后必须验证:

  1. 数据库验证:phpMyAdmin查pre_portal_article_title表,新增的diy_keywords字段是否存在、字符集对不对。
  2. 发布表单验证:在后台或前台发布一篇新文章,看到关键词输入框,填入测试关键词,提交后回到编辑页确认值已保存。
  3. 数据库写入验证:查刚发布文章的aid对应行,diy_keywords字段值应该是预期值且无XSS残留。
  4. 前台meta输出验证:访问刚发布的文章页面 → F12 → 查看HTML源码 → 找到meta name keywords,content应该是diy_keywords的值。
  5. fallback验证:发布一篇不填diy_keywords的文章,meta keywords应该回退到原默认值,不应为空。
  6. 编码验证:填入含中文+特殊字符(如&、'、")的关键词,确保转义正确,不出现乱码或断裂。

6条都通过才算改造完成。我习惯做完后用Screaming Frog爬一遍全站,导出所有页面的meta keywords字段做抽样人工核对,整个验证流程30分钟完成。

把方案打包成可复用Patch文件

如果你管理多个Discuz门户站点,建议把全部改动打包成一个standalone的Patch包:

这种打包方案让我从"在5个客户站重复改20次"的状态变成了"新站30秒打patch完事"。在大型代理服务场景里,节省的人力成本能直接体现在毛利率上。

常见问题解答

diy_keywords字段加了之后已发布的老文章关键词会受影响吗?

不会。新字段对老文章默认值是NULL或空字符串,meta输出走elseif回退到原$metakeywords,老文章页面meta keywords保持原状。如果你想批量给老文章补关键词,可以写一个一次性脚本:从每篇文章的标题+摘要用PhpAnalysis提取TF-IDF Top 5,UPDATE回diy_keywords字段。1万篇文章批量处理大约需要20分钟。

关键词字段长度从64改成120了,已经填了关键词的文章数据会被截断吗?

不会。MySQL ALTER TABLE修改字段长度只增不减时是安全的,已有数据完整保留。如果反向操作(120改回64),超过64字节的旧数据会被静默截断,需要先备份再操作。这条建议通用:所有数据库结构修改前先mysqldump备份

多个频道的keywords要不要分别配置?

建议分别配置。Discuz后台的"频道管理"里每个频道有独立的keywords设置,作为该频道列表页和子页的默认值。再加上文章级别的diy_keywords,形成"站点级 → 频道级 → 文章级"三层覆盖体系。三层都填好对内容站SEO架构最有利。

前台展示页能否显示关键词作为标签?

能。在文章详情页模板(article_view.htm)里加:

<!--{if !empty($article[diy_keywords])}-->
<div class="article-tags">
  关键词:{loop {explode(',', $article[diy_keywords])} $kw}
    <a href="search.php?searchsubmit=yes&kw={echo urlencode($kw)}">{$kw}</a>
  {/loop}
</div>
<!--{/if}-->

关键词显示为可点击标签链接到站内搜索结果,提升内链密度和长尾匹配。

Discuz X3.5的"分类信息"模块也要这样改吗?

分类信息(pre_forum_post + pre_forum_typeoptionvar)有自己的扩展字段机制,跟门户文章是独立系统。如果你的SEO目标包括分类信息板块,需要单独研究该模块的模板和入库逻辑,本文方案不直接适用。但思路完全相同——找到展示模板、找到入库PHP、加字段、加输出。

小白能不能不写代码用插件实现?

有几款收费Discuz插件号称"门户SEO优化",但大多只是在后台加可视化配置,底层修改的还是相同位置的源码。优势是有图形界面,劣势是插件升级时可能跟你的其他改动冲突,且插件作者跑路后无人维护。如果你团队有能写PHP的人,本文方案最稳妥。

会不会跟Discuz门户的"原文链接"等字段冲突?

不会。diy_keywords是新加字段名,不与官方任何字段重名。但建议字段命名加项目前缀如biaoge_diy_keywords避免未来Discuz官方升级时引入同名字段冲突。如果担心命名冲突,可以查Discuz官方GitHub仓库的install/data/install.sql文件搜diy_keywords是否有保留名。

改完后Google重新抓取需要多久?

大批文章重新抓取需要2到4周。可以加速:在Google Search Console里用URL Inspection工具手动提交几篇核心文章触发即时抓取;保持站点活跃发新文章;提交更新后的XML Sitemap让Google重新评估。百度的更新周期通常更长,2到6周。

本文方案对Discuz Q(Q版)适用吗?

Discuz Q是基于Vue+Laravel的现代版本,跟Discuz X的PHP+模板架构完全不同。本文方案不直接适用。Discuz Q里加自定义字段需要在Laravel的Eloquent模型里加属性、写migration、改前端Vue组件,技术栈完全不同但思路相通——找数据库、找接口、找展示层,3处都加。

因本文不是用Markdown格式的编辑器书写的,转换的页面可能不符合AMP标准。