惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LINUX DO - 热门话题
Stack Overflow Blog
Stack Overflow Blog
B
Blog
WordPress大学
WordPress大学
Project Zero
Project Zero
P
Palo Alto Networks Blog
阮一峰的网络日志
阮一峰的网络日志
博客园 - 司徒正美
有赞技术团队
有赞技术团队
S
SegmentFault 最新的问题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
小众软件
小众软件
T
Tailwind CSS Blog
Forbes - Security
Forbes - Security
F
Full Disclosure
SecWiki News
SecWiki News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Hacker News: Ask HN
Hacker News: Ask HN
C
Check Point Blog
Microsoft Security Blog
Microsoft Security Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
F
Fortinet All Blogs
Cisco Talos Blog
Cisco Talos Blog
G
Google Developers Blog
J
Java Code Geeks
Google DeepMind News
Google DeepMind News
人人都是产品经理
人人都是产品经理
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recorded Future
Recorded Future
O
OpenAI News
Spread Privacy
Spread Privacy
MongoDB | Blog
MongoDB | Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
C
Cybersecurity and Infrastructure Security Agency CISA
S
Securelist
V
Vulnerabilities – Threatpost
Y
Y Combinator Blog
IT之家
IT之家
U
Unit 42
腾讯CDC
S
Security Affairs
C
Cisco Blogs
Schneier on Security
Schneier on Security
The Last Watchdog
The Last Watchdog
B
Blog RSS Feed
宝玉的分享
宝玉的分享
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Security @ Cisco Blogs
Cyberwarzone
Cyberwarzone
T
The Blog of Author Tim Ferriss

兴起百年 - XQBN.com - 学习

小内存服务器大爆发:我是如何优化WordPress扛住上万PV的 我的定投日记:纳斯达克指数基金10个月收益16.33%的思考与展望 Typecho缩短链接插件提示错误Deprecated: unserialize(): Passing null to parameter #1 ($data) of type string is deprecated的解决方法 自部署去中心聊天项目 Matrix 服务器Debian12+宝塔面板+Docker安装Matrix免费开源聊天项目 ubuntu 22.04系统 如何将硬盘的inodes参数设置为最大值? ROE投资笔记:大道至简,如何寻找长期稳定高ROE的“宝藏股”? 巴菲特也推崇的选股心法:用好这“三层筛子”,半年收益可达80% 投资进阶必备技能:手把手教你高效查找与阅读公司研报 新能源基金暴涨118%!我的投资学习笔记:碳中和赛道还能追吗?
Typecho关键词链接插件提示错误 Warning: Undefined array key 2 in 的解决方法
作者: 兴起百年 · 2025-12-08 · via 兴起百年 - XQBN.com - 学习

Typecho网站了的服务器环境 Debian 12 + Nginx 1.28 + PHP8.2 + Mysql 8.4 + Typecho 1.3.0

网站主题使用Typecho-Butterfly

网站开启了以下插件 AutoSaveImage、Keywords、Paste Image、ShortLinks

关键词链接插件的作用:

Typecho关键词链接插件提示错误 Warning: Undefined array key 2 in 的解决方法

问题说明:

打开网站首页时,页面上有以下错误提示信息:

Warning: Undefined array key 2 in /www/wwwroot/xqbn.com/usr/plugins/Keywords/Plugin.php on line 105

我检查了这个关键词插件的文件代码如下:

<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
 * 为文中的指定关键词添加链接
 * 
 * @package Keywords
 * @author 羽中
 * @version 1.0.8
 * @dependence 13.12.12-*
 * @link http://www.yzmb.me/archives/net/keywords-for-typecho
 */
class Keywords_Plugin implements Typecho_Plugin_Interface
{
    /**
     * 激活插件方法,如果激活失败,直接抛出异常
     * 
     * @access public
     * @return void
     * @throws Typecho_Plugin_Exception
     */
    public static function activate()
    {
        Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx = array('Keywords_Plugin','kwparse');
        Typecho_Plugin::factory('Widget_Abstract_Contents')->excerptEx = array('Keywords_Plugin','kwparse');
    }

    /**
     * 禁用插件方法,如果禁用失败,直接抛出异常
     * 
     * @static
     * @access public
     * @return void
     * @throws Typecho_Plugin_Exception
     */
    public static function deactivate(){}

    /**
     * 获取插件配置面板
     * 
     * @access public
     * @param Typecho_Widget_Helper_Form $form 配置面板
     * @return void
     */
    public static function config(Typecho_Widget_Helper_Form $form)
    {
        $keywords = new Typecho_Widget_Helper_Form_Element_Textarea('keywords',NULL,'',_t('关键词链接'),_t('每行1组以"关键词<strong style="color:#467B96;">|</strong>(半角竖线)链接"形式填写, 可用第2个竖线追加参数: </br>
        <strong style="color:#467B96;">n</strong>代表nofollow标记, <strong style="color:#467B96;">e</strong>代表external nofollow标记, <strong style="color:#467B96;">b</strong>代表本窗口打开. 例: <br/>google<strong>|</strong>http://www.google.com<strong>|</strong>n 即此链接带nofollow(默认新窗口打开)'));
        $keywords->input->setAttribute('style','max-width:400px;height:150px;');
        $form->addInput($keywords);

        $autolink = new Typecho_Widget_Helper_Form_Element_Checkbox('autolink',array('catslink'=>_t('分类名称'),'tagslink'=>_t('标签名称')),NULL,_t('自动内链'),_t('将与分类/标签名相同的词替换为分类/标签页链接'));
        $form->addInput($autolink);

        $nofollow = new Typecho_Widget_Helper_Form_Element_Checkbox('nofollow',
        array(1=>_t('nofollow标记')),NULL,_t('内链设置'));
        $form->addInput($nofollow);

        $blank = new Typecho_Widget_Helper_Form_Element_Select('blank',
        array(0=>_t('本窗口打开'),1=>_t('新窗口打开')),0,'');
        $blank->input->setAttribute('style','position:absolute;bottom:11px;left:115px;');
        $blank->setAttribute('style','position:relative;');
        $form->addInput($blank);

        $limits = new Typecho_Widget_Helper_Form_Element_Text('limits',NULL,'1',_t('链接频次'),_t('文中有多个重复关键词时可指定替换为链接的次数'));
        $limits->input->setAttribute('style','width:40px;');
        $limits->addRule('required',_t('链接次数不能为空'));
        $form->addInput($limits->addRule('isInteger',_t('请填写整数数字')));

        $pagelinks = new Typecho_Widget_Helper_Form_Element_Radio('pagelinks',array(1=>_t('是'),0=>_t('否')),1,_t('页面使用'),_t('除文章外是否将替换链接效果作用于独立页面内容'));
        $form->addInput($pagelinks);
    }

    /**
     * 个人用户的配置面板
     * 
     * @access public
     * @param Typecho_Widget_Helper_Form $form
     * @return void
     */
    public static function personalConfig(Typecho_Widget_Helper_Form $form){}

    /**
     * 执行数据替换
     * 
     * @access public
     * @param string $content
     * @return string
     */
    public static function kwparse($content,$widget,$lastResult)
    {
        $content = empty($lastResult) ? $content : $lastResult;
        $keywords = self::keywords();

        if ($widget instanceof Widget_Archive && $keywords) {
            $settings = Helper::options()->plugin('Keywords');

            //关闭页面内容替换
            if ($widget->is('page') && !$settings->pagelinks) {
                return $content;
            }
            foreach ($keywords as $i=>$row) {
                $txt = trim($row['0']);
                if ($txt) {
                    $link = trim($row['1']);
                    $set = trim($row['2']);
                    $rel = '';
                    $open = '_blank';

                    //处理标记与打开方式
                     if ($set) {
                          if (false!==stripos($set,'e')) {
                               $rel = ' rel="external nofollow"';
                          } elseif (false!==stripos($set,'n')) {
                               $rel = ' rel="nofollow"';
                          }
                          $open = false!==stripos($set,'b') ? '_self' : $open;
                     }

                    $content = false!==strpos($content,$txt)
                        //正则排除参数和链接
                        ? preg_replace('/(?!<[^>]*)'.$txt.'(?![^<]*(>|<\/[a|sc]))/s'
                    ,'<a href="'.$link.'"'.$rel. 'target="'.$open.'" title="'.$txt.'">'.$txt.'</a>',$content,$settings->limits) : $content;
                }
            }
        }

        return $content;
    }

    /**
     * 输出关键词数据
     * 
     * @access private
     * @return array
     */
    private static function keywords()
    {
        $settings = Helper::options()->plugin('Keywords');
        $autolink = $settings->autolink;
        $kwarray = array();
        $keyword = trim(Typecho_Common::stripTags($settings->keywords));

        if (strpos($keyword,'|')) {
            //解析关键词数组
            $kwsets = array_filter(preg_split("/(\r|\n|\r\n)/",$keyword));
            foreach ($kwsets as $kwset) {
                $kwarray[] = explode('|',$kwset);
            }
        }

        if ($autolink) {
            $db = Typecho_Db::get();
            $nofollow = $settings->nofollow ? 'n' : '';
            $blank = $settings->blank ? '' : 'b';

            if (in_array('catslink',$autolink)) {
                $catselect = $db->select()->from('table.metas')->where('type = ?','category');
                $catdata = $db->fetchAll($catselect,array(Typecho_Widget::widget('Widget_Abstract_Metas'),'filter'));

                //并入分类链接
                $cats = array();
                foreach ($catdata as $cat) {
                    $cats[] = array($cat['name'],$cat['permalink'],$nofollow.$blank);
                }
                $kwarray = array_merge($kwarray,$cats);
            }

            if (in_array('tagslink',$autolink)) {
                $tagselect = $db->select()->from('table.metas')->where('type = ?','tag');
                $tagdata = $db->fetchAll($tagselect,array(Typecho_Widget::widget('Widget_Abstract_Metas'),'filter'));

                //并入标签链接
                if ($tagdata) {
                    $tags = array();
                    foreach ($tagdata as $tag) {
                        $tags[] = array($tag['name'],$tag['permalink'],$nofollow.$blank);
                    }
                    $kwarray = array_merge($kwarray,$tags);
                }
            }
        }

        if ($kwarray) {
            //优先处理长词
            usort($kwarray,array(new Keywords_Plugin,'lsort'));
        }

        return $kwarray;
    }

    /**
     * 按字符长短排序
     * 
     * @access private
     * @return integer
     */
    private static function lsort($a,$b) {
        return strlen($a['0'])<strlen($b['0']) ? 1 : -1;
    }

}

解决方法

  • 1、这个错误是因为 Keywords 插件在处理某些关键词行时,数组下标不存在。这是因为您在插件设置中可能配置了一些只有关键词和链接(没有第三个参数)的关键词行。

    在第105行,代码试图访问 $row['2'],但有些 $row 数组可能只有2个元素(比如只有关键词和链接,没有第三个参数)

修复方法

以下是修复后的 Plugin.php 文件代码,我已经为您添加了安全检查:

<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
 * 为文中的指定关键词添加链接
 * 
 * @package Keywords
 * @author 羽中
 * @version 1.0.8
 * @dependence 13.12.12-*
 * @link http://www.yzmb.me/archives/net/keywords-for-typecho
 */
class Keywords_Plugin implements Typecho_Plugin_Interface
{
    /**
     * 激活插件方法,如果激活失败,直接抛出异常
     * 
     * @access public
     * @return void
     * @throws Typecho_Plugin_Exception
     */
    public static function activate()
    {
        Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx = array('Keywords_Plugin','kwparse');
        Typecho_Plugin::factory('Widget_Abstract_Contents')->excerptEx = array('Keywords_Plugin','kwparse');
    }

    /**
     * 禁用插件方法,如果禁用失败,直接抛出异常
     * 
     * @static
     * @access public
     * @return void
     * @throws Typecho_Plugin_Exception
     */
    public static function deactivate(){}

    /**
     * 获取插件配置面板
     * 
     * @access public
     * @param Typecho_Widget_Helper_Form $form 配置面板
     * @return void
     */
    public static function config(Typecho_Widget_Helper_Form $form)
    {
        $keywords = new Typecho_Widget_Helper_Form_Element_Textarea('keywords',NULL,'',_t('关键词链接'),_t('每行1组以"关键词<strong style="color:#467B96;">|</strong>(半角竖线)链接"形式填写, 可用第2个竖线追加参数: </br>
        <strong style="color:#467B96;">n</strong>代表nofollow标记, <strong style="color:#467B96;">e</strong>代表external nofollow标记, <strong style="color:#467B96;">b</strong>代表本窗口打开. 例: <br/>google<strong>|</strong>http://www.google.com<strong>|</strong>n 即此链接带nofollow(默认新窗口打开)'));
        $keywords->input->setAttribute('style','max-width:400px;height:150px;');
        $form->addInput($keywords);

        $autolink = new Typecho_Widget_Helper_Form_Element_Checkbox('autolink',array('catslink'=>_t('分类名称'),'tagslink'=>_t('标签名称')),NULL,_t('自动内链'),_t('将与分类/标签名相同的词替换为分类/标签页链接'));
        $form->addInput($autolink);

        $nofollow = new Typecho_Widget_Helper_Form_Element_Checkbox('nofollow',
        array(1=>_t('nofollow标记')),NULL,_t('内链设置'));
        $form->addInput($nofollow);

        $blank = new Typecho_Widget_Helper_Form_Element_Select('blank',
        array(0=>_t('本窗口打开'),1=>_t('新窗口打开')),0,'');
        $blank->input->setAttribute('style','position:absolute;bottom:11px;left:115px;');
        $blank->setAttribute('style','position:relative;');
        $form->addInput($blank);

        $limits = new Typecho_Widget_Helper_Form_Element_Text('limits',NULL,'1',_t('链接频次'),_t('文中有多个重复关键词时可指定替换为链接的次数'));
        $limits->input->setAttribute('style','width:40px;');
        $limits->addRule('required',_t('链接次数不能为空'));
        $form->addInput($limits->addRule('isInteger',_t('请填写整数数字')));

        $pagelinks = new Typecho_Widget_Helper_Form_Element_Radio('pagelinks',array(1=>_t('是'),0=>_t('否')),1,_t('页面使用'),_t('除文章外是否将替换链接效果作用于独立页面内容'));
        $form->addInput($pagelinks);
    }

    /**
     * 个人用户的配置面板
     * 
     * @access public
     * @param Typecho_Widget_Helper_Form $form
     * @return void
     */
    public static function personalConfig(Typecho_Widget_Helper_Form $form){}

    /**
     * 执行数据替换
     * 
     * @access public
     * @param string $content
     * @return string
     */
    public static function kwparse($content,$widget,$lastResult)
    {
        $content = empty($lastResult) ? $content : $lastResult;
        $keywords = self::keywords();

        if ($widget instanceof Widget_Archive && $keywords) {
            $settings = Helper::options()->plugin('Keywords');

            //关闭页面内容替换
            if ($widget->is('page') && !$settings->pagelinks) {
                return $content;
            }
            foreach ($keywords as $i=>$row) {
                $txt = trim($row['0']);
                if ($txt) {
                    $link = trim($row['1']);
                    // 修复点:增加安全检查,防止数组下标2不存在
                    $set = isset($row['2']) ? trim($row['2']) : '';
                    $rel = '';
                    $open = '_blank';

                    //处理标记与打开方式
                    if ($set) {
                        if (false!==stripos($set,'e')) {
                            $rel = ' rel="external nofollow"';
                        } elseif (false!==stripos($set,'n')) {
                            $rel = ' rel="nofollow"';
                        }
                        $open = false!==stripos($set,'b') ? '_self' : $open;
                    }

                    $content = false!==strpos($content,$txt)
                        //正则排除参数和链接
                        ? preg_replace('/(?!<[^>]*)'.$txt.'(?![^<]*(>|<\/[a|sc]))/s'
                    ,'<a href="'.$link.'"'.$rel. 'target="'.$open.'" title="'.$txt.'">'.$txt.'</a>',$content,$settings->limits) : $content;
                }
            }
        }

        return $content;
    }

    /**
     * 输出关键词数据
     * 
     * @access private
     * @return array
     */
    private static function keywords()
    {
        $settings = Helper::options()->plugin('Keywords');
        $autolink = $settings->autolink;
        $kwarray = array();
        $keyword = trim(Typecho_Common::stripTags($settings->keywords));

        if (strpos($keyword,'|')) {
            //解析关键词数组
            $kwsets = array_filter(preg_split("/(\r|\n|\r\n)/",$keyword));
            foreach ($kwsets as $kwset) {
                $parts = explode('|',$kwset);
                // 确保数组有3个元素,不足则补空字符串
                for ($i = 0; $i < 3; $i++) {
                    if (!isset($parts[$i])) {
                        $parts[$i] = '';
                    }
                }
                $kwarray[] = $parts;
            }
        }

        if ($autolink) {
            $db = Typecho_Db::get();
            $nofollow = $settings->nofollow ? 'n' : '';
            $blank = $settings->blank ? '' : 'b';

            if (in_array('catslink',$autolink)) {
                $catselect = $db->select()->from('table.metas')->where('type = ?','category');
                $catdata = $db->fetchAll($catselect,array(Typecho_Widget::widget('Widget_Abstract_Metas'),'filter'));

                //并入分类链接
                $cats = array();
                foreach ($catdata as $cat) {
                    $cats[] = array($cat['name'],$cat['permalink'],$nofollow.$blank);
                }
                $kwarray = array_merge($kwarray,$cats);
            }

            if (in_array('tagslink',$autolink)) {
                $tagselect = $db->select()->from('table.metas')->where('type = ?','tag');
                $tagdata = $db->fetchAll($tagselect,array(Typecho_Widget::widget('Widget_Abstract_Metas'),'filter'));

                //并入标签链接
                if ($tagdata) {
                    $tags = array();
                    foreach ($tagdata as $tag) {
                        $tags[] = array($tag['name'],$tag['permalink'],$nofollow.$blank);
                    }
                    $kwarray = array_merge($kwarray,$tags);
                }
            }
        }

        if ($kwarray) {
            //优先处理长词
            usort($kwarray,array(new Keywords_Plugin,'lsort'));
        }

        return $kwarray;
    }

    /**
     * 按字符长短排序
     * 
     * @access private
     * @return integer
     */
    private static function lsort($a,$b) {
        return strlen($a['0'])<strlen($b['0']) ? 1 : -1;
    }

}

修复说明:

  1. 第105行问题修复(在 kwparse 方法中):

    • 原来的 $set = trim($row['2']); 修改为:
    • $set = isset($row['2']) ? trim($row['2']) : '';
    • 这样即使数组没有第三个元素,也不会报错
  2. 预防性修复(在 keywords 方法中):

    • 在解析关键词配置时,确保每个数组都有3个元素
    • 如果某个配置行只有2个部分(如 关键词|链接),会补上第三个空字符串元素