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

推荐订阅源

Help Net Security
Help Net Security
S
SegmentFault 最新的问题
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
博客园 - 三生石上(FineUI控件)
月光博客
月光博客
C
Check Point Blog
M
MIT News - Artificial intelligence
GbyAI
GbyAI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
U
Unit 42
D
Docker
G
Google Developers Blog
云风的 BLOG
云风的 BLOG
H
Help Net Security
D
DataBreaches.Net
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog RSS Feed
Engineering at Meta
Engineering at Meta
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog
Cloudbric
Cloudbric
Blog — PlanetScale
Blog — PlanetScale
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Troy Hunt's Blog
N
News | PayPal Newsroom
V2EX - 技术
V2EX - 技术
H
Heimdal Security Blog
S
Security @ Cisco Blogs
V
Visual Studio Blog
The Last Watchdog
The Last Watchdog
博客园 - Franky
大猫的无限游戏
大猫的无限游戏
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Webroot Blog
Webroot Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
C
Cyber Attacks, Cyber Crime and Cyber Security
Last Week in AI
Last Week in AI
爱范儿
爱范儿
博客园 - 聂微东
S
Securelist
小众软件
小众软件
酷 壳 – CoolShell
酷 壳 – CoolShell
Cisco Talos Blog
Cisco Talos Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
CXSECURITY Database RSS Feed - CXSecurity.com
V
Vulnerabilities – Threatpost
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
O
OpenAI News
Apple Machine Learning Research
Apple Machine Learning Research

兴起百年 - XQBN.com - typecho

Typecho缩短链接插件提示错误Deprecated: unserialize(): Passing null to parameter #1 ($data) of type string is deprecated的解决方法
Typecho关键词链接插件提示错误 Warning: Undefined array key 2 in 的解决方法
作者: 兴起百年 · 2025-12-08 · via 兴起百年 - XQBN.com - typecho

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个部分(如 关键词|链接),会补上第三个空字符串元素