<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="/wp-content/plugins/rss-beauty/pink.xsl"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PHP Archives - obaby 𝐢‍𝐧⃝ void</title>
	<atom:link href="https://zhongxiaojie.cn/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>https://oba.by/tag/php/</link>
	<description>程序媛 / 独立开发者 / 智商不稳定的女神经</description>
	<lastBuildDate>Sun, 15 Mar 2026 04:07:00 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://zhongxiaojie.cn/wp-content/uploads/2026/01/uugai.com-166111691272754-100x100.png</url>
	<title>PHP Archives - obaby 𝐢‍𝐧⃝ void</title>
	<link>https://oba.by/tag/php/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>开源项目目录📇</title>
		<link>https://zhongxiaojie.cn/2026/03/593/</link>
					<comments>https://zhongxiaojie.cn/2026/03/593/#comments</comments>
		
		<dc:creator><![CDATA[obaby]]></dc:creator>
		<pubDate>Sat, 14 Mar 2026 08:14:31 +0000</pubDate>
				<category><![CDATA[程序媛]]></category>
		<category><![CDATA[gitee]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[WP]]></category>
		<category><![CDATA[微信]]></category>
		<category><![CDATA[插件]]></category>
		<guid isPermaLink="false">https://zhongxiaojie.cn/?p=593</guid>

					<description><![CDATA[部分开源项目源码。 PHP8 探针项目（包含WP插件） 专业的服务器监控和管理工具，提供实时系统监控、性能测试 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="https://zhongxiaojie.cn/wp-content/uploads/2026/03/58603a31.jpg" data-lbwps-width="2127" data-lbwps-height="1080" data-lbwps-srcsmall="https://zhongxiaojie.cn/wp-content/uploads/2026/03/58603a31-665x338.jpg" data-lightbox="gal[593]"><img fetchpriority="high" decoding="async" class="alignnone size-full wp-image-597" src="https://zhongxiaojie.cn/wp-content/uploads/2026/03/58603a31.jpg" alt="" width="2127" height="1080" srcset="https://zhongxiaojie.cn/wp-content/uploads/2026/03/58603a31.jpg?v=1773476059 2127w, https://zhongxiaojie.cn/wp-content/uploads/2026/03/58603a31-300x152.jpg?v=1773476059 300w, https://zhongxiaojie.cn/wp-content/uploads/2026/03/58603a31-1024x520.jpg?v=1773476059 1024w, https://zhongxiaojie.cn/wp-content/uploads/2026/03/58603a31-150x76.jpg?v=1773476059 150w, https://zhongxiaojie.cn/wp-content/uploads/2026/03/58603a31-768x390.jpg?v=1773476059 768w, https://zhongxiaojie.cn/wp-content/uploads/2026/03/58603a31-1536x780.jpg?v=1773476059 1536w, https://zhongxiaojie.cn/wp-content/uploads/2026/03/58603a31-2048x1040.jpg?v=1773476059 2048w, https://zhongxiaojie.cn/wp-content/uploads/2026/03/58603a31-665x338.jpg?v=1773476059 665w, https://zhongxiaojie.cn/wp-content/uploads/2026/03/58603a31-512x260.jpg?v=1773476059 512w" sizes="(max-width: 2127px) 100vw, 2127px" /></a></p>
<p>部分开源项目源码。</p>
<p><span id="more-593"></span></p>
<h1>PHP8 探针项目（包含WP插件）</h1>
<p>专业的服务器监控和管理工具，提供实时系统监控、性能测试、数据库检测等功能。本项目包含两个版本：独立PHP探针和WordPress插件版本。</p>
<h2> 项目结构</h2>
<div class="markdown-code-block">
<pre><code class="hljs hljs-">php8-probe/
├── phpprobe.php              # 独立PHP探针（可直接访问）
├── php-probe-widget/         # WordPress插件版本
│   ├── php-probe-widget.php  # 主插件文件
│   ├── includes/             # 小组件类
│   ├── css/                  # 前端样式
│   ├── js/                   # 前端脚本
│   └── README.md             # 插件详细文档
├── LICENSE                   # 许可证
└── README.md                 # 本文件
</code></pre>
<div class="markdown-code-block-copy-btn"></div>
</div>
<h2><a id="user-content--快速开始" class="anchor" href="https://gitee.com/obaby/php8-probe#-%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B"></a><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 快速开始</h2>
<h3><a id="user-content-方式一独立php探针" class="anchor" href="https://gitee.com/obaby/php8-probe#%E6%96%B9%E5%BC%8F%E4%B8%80%E7%8B%AC%E7%AB%8Bphp%E6%8E%A2%E9%92%88"></a>方式一：独立PHP探针</h3>
<ol>
<li>将 <code>phpprobe.php</code> 上传到您的Web服务器</li>
<li>通过浏览器访问该文件即可查看服务器信息</li>
<li>支持实时监控、性能测试、数据库检测等功能</li>
</ol>
<p><strong>特点：</strong></p>
<ul>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 无需安装，直接使用</li>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 单文件部署，简单方便</li>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 支持多平台（Linux、Windows、macOS、FreeBSD）</li>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 实时系统监控</li>
</ul>
<h3><a id="user-content-方式二wordpress插件" class="anchor" href="https://gitee.com/obaby/php8-probe#%E6%96%B9%E5%BC%8F%E4%BA%8Cwordpress%E6%8F%92%E4%BB%B6"></a>方式二：WordPress插件</h3>
<ol>
<li>将 <code>php-probe-widget</code> 文件夹复制到 <code>wp-content/plugins/</code> 目录</li>
<li>在WordPress后台激活&#8221;服务器监控探针&#8221;插件</li>
<li>进入 <strong>外观 &gt; 小组件</strong> 页面</li>
<li>将&#8221;服务器监控探针&#8221;小组件拖拽到侧边栏</li>
<li>配置显示选项和主题设置</li>
</ol>
<p><a href="https://gitee.com/obaby/php8-probe" target="_blank" rel="noopener">https://gitee.com/obaby/php8-probe</a></p>
<hr />
<h1>结巴分词HTTP服务</h1>
<p>基于Flask和jieba的本地HTTP分词服务。</p>
<p><a href="https://gitee.com/obaby/baby-jb-server" target="_blank" rel="noopener">https://gitee.com/obaby/baby-jb-server</a></p>
<hr />
<h1>WordPress 博客数据分析工具</h1>
<p>这是一个用于分析 WordPress 博客数据的 Python 工具，可以通过 WordPress REST API 获取并分析博客的文章和评论数据。</p>
<h2><a id="user-content-功能特性" class="anchor" href="https://gitee.com/obaby/baby-wp-data-analysis-tool#%E5%8A%9F%E8%83%BD%E7%89%B9%E6%80%A7"></a>功能特性</h2>
<ul>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4dd.png" alt="📝" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 统计指定年份发布的文章数量（按月统计）</li>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4ac.png" alt="💬" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 统计指定年份的评论数量</li>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 分析评论用户的评论数排行</li>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4be.png" alt="💾" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 将分析结果保存为 JSON 文件</li>
</ul>
<p><a href="https://gitee.com/obaby/baby-wp-data-analysis-tool" target="_blank" rel="noopener">https://gitee.com/obaby/baby-wp-data-analysis-tool</a></p>
<hr />
<h1>微信双开脚本 (WeChat Dual Launch Script)</h1>
<p>一个用于 macOS 系统的微信双开自动化脚本，通过复制微信应用并修改 Bundle ID 实现真正的微信双开功能。</p>
<h2><a id="user-content--功能特性" class="anchor" href="https://gitee.com/obaby/baby-wechat#-%E5%8A%9F%E8%83%BD%E7%89%B9%E6%80%A7"></a><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4cb.png" alt="📋" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 功能特性</h2>
<ul>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>一键双开</strong> &#8211; 自动完成所有设置步骤</li>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>智能检测</strong> &#8211; 自动检测已存在的 WeChat2.app</li>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>安全可靠</strong> &#8211; 完善的错误处理和权限检查</li>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>彩色输出</strong> &#8211; 友好的命令行界面</li>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>进程管理</strong> &#8211; 查看和管理微信进程</li>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>自动化设置</strong> &#8211; 无需手动执行复杂命令</li>
</ul>
<p><a href="https://github.com/obaby/baby-wechat" target="_blank" rel="noopener">https://github.com/obaby/baby-wechat</a></p>
<hr />
<div class="markdown-heading" dir="auto">
<h1 class="heading-element" dir="auto" tabindex="-1">Baby 足迹地图</h1>
<p>&nbsp;</p>
</div>
<div class="markdown-heading" dir="auto">
<h2 class="heading-element" dir="auto" tabindex="-1">简介：</h2>
<p>&nbsp;</p>
</div>
<p dir="auto">基于百度地图的足迹地图。<br />
启动服务之后，先去后台 地图 key 设置页面，添加百度地图浏览器端 ak！<br />
启动服务之后，先去后台 地图 key 设置页面，添加百度地图浏览器端 ak！<br />
启动服务之后，先去后台 地图 key 设置页面，添加百度地图浏览器端 ak！</p>
<p dir="auto">为了防止 js 地址解析受限，需要同时添加服务端 ak！<br />
为了防止 js 地址解析受限，需要同时添加服务端 ak！<br />
为了防止 js 地址解析受限，需要同时添加服务端 ak！</p>
<p dir="auto">添加之后，访问： <a href="http://127.0.0.1:10099/api/location/process-my-location/" rel="nofollow">http://127.0.0.1:10099/api/location/process-my-location/</a> 地址刷新数据库的地点坐标信息，后续无需再通过 js 接口进行解析！</p>
<p><a href="https://github.com/obaby/BabyFootprintV2" target="_blank" rel="noopener">https://github.com/obaby/BabyFootprintV2</a></p>
<hr />
<h1 class="heading-element" dir="auto" tabindex="-1">Simple microblogging</h1>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">Add a microblog to your site; display the microposts in a widget or using a shortcode. 
增强版优化页面显示，增加分页功能。wp微博插件。</pre>
<p>&nbsp;</p>
<p><a href="https://github.com/obaby/Simple-microblogging-wordpress-plugin" target="_blank" rel="noopener">https://github.com/obaby/Simple-microblogging-wordpress-plugin</a></p>
<hr />
<div class="markdown-heading" dir="auto">
<h1 class="heading-element" dir="auto" tabindex="-1">Baby WP 评论强化拦截插件</h1>
<p>&nbsp;</p>
</div>
<p dir="auto">一个强大的WordPress评论过滤插件，支持字数限制、中文检测、关键词过滤等功能。</p>
<div class="markdown-heading" dir="auto">
<h2 class="heading-element" dir="auto" tabindex="-1">插件信息</h2>
<p>&nbsp;</p>
</div>
<ul dir="auto">
<li><strong>插件名称</strong>: Baby WP 评论强化拦截插件</li>
<li><strong>版本</strong>: 1.0.5</li>
<li><strong>作者</strong>: obaby</li>
<li><strong>作者网址</strong>: <a href="https://h4ck.org.cn/" rel="nofollow">https://h4ck.org.cn</a></li>
<li><strong>许可证</strong>: GPL v2 or later</li>
</ul>
<div class="markdown-heading" dir="auto">
<h2 class="heading-element" dir="auto" tabindex="-1">功能特性</h2>
<p>&nbsp;</p>
</div>
<div class="markdown-heading" dir="auto">
<h3 class="heading-element" dir="auto" tabindex="-1"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6e1.png" alt="🛡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 评论过滤功能</h3>
<p>&nbsp;</p>
</div>
<ul dir="auto">
<li><strong>字数限制</strong>: 设置评论的最少和最多字数</li>
<li><strong>中文检测</strong>: 要求评论必须包含中文字符</li>
<li><strong>关键词过滤</strong>: 支持自定义关键词和WordPress设置的关键词</li>
<li><strong>正则表达式支持</strong>: 支持使用正则表达式进行高级匹配</li>
</ul>
<div class="markdown-heading" dir="auto">
<h3 class="heading-element" dir="auto" tabindex="-1"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2699.png" alt="⚙" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 管理功能</h3>
<p>&nbsp;</p>
</div>
<ul dir="auto">
<li><strong>简单设置界面</strong>: 直观的管理后台设置页面</li>
<li><strong>错误消息自定义</strong>: 可以自定义各种错误提示消息和标题</li>
<li><strong>统计信息</strong>: 记录评论过滤统计信息，支持重置功能</li>
<li><strong>WordPress集成</strong>: 与WordPress讨论设置完美集成，支持实时预览</li>
<li><strong>设置验证</strong>: 完整的输入验证和数据清理机制</li>
</ul>
<div class="markdown-heading" dir="auto">
<h3 class="heading-element" dir="auto" tabindex="-1"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f527.png" alt="🔧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 技术特性</h3>
<p>&nbsp;</p>
</div>
<ul dir="auto">
<li><strong>简单架构</strong>: 采用简单的面向对象架构，易于维护</li>
<li><strong>性能优化</strong>: 高效的过滤算法，不影响网站性能</li>
<li><strong>兼容性</strong>: 支持WordPress 5.0+版本，PHP 7.4+</li>
<li><strong>多语言</strong>: 支持多语言环境</li>
<li><strong>数据安全</strong>: 完整的输入验证和清理机制</li>
<li><strong>错误处理</strong>: 完善的错误处理和日志记录</li>
</ul>
<p><a href="https://github.com/obaby/baby-wp-comment-filter" target="_blank" rel="noopener">https://github.com/obaby/baby-wp-comment-filter</a></p>
<hr />
<div class="markdown-heading" dir="auto">
<h1 class="heading-element" dir="auto" tabindex="-1">WinRAR-Keygen</h1>
<p>&nbsp;</p>
</div>
<div class="markdown-heading" dir="auto">
<h2 class="heading-element" dir="auto" tabindex="-1">1. What is WinRAR?</h2>
<p>&nbsp;</p>
</div>
<ul dir="auto">
<li>
<p dir="auto">WinRAR is a trialware file archiver utility for Windows, developed by Eugene Roshal of win.rar GmbH.</p>
</li>
<li>
<p dir="auto">It can create and view archives in RAR or ZIP file formats and unpack numerous archive file formats.</p>
</li>
<li>
<p dir="auto">WinRAR is not a free software. If you want to use it, you should pay to <a href="https://rarlab.com/" rel="nofollow"><strong>RARLAB</strong></a> and then you will get a license file named <code>"rarreg.key"</code>.</p>
</li>
<li>
<p dir="auto">This repository will tell you how WinRAR license file <code>"rarreg.key"</code> is generated.</p>
</li>
</ul>
<div class="markdown-heading" dir="auto">
<h2 class="heading-element" dir="auto" tabindex="-1">2. How is &#8220;rarreg.key&#8221; generated?</h2>
<p>&nbsp;</p>
</div>
<ul dir="auto">
<li>
<p dir="auto">WinRAR uses a signature algorithm, which is a variant of Chinese SM2 digital signature algorithm, to process the user&#8217;s name and the license type he/she got. Save the result to &#8220;rarreg.key&#8221; and add some header info, then a license file is generated.</p>
</li>
</ul>
<p><a href="https://github.com/obaby/winrar-keygen" target="_blank" rel="noopener">https://github.com/obaby/winrar-keygen</a></p>
<hr />
<div class="markdown-heading" dir="auto">
<h1 class="heading-element" dir="auto" tabindex="-1">Baby Device Manager</h1>
<p>&nbsp;</p>
</div>
<p dir="auto">一个功能强大的WordPress设备管理系统插件，支持设备分组管理、设备信息管理、自定义排序、状态跟踪等功能。</p>
<div class="markdown-heading" dir="auto">
<h2 class="heading-element" dir="auto" tabindex="-1">功能特点</h2>
<p>&nbsp;</p>
</div>
<ul dir="auto">
<li>设备分组管理
<ul dir="auto">
<li>创建和管理设备分组</li>
<li>自定义分组排序</li>
<li>分组描述信息</li>
</ul>
</li>
<li>设备管理
<ul dir="auto">
<li>添加/编辑/删除设备</li>
<li>设备状态管理（在售、停售、已售出、维修中、已报废）</li>
<li>设备图片和产品链接</li>
<li>自定义设备排序</li>
<li>设备描述信息</li>
</ul>
</li>
<li>前端展示
<ul dir="auto">
<li>响应式布局</li>
<li>按分组分类显示</li>
<li>支持多种排序方式</li>
<li>美观的界面设计</li>
<li>支持自定义每行显示设备数量（1-6个）</li>
</ul>
</li>
<li>其他功能
<ul dir="auto">
<li>图片管理：支持设备图片上传和显示</li>
<li>产品链接：支持添加产品详情页链接</li>
<li>状态跟踪：支持多种设备状态管理</li>
<li>自定义排序：支持设备分组和设备的自定义排序</li>
</ul>
</li>
</ul>
<p><a href="https://github.com/obaby/Baby-Device-Manager" target="_blank" rel="noopener">https://github.com/obaby/Baby-Device-Manager</a></p>
<hr />
<div class="relative cnb-markdown-heading group">
<h1 class="cnb-markdown-heading-com">RSS Beauty</h1>
<p>&nbsp;</p>
</div>
<p>为 WordPress RSS Feed 提供美观的网页展示样式（基于 <a class="cursor-pointer hover:underline" href="https://cnb.cool/110?url=https%3A%2F%2Frss.beauty" target="_blank" rel="noopener">RSS.Beauty</a> 的 Pink 主题）。</p>
<div class="relative cnb-markdown-heading group">
<h2 class="cnb-markdown-heading-com">项目功能</h2>
<p>&nbsp;</p>
</div>
<ul>
<li><strong>RSS 样式化</strong>：在 Feed 中注入 XSL 样式表，浏览器打开 feed 地址时以 HTML 页面形式展示，而非原始 XML。</li>
<li><strong>Feed Content-Type</strong>：将 feed 的 Content-Type 设为 <code>application/xml</code>，使浏览器按 XML 解析并应用 <code>xml-stylesheet</code>。</li>
<li><strong>XSL 地址</strong>：样式表使用插件目录下的静态文件 <code>pink.xsl</code>。需在 OpenResty/Nginx 中为 <code>.xsl</code> 配置正确的 Content-Type（见下方配置说明），否则浏览器可能不按 XSL 解析。</li>
<li><strong>主题</strong>：内置淡粉色（light pink）页面背景与适配的文字颜色。</li>
</ul>
<p><a href="https://cnb.cool/oba.by/rss-beauty" target="_blank" rel="noopener">https://cnb.cool/oba.by/rss-beauty</a></p>
<hr />
<div class="relative cnb-markdown-heading group">
<h1 class="cnb-markdown-heading-com">WP-UserAgent</h1>
<p>&nbsp;</p>
</div>
<p><strong>Contributors:</strong> obaby<br />
<strong>Donate Link:</strong> <a class="cursor-pointer hover:underline" href="https://cnb.cool/110?url=https%3A%2F%2Foba.by" target="_blank" rel="noopener">https://oba.by</a><br />
<strong>Tags:</strong> useragent, user-agent, user agent, web, browser, web browser, operating system, platform, os, mac, apple, windows, win, linux, phone<br />
<strong>Requires at least:</strong> 2.0<br />
<strong>Tested up to:</strong> 6.3<br />
<strong>Stable tag:</strong> 16.06.99</p>
<div class="relative cnb-markdown-heading group">
<h2 class="cnb-markdown-heading-com">IP 查询方式（归属地）</h2>
<p>&nbsp;</p>
</div>
<p>插件支持四种 IP 查询方式，可在 <strong>设置 → WP-UserAgent</strong> 中选择：</p>
<table>
<thead>
<tr>
<th>方式</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>IP2Location</strong></td>
<td>使用 IP2Location 数据库（需将 BIN 文件放入 <code>show-useragent/ip2location_db/db/</code>），依赖 Composer</td>
</tr>
<tr>
<td><strong>CZDB</strong></td>
<td>使用纯真 CZDB 数据库（需授权与 db 文件放入 <code>show-useragent/czdb/db/</code>），依赖 Composer</td>
</tr>
<tr>
<td><strong>ip2region</strong></td>
<td>使用 ip2region xdb（<strong>仅内置 ip2reginapi，不依赖 Composer</strong>）。需将 xdb 文件放入 <code>show-useragent/ip2region_db/</code>，文件名：<code>ip2region_v4.xdb</code>、<code>ip2region_v6.xdb</code></td>
</tr>
<tr>
<td><strong>纯真QQWRY</strong></td>
<td>使用 qqwry_api（qqwry.dat + ipv6wry.db），无需 Composer。数据文件放入 <code>show-useragent/qqwry_api/ipdata/</code></td>
</tr>
</tbody>
</table>
<p>选择 <strong>ip2region</strong> 或 <strong>纯真QQWRY</strong> 时不会加载 <code>vendor/autoload.php</code>。若选择 IP2Location 或 CZDB 时 vendor 加载失败，插件会自动回退为 ip2region 模式，避免站点白屏。</p>
<div class="relative cnb-markdown-heading group">
<h2 class="cnb-markdown-heading-com">Description</h2>
<p>&nbsp;</p>
</div>
<p><strong>WP-UserAgent</strong> is a simple plugin that allows you to display details about a computer&#8217;s <a class="cursor-pointer hover:underline" href="https://cnb.cool/110?url=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FOperating_system" target="_blank" rel="noopener">operating system</a> or <a class="cursor-pointer hover:underline" href="https://cnb.cool/110?url=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FWeb_browser" target="_blank" rel="noopener">web browser</a> that your visitors comment from.</p>
<p>It uses the comment-&gt;agent property to access the <a class="cursor-pointer hover:underline" href="https://cnb.cool/110?url=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FUser_agent" target="_blank" rel="noopener">User-Agent string</a>. Through a series of regular expressions, this plugin is able to detect the operating system and browser which can be integrated in comments or placed in custom places through your template(s).</p>
<p>I&#8217;m adding new web browsers and operating systems frequently, as well as updating and optimizing the source code. Your feedback is very important, new features have been added by request, so if there&#8217;s something you would like to see in <strong>WP-UserAgent</strong>, <a class="cursor-pointer hover:underline" href="https://cnb.cool/110?url=https%3A%2F%2Fwww.kyleabaker.com%2Fgoodies%2Fcoding%2Fwp-useragent%2F" target="_blank" rel="noopener">leave a comment</a>, and I&#8217;ll see what I can do.</p>
<p><strong>WP-UserAgent</strong> was written with Geany &#8211; <a class="cursor-pointer hover:underline" href="https://cnb.cool/110?url=http%3A%2F%2Fwww.geany.org%2F" target="_blank" rel="noopener">http://www.geany.org/</a><br />
Images created with The Gimp &#8211; <a class="cursor-pointer hover:underline" href="https://cnb.cool/110?url=http%3A%2F%2Fwww.gimp.org%2F" target="_blank" rel="noopener">http://www.gimp.org/</a></p>
<blockquote><p><strong>注意：</strong></p>
<ul>
<li>使用 <strong>CZDB</strong> 时：若更新替换纯真数据库，请同步更新 <code>show-useragent/ip2c-text.php</code> 中的 <code>$key = 'n2pf2+PrE1y9I55MjdpLpg==';</code></li>
<li>使用 <strong>ip2region</strong> 时：将 xdb 文件放入 <code>show-useragent/ip2region_db/</code>（<code>ip2region_v4.xdb</code>、<code>ip2region_v6.xdb</code>），无需 Composer。</li>
</ul>
</blockquote>
<p><a href="https://cnb.cool/oba.by/wp-useragent" target="_blank" rel="noopener">https://cnb.cool/oba.by/wp-useragent</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zhongxiaojie.cn/2026/03/593/feed/</wfw:commentRss>
			<slash:comments>81</slash:comments>
		
		
			</item>
		<item>
		<title>浅谈WordPress静态化</title>
		<link>https://zhongxiaojie.cn/2026/01/270/</link>
					<comments>https://zhongxiaojie.cn/2026/01/270/#comments</comments>
		
		<dc:creator><![CDATA[obaby]]></dc:creator>
		<pubDate>Tue, 27 Jan 2026 12:59:14 +0000</pubDate>
				<category><![CDATA[程序媛]]></category>
		<category><![CDATA[btop]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[openresty]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[php-fpm]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[缓存]]></category>
		<guid isPermaLink="false">https://zhongxiaojie.cn/?p=270</guid>

					<description><![CDATA[以前在使用php 7.4的时候，并没有刻意尝试将页面静态化。然而，在升级到8.4之后由于一系列的问题，导致ph [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="https://zhongxiaojie.cn/wp-content/uploads/2026/01/30A4104tuya.jpg" data-lbwps-width="2560" data-lbwps-height="3840" data-lbwps-srcsmall="https://zhongxiaojie.cn/wp-content/uploads/2026/01/30A4104tuya.jpg" data-lightbox="gal[270]" data-lbwps-exif="&lt;span class=&quot;pswp__caption__exif_camera&quot;&gt;Canon EOS R6m2&lt;/span&gt; &lt;span class=&quot;pswp__caption__exif_focal&quot;&gt;85mm&lt;/span&gt; &lt;span class=&quot;pswp__caption__exif_fstop&quot;&gt;𝑓/4&lt;/span&gt; &lt;span class=&quot;pswp__caption__exif_shutter&quot;&gt;1/160s&lt;/span&gt; &lt;span class=&quot;pswp__caption__exif_iso&quot;&gt;ISO320&lt;/span&gt; &lt;span class=&quot;pswp__caption__exif_datetime&quot;&gt;2025年11月10日&lt;/span&gt; "><img decoding="async" class="alignnone size-full wp-image-276" src="https://zhongxiaojie.cn/wp-content/uploads/2026/01/30A4104tuya-scaled.jpg" alt="" width="1707" height="2560" srcset="https://zhongxiaojie.cn/wp-content/uploads/2026/01/30A4104tuya-scaled.jpg?v=1769518740 1707w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/30A4104tuya-200x300.jpg?v=1769518740 200w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/30A4104tuya-683x1024.jpg?v=1769518740 683w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/30A4104tuya-100x150.jpg?v=1769518740 100w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/30A4104tuya-768x1152.jpg?v=1769518740 768w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/30A4104tuya-1024x1536.jpg?v=1769518740 1024w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/30A4104tuya-1365x2048.jpg?v=1769518740 1365w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/30A4104tuya-665x998.jpg?v=1769518740 665w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/30A4104tuya-173x260.jpg?v=1769518740 173w" sizes="(max-width: 1707px) 100vw, 1707px" /></a></p>
<p>以前在使用php 7.4的时候，并没有刻意尝试将页面静态化。然而，在升级到8.4之后由于一系列的问题，导致php响应异常缓慢，哪怕是开启了object cache。这就让人挺奇怪。不过在后期解决掉配置文件长度异常以及主题频繁的更新提示之后页面恢复正常了。</p>
<p><span id="more-270"></span></p>
<p>测速的时候，多数测速点基本都在1s以内。然而，与旧版一样，扛不住快速测试，快速测试的情况下，前面测速点的正常，后面的就会让php-fpm跑满cpu。于是，在<a href="https://zhongxiaojie.cn/2026/01/197/" target="_blank" rel="noopener">之前的一篇文章提到了解决wp健康问题(响应超时)</a>的问题，也是为了解决速度太慢的问题。本质上也是用的静态化的处理逻辑。</p>
<p>然而，这个东西存在问题，那就是我有多个域名，在数据更新之后怎么同时更新所有域名的缓存数据就成了问题。之前想的是通过wp插件，检测到变化删除缓存文件的方式。但是php-fpm由于权限问题导致删除失败。我又不想给php进程太高的权限，所以，后来尝试在nginx中进行操作，不过需要编译lua模块。</p>
<p>我不想编译，于是干脆换了 openresty:</p>
<blockquote><p>OpenResty<sup>®</sup> 是一个基于 <a title="Nginx" href="https://openresty.org/cn/nginx.html">Nginx</a> 与 Lua 的高性能 Web 平台，其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。</p>
<p>OpenResty<sup>®</sup> 通过汇聚各种设计精良的 <a title="Nginx" href="https://openresty.org/cn/nginx.html">Nginx</a> 模块（主要由 OpenResty 团队自主开发），从而将 <a title="Nginx" href="https://openresty.org/cn/nginx.html">Nginx</a> 有效地变成一个强大的通用 Web 应用平台。这样，Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 <a title="Nginx" href="https://openresty.org/cn/nginx.html">Nginx</a> 支持的各种 C 以及 Lua 模块，快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。</p></blockquote>
<p>这么一来就简单了，安装openresty替换掉原来的nginx:</p>
<p>1.更新缓存配置，所有的域名使用同一个缓存配置wordpress-php-with-cache-auto-purge-allinone.conf：</p>
<pre class="EnlighterJSRAW" data-enlighter-language="nginx"># WordPress PHP 处理 + FastCGI 页面缓存 + 自动清除缓存（无需插件）
# 基于 wordpress-php-with-cache.conf，添加自动缓存清除功能
# 每个站点独立缓存（缓存键包含 $host）

location ~ [^/]\.php(/|$)
{
    try_files $uri =404;

    fastcgi_pass unix:/run/php/php8.4-fpm.sock;

    # ------ 页面缓存：跳过后台、登录、订阅等 ------
    set $skip_cache 0;
    if ($request_uri ~* "/wp-admin/|/wp-login\.php|/xmlrpc\.php|wp-.*\.php|/feed/|sitemap(_index)?.xml|/cart/|/checkout/|/my-account/") {
        set $skip_cache 1;
    }
    if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in|woocommerce_") {
        set $skip_cache 1;
    }
    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache $skip_cache;

    # ------ FastCGI 缓存（依赖 nginx.conf 中 fastcgi_cache_path ALLINONE）------
    # 注意：缓存键包含 $host，每个站点独立缓存
    fastcgi_cache ALLINONE;
    fastcgi_cache_key $scheme$request_method$host$request_uri;
    fastcgi_cache_valid 200 301 302 60m;
    fastcgi_cache_use_stale error timeout updating http_500 http_503;
    fastcgi_cache_lock on;
    fastcgi_cache_lock_timeout 5s;

    fastcgi_index index.php;
    include fastcgi.conf;

    # ------ 检测工具要求的客户端缓存响应头 ------
    add_header X-Cache-Status $upstream_cache_status;
    add_header X-Cache-Enabled "1";
    add_header Cache-Control "public, max-age=3600";


}
</pre>
<p>缓存清理配置cache-purge-lua-allinone.conf：</p>
<pre class="EnlighterJSRAW" data-enlighter-language="nginx"># OpenResty Lua 缓存清除配置（ALLINONE 缓存版本）
# 在 server 块中添加此配置以启用缓存清除功能
# 适用于 ALLINONE 缓存（缓存键不包含 host，所有域名共享）

# 缓存清除 location（使用 Lua 脚本）
# 支持两种方式：
# 1. /purge/路径 - 清除指定路径的缓存
# 2. /purge-all - 清除全部缓存
# 3. PURGE 方法 - 使用 HTTP PURGE 方法清除当前请求的缓存
location ~ ^/purge(/.*)$ {
    # 只允许本地或内网访问（安全考虑）
    allow 127.0.0.1;
    allow ::1;
    allow 10.0.0.0/8;
    allow 172.16.0.0/12;
    allow 192.168.0.0/16;
    deny all;
    
    # 使用 Lua 脚本处理
    content_by_lua_block {
        local cache_purge = require "cache_purge_allinone"
        cache_purge.handle_purge_request()
    }
    
    access_log off;
}

# 清除全部缓存 location
location = /purge-all {
    # 只允许本地或内网访问（安全考虑）
    allow 127.0.0.1;
    allow ::1;
    allow 10.0.0.0/8;
    allow 172.16.0.0/12;
    allow 192.168.0.0/16;
    deny all;

    # 使用 Lua 脚本处理
    content_by_lua_block {
        local cache_purge = require "cache_purge_allinone"
        cache_purge.handle_purge_request()
    }

    access_log off;
}

# 获取缓存路径列表 location
location = /cache-paths {
    # 只允许本地或内网访问（安全考虑）
    allow 127.0.0.1;
    allow ::1;
    allow 10.0.0.0/8;
    allow 172.16.0.0/12;
    allow 192.168.0.0/16;
    deny all;

    # 使用 Lua 脚本处理
    content_by_lua_block {
        local cache_purge = require "cache_purge_allinone"
        cache_purge.handle_cache_paths_request()
    }

    access_log off;
}

</pre>
<p>2.lua脚本部分：auto_cache_purge_allinone.lua</p>
<pre class="EnlighterJSRAW" data-enlighter-language="lua">-- OpenResty 自动缓存清除脚本（ALLINONE 缓存）
-- 自动检测评论提交并清除缓存
-- 缓存规则：fastcgi_cache_key $scheme$request_method$host$request_uri（包含 host，每个站点独立缓存）
-- 缓存目录：/var/cache/nginx/allinone/

local _M = {}

-- 统一的缓存目录
local cache_path = '/var/cache/nginx/allinone'

-- 计算缓存文件路径
local function get_cache_file_path(cache_key_md5)
    local level1 = string.sub(cache_key_md5, -1)
    local level2 = string.sub(cache_key_md5, -3, -2)
    return cache_path .. '/' .. level1 .. '/' .. level2 .. '/' .. cache_key_md5
end

-- 计算缓存键的 MD5（包含 host）
-- 缓存键格式：$scheme$request_method$host$request_uri
local function get_cache_key_md5(scheme, method, host, uri)
    local cache_key_string = scheme .. method .. host .. uri
    return ngx.md5(cache_key_string)
end

-- 删除缓存文件
local function delete_cache_file(file_path)
    local command = 'rm -f "' .. file_path .. '" 2&gt;/dev/null'
    local ok = os.execute(command)
    return ok == 0
end

-- 清除指定 URL 的缓存
local function purge_url(scheme, host, uri)
    local method = 'GET'
    local cache_key_md5 = get_cache_key_md5(scheme, method, host, uri)
    local cache_file = get_cache_file_path(cache_key_md5)
    
    local deleted = delete_cache_file(cache_file)
    
    -- 也尝试删除匹配的文件（处理查询参数等情况）
    local level1 = string.sub(cache_key_md5, -1)
    local level2 = string.sub(cache_key_md5, -3, -2)
    local cache_dir = cache_path .. '/' .. level1 .. '/' .. level2
    local command = 'find "' .. cache_dir .. '" -name "' .. cache_key_md5 .. '*" -delete 2&gt;/dev/null'
    os.execute(command)
    
    return deleted
end

-- 从评论提交请求中提取文章 ID
local function extract_post_id_from_request()
    -- 尝试从请求体中获取 post_id
    ngx.req.read_body()
    local body = ngx.req.get_body_data()
    
    if body then
        -- 解析 POST 数据
        local post_id = string.match(body, ".*comment_post_ID=(%d+)")
        if post_id then
            return tonumber(post_id)
        end
    end
    
    -- 尝试从 referer 中提取
    local referer = ngx.var.http_referer
    if referer then
        -- 从 URL 中提取文章 ID（WordPress 的 URL 结构）
        local post_id = string.match(referer, ".*/%?p=(%d+)")
        if post_id then
            return tonumber(post_id)
        end
    end
    
    return nil
end

-- 从 referer 中提取文章路径
local function extract_post_path()
    -- 从 referer 获取（评论来源页面就是文章页面）
    local referer = ngx.var.http_referer
    if referer then
        local path = string.match(referer, ".*https?://[^/]+(.+)")
        if path then
            -- 移除查询参数和锚点
            path = string.match(path, "^([^?#]+)")
            -- 移除尾部斜杠（除了根路径）
            if path ~= "/" then
                path = string.match(path, "^(.+)/$") or path
            end
            if path and path ~= "" then
                return path
            end
        end
    end
    
    return nil
end

-- 实际的缓存清除操作（在异步定时器中执行）
local function do_purge_cache(scheme, host, post_path, request_uri)
    -- 如果获取到文章信息，清除文章缓存
    if post_path and post_path ~= "" and post_path ~= "/" then
        local deleted = purge_url(scheme, host, post_path)
        if deleted then
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 已清除文章缓存: ", post_path)
        end
        
        -- 也尝试带尾部斜杠的版本
        purge_url(scheme, host, post_path .. "/")
    else
        -- 如果获取不到文章信息，记录日志
        ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 无法获取文章信息，仅清除首页缓存")
    end
    
    -- 无论是否获取到文章信息，都清除首页缓存
    local home_deleted = purge_url(scheme, host, "/")
    if home_deleted then
        ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 已清除首页缓存")
    end
end

-- 自动检测评论相关操作并清除缓存
function _M.auto_purge_on_comment()
    ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] log 阶段开始执行")
    
    -- 检查是否已标记为跳过（例如在 header_filter 阶段已检测到需要忽略的请求）
    if ngx.ctx and ngx.ctx.skip_cache_purge then
        ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 跳过：已标记为 skip_cache_purge")
        return
    end
    
    -- 只处理 POST 请求
    if ngx.var.request_method ~= "POST" then
        ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 跳过：不是 POST 请求，method=", ngx.var.request_method)
        return
    end
    
    local request_uri = ngx.var.request_uri or ""
    ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] log 阶段，request_uri: ", request_uri)
    
    local is_comment_action = false
    local comment_id = nil
    local post_id = nil
    local body = nil
    
    -- 检测前端评论提交
    if string.find(request_uri, "wp%-comments%-post%.php") then
        -- 检查状态码（302 重定向表示评论提交成功）
        local status = ngx.status
        ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] wp-comments-post.php 请求，status: ", status)
        if status ~= 302 and status ~= 200 then
            return
        end
        is_comment_action = true
    end
    
    -- 检测后台 AJAX 评论操作（删除、批准、垃圾评论、回复评论等）
    if string.find(request_uri, "admin%-ajax%.php") then
        ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 检测到 admin-ajax.php 请求")
        
        -- 首先尝试从上下文获取请求体（可能在 header_filter 阶段已读取）
        if ngx.ctx and ngx.ctx.request_body then
            body = ngx.ctx.request_body
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 从上下文获取请求体，长度: ", string.len(body))
        else
            -- 安全地读取请求体（避免重复读取）
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 尝试读取请求体")
            local ok, err = pcall(function()
                ngx.req.read_body()
                body = ngx.req.get_body_data()
            end)
            
            if not ok then
                ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 读取请求体失败: ", err or "unknown error")
                return
            end
            
            if body then
                ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 成功读取请求体，长度: ", string.len(body))
            else
                ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 请求体为空")
            end
        end
        
        -- 检查 referer 和 body，如果不包含 /wp-admin/ 则跳过
        local referer = ngx.var.http_referer or ""
        ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] referer: ", referer)
        if not string.match(referer, ".*/wp%-admin/") then
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 跳过：referer 不包含 /wp-admin/, referer=", referer)
            return
        end
        
        if not body then
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 跳过：body 为空")
            return
        end
        
        -- 记录 body 内容（用于调试，只记录前 500 个字符）
        local body_preview = string.sub(body, 1, 500)
        ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] admin-ajax.php 请求，body 预览: ", body_preview)
        
        -- 检测请求动作，忽略 php_probe_realtime
        local action_match = string.match(body, ".*action=([^&amp;]+)")
        ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] action_match: ", action_match or "nil")
        if action_match == "php_probe_realtime" then
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 跳过：php_probe_realtime 请求")
            return
        end
        
        -- 检测评论相关操作
        local action_detected = false
        if string.match(body, ".*action=delete%-comment") then
            action_detected = true
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 检测到 action=delete-comment")
        elseif string.match(body, ".*action=trash%-comment") then
            action_detected = true
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 检测到 action=trash-comment")
        elseif string.match(body, ".*action=untrash%-comment") then
            action_detected = true
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 检测到 action=untrash-comment")
        elseif string.match(body, ".*action=spam%-comment") then
            action_detected = true
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 检测到 action=spam-comment")
        elseif string.match(body, ".*action=unspam%-comment") then
            action_detected = true
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 检测到 action=unspam-comment")
        elseif string.match(body, ".*action=approve%-comment") then
            action_detected = true
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 检测到 action=approve-comment")
        elseif string.match(body, ".*action=unapprove%-comment") then
            action_detected = true
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 检测到 action=unapprove-comment")
        elseif string.match(body, ".*action=replyto%-comment") then
            action_detected = true
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 检测到 action=replyto-comment")
        end
        
        if action_detected then
            is_comment_action = true
            
            -- 提取评论 ID 和文章 ID
            comment_id = string.match(body, ".*comment_ID=(%d+)") or string.match(body, ".*id=(%d+)")
            post_id = string.match(body, ".*comment_post_ID=(%d+)")
            
            -- 记录检测到的评论操作
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 检测到后台评论操作: action=", action_match or "unknown", ", comment_id=", comment_id or "nil", ", post_id=", post_id or "nil")
        else
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 未检测到评论相关操作")
        end
    end
    
    if not is_comment_action then
        ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 跳过：不是评论相关操作")
        return
    end
    
    local scheme = ngx.var.scheme or "https"
    local host = ngx.var.host or ngx.var.http_host or ""
    
    -- 提取文章路径
    local post_path = nil
    
    -- 如果是后台 AJAX 操作，尝试从请求参数或 referer 中提取文章信息
    if string.find(request_uri, "admin%-ajax%.php") and (comment_id or post_id) then
        -- 使用之前读取的 body（避免重复读取）
        if body then
            -- 尝试从 _url 参数中提取文章路径
            local url_param = string.match(body, ".*_url=([^&amp;]+)")
            if url_param then
                url_param = ngx.unescape_uri(url_param)
                -- 提取路径部分
                local extracted_path = string.match(url_param, ".*https?://[^/]+(.+)")
                if extracted_path then
                    extracted_path = string.match(extracted_path, "^([^?#]+)")
                    -- 如果不是后台页面，使用这个路径
                    if extracted_path and not string.match(extracted_path, ".*wp%-admin") then
                        post_path = extracted_path
                    end
                end
            end
            
            -- 如果还没有找到路径，尝试从其他参数中提取
            if not post_path or post_path == "" then
                -- 尝试从 referer 中提取（如果 referer 是文章页面）
                local referer = ngx.var.http_referer
                if referer and not string.match(referer, ".*wp%-admin") then
                    post_path = string.match(referer, ".*https?://[^/]+(.+)")
                    if post_path then
                        post_path = string.match(post_path, "^([^?#]+)")
                    end
                end
            end
        end
    else
        -- 前端评论提交，从 referer 提取文章路径
        post_path = extract_post_path()
    end
    
    -- 使用异步定时器执行缓存清除操作
    -- ngx.timer.at(0, handler) 会在当前请求处理完成后立即在后台执行
    local ok, err = ngx.timer.at(0, function(premature, scheme_arg, host_arg, post_path_arg, request_uri_arg)
        if premature then
            -- 定时器被提前取消（不应该发生，因为 delay=0）
            ngx.log(ngx.WARN, "[Auto Cache Purge ALLINONE] 定时器被提前取消")
            return
        end
        
        -- 在异步上下文中执行实际的缓存清除
        local purge_ok, purge_err = pcall(do_purge_cache, scheme_arg, host_arg, post_path_arg, request_uri_arg)
        if not purge_ok then
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 异步清除缓存错误: ", purge_err)
        end
    end, scheme, host, post_path, request_uri)
    
    if not ok then
        -- 如果创建定时器失败（例如定时器池已满），回退到同步执行
        ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] 无法创建异步定时器，使用同步执行: ", err)
        do_purge_cache(scheme, host, post_path, request_uri)
    end
end

-- 在 rewrite 阶段执行（可以读取请求体）
-- 提前读取请求体并保存到上下文，供 log 阶段使用
function _M.rewrite()
    -- 只处理 POST 请求
    if ngx.var.request_method ~= "POST" then
        return
    end
    
    local request_uri = ngx.var.request_uri or ""
    
    -- 只处理 admin-ajax.php 和 wp-comments-post.php 请求
    if string.find(request_uri, "admin%-ajax%.php") or string.find(request_uri, "wp%-comments%-post%.php") then
        -- 检查 referer（对于 admin-ajax.php）
        if string.find(request_uri, "admin%-ajax%.php") then
            local referer = ngx.var.http_referer or ""
            if not string.find(referer, "/wp%-admin/") then
                ngx.ctx.skip_cache_purge = true
                return
            end
        end
        
        -- 在 rewrite 阶段读取请求体（这个阶段允许读取）
        local ok, err = pcall(function()
            ngx.req.read_body()
            local body = ngx.req.get_body_data()
            
            if body then
                -- 对于 admin-ajax.php，检查是否为需要忽略的请求
                if string.find(request_uri, "admin%-ajax%.php") then
                    local action_match = string.match(body, ".*action=([^&amp;]+)")
                    if action_match == "php_probe_realtime" then
                        ngx.ctx.skip_cache_purge = true
                        return
                    end
                end
                
                -- 保存到上下文，供 log 阶段使用
                ngx.ctx.request_body = body
                ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] rewrite 阶段已保存请求体，长度: ", string.len(body))
            else
                ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] rewrite 阶段：请求体为空")
            end
        end)
        
        if not ok then
            ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] rewrite 阶段读取请求体出错: ", err or "unknown error")
        end
    end
end

-- 在响应头过滤阶段执行（可以访问响应头）
-- 注意：header_filter 阶段无法读取请求体，只能做简单的标记
function _M.header_filter()
    -- header_filter 阶段不再需要做任何处理
    -- 所有检查都在 rewrite 阶段完成
end

-- 在日志阶段执行（确保在响应完成后）
function _M.log()
    -- 使用 pcall 包装，避免错误导致请求失败
    local ok, err = pcall(function()
        _M.auto_purge_on_comment()
    end)
    
    if not ok then
        ngx.log(ngx.ERR, "[Auto Cache Purge ALLINONE] log 阶段执行错误: ", err)
    end
end

return _M

</pre>
<p>cache_purge_allinone.lua：</p>
<pre class="EnlighterJSRAW" data-enlighter-language="lua">-- OpenResty Lua 缓存清除脚本（ALLINONE 缓存版本，支持独立缓存）
-- 支持独立缓存清除（缓存键包含 host，每个站点独立缓存）
-- 缓存键格式：$scheme$request_method$host$request_uri

local _M = {}

-- 统一的缓存目录（ALLINONE 缓存）
local cache_path = "/var/cache/nginx/allinone"

-- 计算缓存文件路径（基于 Nginx levels=1:2）
local function get_cache_file_path(cache_key_md5)
    local level1 = string.sub(cache_key_md5, -1)  -- 最后1位
    local level2 = string.sub(cache_key_md5, -3, -2)  -- 倒数第3-2位
    return cache_path .. "/" .. level1 .. "/" .. level2 .. "/" .. cache_key_md5
end

-- 计算缓存键的 MD5（包含 host，每个站点独立缓存）
-- 缓存键格式：$scheme$request_method$host$request_uri
local function get_cache_key_md5(scheme, method, host, uri)
    local cache_key_string = scheme .. method .. host .. uri
    return ngx.md5(cache_key_string)
end

-- 删除缓存文件
local function delete_cache_file(file_path)
    -- 使用 shell 命令删除（更可靠）
    local command = "rm -f \"" .. file_path .. "\" 2&gt;/dev/null"
    local ok = os.execute(command)
    if ok == 0 then
        return true
    else
        ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 删除缓存文件失败: ", file_path)
        return false
    end
end

-- 清除指定 URL 的缓存（包含 host，每个站点独立缓存）
function _M.purge_url(scheme, host, uri)
    -- 计算缓存键（包含 host）：$scheme$request_method$host$request_uri
    local method = "GET"
    local cache_key_md5 = get_cache_key_md5(scheme, method, host, uri)
    
    -- 获取缓存文件路径
    local cache_file = get_cache_file_path(cache_key_md5)
    
    -- 删除缓存文件
    local deleted = delete_cache_file(cache_file)
    
    -- 也尝试删除匹配的文件（处理查询参数等情况）
    local level1 = string.sub(cache_key_md5, -1)
    local level2 = string.sub(cache_key_md5, -3, -2)
    local cache_dir = cache_path .. "/" .. level1 .. "/" .. level2
    
    -- 使用 shell 命令删除匹配的文件
    local command = "find \"" .. cache_dir .. "\" -name \"" .. cache_key_md5 .. "*\" -delete 2&gt;/dev/null"
    local result = os.execute(command)
    if result == 0 then
        deleted = true
    end
    
    -- 也尝试带尾部斜杠的版本（如果原路径没有）
    if uri ~= "/" and not string.match(uri, "/$") then
        local uri_with_slash = uri .. "/"
        local cache_key_md5_slash = get_cache_key_md5(scheme, method, host, uri_with_slash)
        local cache_file_slash = get_cache_file_path(cache_key_md5_slash)
        delete_cache_file(cache_file_slash)
        
        local level1_slash = string.sub(cache_key_md5_slash, -1)
        local level2_slash = string.sub(cache_key_md5_slash, -3, -2)
        local cache_dir_slash = cache_path .. "/" .. level1_slash .. "/" .. level2_slash
        local command_slash = "find \"" .. cache_dir_slash .. "\" -name \"" .. cache_key_md5_slash .. "*\" -delete 2&gt;/dev/null"
        os.execute(command_slash)
    end
    
    -- 也尝试不带尾部斜杠的版本（如果原路径有）
    if uri ~= "/" and string.match(uri, "/$") then
        local uri_without_slash = string.match(uri, "^(.+)/$") or uri
        local cache_key_md5_no_slash = get_cache_key_md5(scheme, method, host, uri_without_slash)
        local cache_file_no_slash = get_cache_file_path(cache_key_md5_no_slash)
        delete_cache_file(cache_file_no_slash)
        
        local level1_no_slash = string.sub(cache_key_md5_no_slash, -1)
        local level2_no_slash = string.sub(cache_key_md5_no_slash, -3, -2)
        local cache_dir_no_slash = cache_path .. "/" .. level1_no_slash .. "/" .. level2_no_slash
        local command_no_slash = "find \"" .. cache_dir_no_slash .. "\" -name \"" .. cache_key_md5_no_slash .. "*\" -delete 2&gt;/dev/null"
        os.execute(command_no_slash)
    end
    
    return deleted
end

-- 清除全部缓存
function _M.purge_all()
    ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 开始清除全部缓存，目录: " .. cache_path)

    -- 测试：先检查当前用户和权限
    local whoami_cmd = "whoami 2&gt;&amp;1"
    local whoami_handle = io.popen(whoami_cmd)
    if whoami_handle then
        local user = whoami_handle:read("*a")
        whoami_handle:close()
        ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 当前用户: " .. (user or "unknown"))
    end

    -- 测试：检查缓存目录权限
    local ls_cmd = "ls -la '" .. cache_path .. "' 2&gt;&amp;1"
    local ls_handle = io.popen(ls_cmd)
    if ls_handle then
        local ls_output = ls_handle:read("*a")
        ls_handle:close()
        ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 目录权限: " .. ls_output)
    end

    -- 方法1: 直接使用 rm 命令
    local cmd = "rm -rf '" .. cache_path .. "'/* 2&gt;&amp;1"
    ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 执行命令: " .. cmd)

    local handle = io.popen(cmd)
    if handle then
        local output = handle:read("*a")
        local success, exit_reason, exit_code = handle:close()

        ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 命令输出: " .. (output or "无输出"))
        ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 命令结果: success=" .. tostring(success) .. ", exit_code=" .. tostring(exit_code))

        if exit_code == 0 then
            ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 成功清除全部缓存")
            return true, 1
        end
    else
        ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 无法执行命令: io.popen 失败")
    end

    -- 方法2: 如果上面的失败了，尝试使用 os.execute
    ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 尝试 os.execute 方法")
    local result = os.execute(cmd)
    ngx.log(ngx.ERR, "[Cache Purge ALLINONE] os.execute 结果: " .. tostring(result))

    if result == 0 then
        ngx.log(ngx.ERR, "[Cache Purge ALLINONE] os.execute 成功清除全部缓存")
        return true, 1
    end

    ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 所有删除方法都失败了")
    return false, 0
end

-- 处理缓存路径请求
function _M.handle_cache_paths_request()
    local success, result = _M.get_cache_paths()

    if success then
        ngx.status = 200
        ngx.header["Content-Type"] = "application/json"

        -- 限制返回数量
        local limit = 100
        local limited_paths = {}
        for i = 1, math.min(limit, #result) do
            table.insert(limited_paths, result[i])
        end

        -- 构建简单的 JSON 响应
        local json_paths = {}
        for _, path in ipairs(limited_paths) do
            table.insert(json_paths, string.format('{"path":"%s","size":%d,"mtime":%d,"md5":"%s"}',
                path.path,
                path.size,
                path.mtime,
                path.md5
            ))
        end

        local response = string.format('{"status":"success","paths":[%s],"total_count":%d,"has_more":%s,"limit":%d}',
            table.concat(json_paths, ','),
            #result,
            #result &gt; limit and "true" or "false",
            limit
        )

        ngx.say(response)
    else
        ngx.status = 500
        ngx.header["Content-Type"] = "application/json"
        local error_msg = type(result) == "string" and result or "获取缓存路径失败"
        ngx.say(string.format('{"status":"error","message":"%s"}', error_msg))
        ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 获取缓存路径失败: " .. error_msg)
    end

    ngx.exit(ngx.status)
end

-- 处理 PURGE 请求
function _M.handle_purge_request()
    local request_uri = ngx.var.request_uri or ""

    -- 检查是否是清除全部缓存的请求
    if string.match(request_uri, "^/purge%-all") then
        local success, file_count = _M.purge_all()

        if success then
            ngx.status = 200
            ngx.header["Content-Type"] = "application/json"
            ngx.say("{\"status\":\"success\",\"message\":\"已清除全部缓存\",\"deleted_count\":" .. file_count .. "}")
        else
            ngx.status = 500
            ngx.header["Content-Type"] = "application/json"
            ngx.say("{\"status\":\"error\",\"message\":\"清除全部缓存失败，请检查 Nginx 错误日志获取详细信息\"}")
        end

        ngx.exit(ngx.status)
        return
    end

    -- 从请求 URI 中提取路径（/purge/xxx -&gt; xxx）
    local uri = string.match(request_uri, "^/purge(/.*)$")

    if not uri or uri == "" then
        uri = "/"
    end

    -- 移除查询参数
    uri = string.match(uri, "^([^?]+)") or uri

    -- 强制使用 https（因为实际缓存都是 https 的）
    local scheme = "https"

    -- 获取 host（从 Host 头或 server_name 获取）
    local host = ngx.var.http_host or ngx.var.host or ngx.var.server_name or ""

    -- 如果 host 为空，记录错误
    if host == "" then
        ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 无法获取 host，清除失败")
        ngx.status = 400
        ngx.header["Content-Type"] = "application/json"
        ngx.say("{\"status\":\"error\",\"message\":\"无法获取 host 信息\"}")
        ngx.exit(ngx.status)
    end

    -- 清除缓存（包含 host，每个站点独立缓存）
    local success = _M.purge_url(scheme, host, uri)

    if success then
        ngx.status = 200
        ngx.header["Content-Type"] = "application/json"
        ngx.say("{\"status\":\"success\",\"message\":\"已清除缓存: " .. scheme .. "://" .. host .. uri .. " (独立缓存)\"}")
        ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 成功清除缓存: " .. scheme .. "://" .. host .. uri)
    else
        ngx.status = 404
        ngx.header["Content-Type"] = "application/json"
        ngx.say("{\"status\":\"error\",\"message\":\"清除失败: " .. scheme .. "://" .. host .. uri .. " (可能缓存不存在)\"}")
        ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 清除缓存失败: " .. scheme .. "://" .. host .. uri)
    end

    ngx.exit(ngx.status)
end

-- 获取缓存路径列表
function _M.get_cache_paths()
    ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 开始获取缓存路径列表，目录: " .. cache_path)

    local paths = {}
    local total_count = 0

    -- 直接尝试使用 find 命令，如果目录不存在，find 会返回错误
    -- 使用 -maxdepth 限制深度，提高性能
    local cmd = "find '" .. cache_path .. "' -maxdepth 3 -type f 2&gt;&amp;1 | head -100"
    ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 执行命令: " .. cmd)

    local handle = io.popen(cmd)
    if not handle then
        ngx.log(ngx.ERR, "[Cache Purge ALLINONE] io.popen 执行失败")
        return false, "无法执行 find 命令"
    end

    local output = handle:read("*a")
    local success, exit_reason, exit_code = handle:close()

    ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 命令输出长度: " .. (output and string.len(output) or 0))
    ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 命令结果: success=" .. tostring(success) .. ", exit_code=" .. tostring(exit_code))

    -- 检查输出中是否包含错误信息
    if output and string.find(output, "No such file or directory") then
        ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 缓存目录不存在")
        return false, "缓存目录不存在: " .. cache_path
    end

    if not output or output == "" then
        ngx.log(ngx.ERR, "[Cache Purge ALLINONE] find 命令无输出，可能是目录为空或不存在")
        -- 返回空列表而不是错误
        return true, {}
    end

    -- 解析输出
    for line in output:gmatch("[^\r\n]+") do
        if line ~= "" and not string.find(line, "^find:") then -- 跳过错误行
            local full_path = line:gsub("^%s+", ""):gsub("%s+$", "") -- 去除首尾空格
            if full_path ~= "" and string.find(full_path, cache_path) then
                -- 提取相对路径和文件名
                local relative_path = full_path:gsub("^" .. cache_path:gsub("%-", "%%-"):gsub("%.", "%%.") .. "/", "")
                local md5 = relative_path:match("([^/]+)$") or relative_path

                -- 尝试获取文件大小和修改时间
                local stat_cmd = "stat -c '%s %Y' '" .. full_path .. "' 2&gt;/dev/null"
                local stat_handle = io.popen(stat_cmd)
                local size = 0
                local mtime = 0
                if stat_handle then
                    local stat_output = stat_handle:read("*a")
                    stat_handle:close()
                    if stat_output then
                        local stat_size, stat_mtime = stat_output:match("(%d+)%s+(%d+)")
                        if stat_size then size = tonumber(stat_size) or 0 end
                        if stat_mtime then mtime = tonumber(stat_mtime) or 0 end
                    end
                end

                table.insert(paths, {
                    path = full_path,
                    size = size,
                    mtime = mtime,
                    md5 = md5
                })

                total_count = total_count + 1

                -- 限制返回数量
                if total_count &gt;= 100 then
                    break
                end
            end
        end
    end

    -- 按修改时间倒序排序
    table.sort(paths, function(a, b) return a.mtime &gt; b.mtime end)

    ngx.log(ngx.ERR, "[Cache Purge ALLINONE] 成功获取 " .. #paths .. " 个缓存文件路径")
    return true, paths
end

return _M
</pre>
<p>3.openresty nginx.conf 配置添加下面的内容 在http中添加：</p>
<pre class="EnlighterJSRAW" data-enlighter-language="nginx">http
    {
        # Lua 模块路径配置（必须）
        lua_package_path "/usr/local/openresty/nginx/conf/lua/?.lua;;";


    # ALLINONE
    fastcgi_cache_path /var/cache/nginx/allinone
    	levels=1:2
    	keys_zone=ALLINONE:64m
    	max_size=512m
    	inactive=60m
    	use_temp_path=off;
</pre>
<p>4.修改vhost配置文件添加conf引入zhongxiaojie.com.conf：</p>
<pre class="EnlighterJSRAW" data-enlighter-language="nginx">include cache-purge-lua-allinone.conf;
include wordpress-php-with-cache-auto-purge-allinone.conf;</pre>
<p>5.wp插件nginx-cache-purge-multi-domain.php 如果只有一个域名，就保留一个就可以了：</p>
<pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php
/**
 * Plugin Name: Nginx FastCGI Cache Purge Multi-Domain
 * Description: 当有新评论提交或文章更新时，自动清除多个域名的 Nginx FastCGI 缓存（每个站点独立缓存）
 * Version: 3.1
 * Author: obaby
 */

// 防止直接访问
if (!defined("ABSPATH")) {
    exit;
}

class Nginx_Cache_Purge_Multi_Domain {
    
    // 统一的缓存目录（ALLINONE 缓存，但每个站点独立缓存）
    private $cache_path = "/var/cache/nginx/allinone";
    
    // 需要清除缓存的所有域名列表（可通过 WordPress 选项覆盖）
    private $default_domains = array(
        "zhongxiaojie.com",
        "oba.by",
    );
    
    // 选项名称
    private $option_name = "nginx_cache_purge_multi_domain";
    
    // 是否启用调试日志
    private $debug = true;
    
    // 异步清除队列
    private $purge_queue = array();
    
    // 缓存键计算缓存（避免重复计算）
    private $cache_key_cache = array();
    
    // 文件系统访问检查缓存
    private $fs_access_cache = null;
    
    public function __construct() {
        // 注册 hooks
        add_action("comment_post", array($this, "purge_cache_on_comment"), 10, 2);
        add_action("wp_set_comment_status", array($this, "purge_cache_on_comment_status"), 10, 2);
        add_action("save_post", array($this, "purge_cache_on_post_save"), 10, 1);
        
        // 异步处理队列（在请求结束后执行）
        add_action("shutdown", array($this, "process_purge_queue"), 999);
        
        // 添加管理菜单
        add_action("admin_menu", array($this, "add_admin_menu"));
        
        // 处理 AJAX 请求
        add_action("wp_ajax_nginx_cache_purge_all", array($this, "ajax_purge_all_cache"));
        add_action("wp_ajax_nginx_cache_get_info", array($this, "ajax_get_cache_info"));
        add_action("wp_ajax_nginx_cache_get_paths", array($this, "ajax_get_cache_paths"));
        
        if ($this-&gt;debug) {
            $this-&gt;log("插件初始化完成");
        }
    }
    
    /**
     * 获取配置的域名列表
     */
    private function get_domains() {
        $options = get_option($this-&gt;option_name, array());
        if (isset($options["domains"]) &amp;&amp; is_array($options["domains"]) &amp;&amp; !empty($options["domains"])) {
            return $options["domains"];
        }
        return $this-&gt;default_domains;
    }
    
    /**
     * 添加到清除队列（异步处理）
     */
    private function add_to_purge_queue($scheme, $host, $path) {
        $key = $scheme . "|" . $host . "|" . $path;
        if (!isset($this-&gt;purge_queue[$key])) {
            $this-&gt;purge_queue[$key] = array(
                "scheme" =&gt; $scheme,
                "host" =&gt; $host,
                "path" =&gt; $path,
            );
        }
    }
    
    /**
     * 批量添加到清除队列
     */
    private function add_paths_to_queue($paths, $scheme = "https") {
        $domains = $this-&gt;get_domains();
        foreach ($domains as $domain) {
            foreach ($paths as $path) {
                $this-&gt;add_to_purge_queue($scheme, $domain, $path);
            }
        }
    }
    
    /**
     * 处理清除队列（异步执行）
     */
    public function process_purge_queue() {
        if (empty($this-&gt;purge_queue)) {
            return;
        }
        
        // 如果支持 fastcgi_finish_request，立即结束响应，在后台处理
        if (function_exists("fastcgi_finish_request")) {
            fastcgi_finish_request();
        }
        
        if ($this-&gt;debug) {
            $this-&gt;log(sprintf("开始异步处理清除队列，共 %d 个任务", count($this-&gt;purge_queue)));
        }
        
        $success_count = 0;
        $fail_count = 0;
        
        foreach ($this-&gt;purge_queue as $item) {
            $result = $this-&gt;purge_url_for_domain($item["scheme"], $item["host"], $item["path"]);
            if ($result) {
                $success_count++;
            } else {
                $fail_count++;
            }
        }
        
        if ($this-&gt;debug) {
            $this-&gt;log(sprintf("清除队列处理完成：成功 %d，失败 %d", $success_count, $fail_count));
        }
        
        // 清空队列
        $this-&gt;purge_queue = array();
    }
    
    /**
     * 评论提交后清除缓存
     */
    public function purge_cache_on_comment($comment_id, $comment_approved) {
        if ($this-&gt;debug) {
            $this-&gt;log(sprintf("Hook 触发: comment_id=%d, approved=%s", $comment_id, $comment_approved));
        }
        
        // 只处理已批准的评论
        if ($comment_approved != 1) {
            return;
        }
        
        $comment = get_comment($comment_id);
        if (!$comment) {
            return;
        }
        
        $post_id = $comment-&gt;comment_post_ID;
        $post = get_post($post_id);
        if (!$post) {
            return;
        }
        
        // 获取需要清除的路径
        $paths = $this-&gt;get_post_purge_paths($post_id);
        
        // 添加到异步队列
        $this-&gt;add_paths_to_queue($paths);
        
        if ($this-&gt;debug) {
            $this-&gt;log(sprintf("评论提交：已添加到清除队列，post_id=%d，路径数=%d", $post_id, count($paths)));
        }
    }
    
    /**
     * 评论状态变更时清除缓存
     */
    public function purge_cache_on_comment_status($comment_id, $status) {
        if (!in_array($status, array("approve", "spam", "trash"))) {
            return;
        }
        
        $comment = get_comment($comment_id);
        if (!$comment) {
            return;
        }
        
        $post_id = $comment-&gt;comment_post_ID;
        $paths = $this-&gt;get_post_purge_paths($post_id);
        $this-&gt;add_paths_to_queue($paths);
    }
    
    /**
     * 文章保存时清除缓存
     */
    public function purge_cache_on_post_save($post_id) {
        // 跳过自动保存和修订
        if (defined("DOING_AUTOSAVE") &amp;&amp; DOING_AUTOSAVE) {
            return;
        }
        
        if (wp_is_post_revision($post_id)) {
            return;
        }
        
        $post = get_post($post_id);
        if (!$post || $post-&gt;post_status != "publish") {
            return;
        }
        
        $paths = $this-&gt;get_post_purge_paths($post_id);
        $this-&gt;add_paths_to_queue($paths);
        
        if ($this-&gt;debug) {
            $this-&gt;log(sprintf("文章保存：已添加到清除队列，post_id=%d，路径数=%d", $post_id, count($paths)));
        }
    }
    
    /**
     * 获取文章相关的清除路径列表
     */
    private function get_post_purge_paths($post_id) {
        $paths = array();
        
        // 文章页面
        $post_url = get_permalink($post_id);
        if ($post_url) {
            $parsed = parse_url($post_url);
            if (isset($parsed["path"])) {
                $paths[] = $parsed["path"];
            }
        }
        
        // 首页
        $paths[] = "/";
        
        // 分类页
        $categories = get_the_category($post_id);
        foreach ($categories as $category) {
            $cat_url = get_category_link($category-&gt;term_id);
            if ($cat_url) {
                $parsed = parse_url($cat_url);
                if (isset($parsed["path"])) {
                    $paths[] = $parsed["path"];
                }
            }
        }
        
        return array_unique($paths);
    }
    
    /**
     * 清除指定域名和路径的缓存
     */
    private function purge_url_for_domain($scheme, $host, $path) {
        if (empty($host) || empty($path)) {
            return false;
        }
        
        // 方法1：尝试 HTTP PURGE（优先，更快）
        if ($this-&gt;purge_via_http($scheme, $host, $path)) {
            return true;
        }
        
        // 方法2：直接删除缓存文件
        return $this-&gt;purge_via_file_delete($scheme, $host, $path);
    }
    
    /**
     * 通过 HTTP 请求清除缓存
     */
    private function purge_via_http($scheme, $host, $path) {
        $purge_url = "http://127.0.0.1/purge" . $path; // 使用本地回环，避免外部网络开销
        
        $args = array(
            "method" =&gt; "GET",
            "timeout" =&gt; 1, // 减少超时时间，快速失败
            "headers" =&gt; array(
                "Host" =&gt; $host,
            ),
            "sslverify" =&gt; false,
            "blocking" =&gt; true, // 必须阻塞，否则无法判断结果
        );
        
        $response = wp_remote_request($purge_url, $args);
        
        if (is_wp_error($response)) {
            if ($this-&gt;debug) {
                $this-&gt;log(sprintf("HTTP PURGE 失败: %s - %s", $purge_url, $response-&gt;get_error_message()));
            }
            return false;
        }
        
        $code = wp_remote_retrieve_response_code($response);
        // 200 或 404 都算成功
        if ($code == 200 || $code == 404) {
            if ($this-&gt;debug) {
                $this-&gt;log(sprintf("HTTP PURGE 成功: %s (code=%d)", $purge_url, $code));
            }
            return true;
        }
        
        return false;
    }
    
    /**
     * 通过删除缓存文件清除缓存
     */
    private function purge_via_file_delete($scheme, $host, $path) {
        // 检查文件系统访问权限（缓存结果）
        if ($this-&gt;fs_access_cache === null) {
            $this-&gt;fs_access_cache = $this-&gt;check_fs_access();
        }
        
        if (!$this-&gt;fs_access_cache) {
            // 无法访问文件系统，尝试 shell 命令
            return $this-&gt;purge_via_shell($scheme, $host, $path);
        }
        
        $deleted = false;
        $path_variants = $this-&gt;get_path_variants($path);
        
        foreach ($path_variants as $path_variant) {
            $cache_files = $this-&gt;get_cache_files($scheme, $host, $path_variant);
            
            foreach ($cache_files as $cache_file) {
                if (@file_exists($cache_file) &amp;&amp; @unlink($cache_file)) {
                    $deleted = true;
                    if ($this-&gt;debug) {
                        $this-&gt;log(sprintf("文件删除成功: %s", $cache_file));
                    }
                }
            }
            
            // 也尝试删除匹配的文件（处理查询参数等情况）
            $cache_dir = dirname($cache_files[0]);
            if (@is_dir($cache_dir)) {
                $md5 = $this-&gt;get_cache_key_md5($scheme, $host, $path_variant);
                $files = @glob($cache_dir . "/" . $md5 . "*");
                if ($files &amp;&amp; is_array($files)) {
                    foreach ($files as $file) {
                        if (@is_file($file) &amp;&amp; @unlink($file)) {
                            $deleted = true;
                        }
                    }
                }
            }
        }
        
        // 如果文件删除失败，尝试 shell 命令
        if (!$deleted) {
            $deleted = $this-&gt;purge_via_shell($scheme, $host, $path);
        }
        
        return $deleted;
    }
    
    /**
     * 检查文件系统访问权限
     */
    private function check_fs_access() {
        $old_error_handler = set_error_handler(function($errno, $errstr) {
            if (strpos($errstr, "open_basedir") !== false) {
                return true;
            }
            return false;
        }, E_WARNING);
        
        $can_access = @is_dir($this-&gt;cache_path);
        restore_error_handler();
        
        return $can_access;
    }
    
    /**
     * 获取路径变体（处理尾部斜杠等）
     */
    private function get_path_variants($path) {
        $variants = array(
            $path,
            rtrim($path, "/"),
            $path . "/",
        );
        
        // 去重
        return array_unique($variants);
    }
    
    /**
     * 计算缓存键的 MD5（带缓存）
     */
    private function get_cache_key_md5($scheme, $host, $path) {
        $key = $scheme . "|" . $host . "|" . $path;
        
        if (!isset($this-&gt;cache_key_cache[$key])) {
            $cache_key_string = $scheme . "GET" . $host . $path;
            $this-&gt;cache_key_cache[$key] = md5($cache_key_string);
        }
        
        return $this-&gt;cache_key_cache[$key];
    }
    
    /**
     * 获取缓存文件路径列表
     */
    private function get_cache_files($scheme, $host, $path) {
        $md5 = $this-&gt;get_cache_key_md5($scheme, $host, $path);
        $level1 = substr($md5, -1);
        $level2 = substr($md5, -3, 2);
        $cache_file = $this-&gt;cache_path . "/" . $level1 . "/" . $level2 . "/" . $md5;
        
        return array($cache_file);
    }
    
    /**
     * 通过 shell 命令删除缓存文件
     */
    private function purge_via_shell($scheme, $host, $path) {
        // 检查 shell 命令是否可用
        if (!function_exists("exec")) {
            return false;
        }
        
        $disabled_functions = explode(",", ini_get("disable_functions"));
        if (in_array("exec", $disabled_functions)) {
            return false;
        }
        
        $deleted = false;
        $path_variants = $this-&gt;get_path_variants($path);
        
        foreach ($path_variants as $path_variant) {
            $md5 = $this-&gt;get_cache_key_md5($scheme, $host, $path_variant);
            $level1 = substr($md5, -1);
            $level2 = substr($md5, -3, 2);
            $cache_file = $this-&gt;cache_path . "/" . $level1 . "/" . $level2 . "/" . $md5;
            
            // 删除精确匹配的文件
            $command = sprintf("rm -f %s 2&gt;/dev/null", escapeshellarg($cache_file));
            @exec($command, $output, $return_var);
            
            if ($return_var === 0) {
                $deleted = true;
            }
            
            // 删除匹配的文件（处理查询参数）
            $cache_dir = dirname($cache_file);
            $glob_command = sprintf("rm -f %s/%s* 2&gt;/dev/null", escapeshellarg($cache_dir), escapeshellarg($md5));
            @exec($glob_command, $glob_output, $glob_return_var);
            
            if ($glob_return_var === 0) {
                $deleted = true;
            }
        }
        
        return $deleted;
    }
    
    /**
     * 日志记录（统一入口）
     */
    private function log($message) {
        if ($this-&gt;debug &amp;&amp; function_exists("error_log")) {
            error_log("[Nginx Cache Purge Multi-Domain] " . $message);
        }
    }
    
    /**
     * 添加管理菜单
     */
    public function add_admin_menu() {
        add_management_page(
            "Nginx 缓存管理",
            "Nginx 缓存管理",
            "manage_options",
            "nginx-cache-purge-tools",
            array($this, "render_tools_page")
        );
    }
    
    /**
     * 渲染工具页面
     */
    public function render_tools_page() {
        if (!current_user_can("manage_options")) {
            wp_die("您没有权限访问此页面");
        }
        
        // 获取缓存信息
        $cache_info = $this-&gt;get_cache_info();
        $sample_md5 = $this-&gt;get_sample_cache_md5();
        
        ?&gt;
        &lt;div class="wrap"&gt;
            &lt;h1&gt;Nginx 缓存管理工具&lt;/h1&gt;
            
            &lt;div class="card" style="max-width: 800px;"&gt;
                &lt;h2&gt;缓存信息&lt;/h2&gt;
                &lt;table class="form-table"&gt;
                    &lt;tr&gt;
                        &lt;th scope="row"&gt;缓存目录&lt;/th&gt;
                        &lt;td&gt;
                            &lt;code&gt;&lt;?php echo esc_html($this-&gt;cache_path); ?&gt;&lt;/code&gt;
                            &lt;?php if (!$cache_info["accessible"]): ?&gt;
                                &lt;span style="color: red;"&gt;（无法访问）&lt;/span&gt;
                            &lt;?php endif; ?&gt;
                        &lt;/td&gt;
                    &lt;/tr&gt;
                    &lt;tr&gt;
                        &lt;th scope="row"&gt;缓存大小&lt;/th&gt;
                        &lt;td&gt;
                            &lt;?php if ($cache_info["accessible"]): ?&gt;
                                &lt;strong&gt;&lt;?php echo esc_html($this-&gt;format_bytes($cache_info["size"])); ?&gt;&lt;/strong&gt;
                            &lt;?php else: ?&gt;
                                &lt;span style="color: red;"&gt;无法获取&lt;/span&gt;
                            &lt;?php endif; ?&gt;
                        &lt;/td&gt;
                    &lt;/tr&gt;
                    &lt;tr&gt;
                        &lt;th scope="row"&gt;缓存文件数&lt;/th&gt;
                        &lt;td&gt;
                            &lt;?php if ($cache_info["accessible"]): ?&gt;
                                &lt;strong&gt;&lt;?php echo number_format($cache_info["file_count"]); ?&gt;&lt;/strong&gt; 个文件
                            &lt;?php else: ?&gt;
                                &lt;span style="color: red;"&gt;无法获取&lt;/span&gt;
                            &lt;?php endif; ?&gt;
                        &lt;/td&gt;
                    &lt;/tr&gt;
                    &lt;tr&gt;
                        &lt;th scope="row"&gt;缓存 MD5 示例&lt;/th&gt;
                        &lt;td&gt;
                            &lt;code&gt;&lt;?php echo esc_html($sample_md5["md5"]); ?&gt;&lt;/code&gt;
                            &lt;br&gt;
                            &lt;small style="color: #666;"&gt;
                                缓存键: &lt;code&gt;&lt;?php echo esc_html($sample_md5["key"]); ?&gt;&lt;/code&gt;
                                &lt;br&gt;
                                文件路径: &lt;code&gt;&lt;?php echo esc_html($sample_md5["path"]); ?&gt;&lt;/code&gt;
                            &lt;/small&gt;
                        &lt;/td&gt;
                    &lt;/tr&gt;
                &lt;/table&gt;
                
                &lt;p&gt;
                    &lt;button type="button" id="refresh-cache-info" class="button"&gt;刷新信息&lt;/button&gt;
                    &lt;button type="button" id="purge-all-cache" class="button button-primary" style="margin-left: 10px;"&gt;清除全部缓存&lt;/button&gt;
                    &lt;button type="button" id="show-cache-paths" class="button" style="margin-left: 10px;"&gt;查看缓存文件&lt;/button&gt;
                &lt;/p&gt;

                &lt;div id="cache-action-message" style="margin-top: 15px;"&gt;&lt;/div&gt;
            &lt;/div&gt;

            &lt;div class="card" id="cache-paths-section" style="max-width: 800px; display: none; margin-top: 20px;"&gt;
                &lt;h2&gt;缓存文件列表&lt;/h2&gt;
                &lt;div id="cache-paths-controls" style="margin-bottom: 15px;"&gt;
                    &lt;label for="cache-paths-limit"&gt;显示数量:&lt;/label&gt;
                    &lt;select id="cache-paths-limit"&gt;
                        &lt;option value="20"&gt;20&lt;/option&gt;
                        &lt;option value="50" selected&gt;50&lt;/option&gt;
                        &lt;option value="100"&gt;100&lt;/option&gt;
                        &lt;option value="200"&gt;200&lt;/option&gt;
                    &lt;/select&gt;
                    &lt;button type="button" id="refresh-cache-paths" class="button" style="margin-left: 10px;"&gt;刷新列表&lt;/button&gt;
                &lt;/div&gt;
                &lt;div id="cache-paths-content"&gt;
                    &lt;p class="description"&gt;正在加载缓存文件列表...&lt;/p&gt;
                &lt;/div&gt;
                &lt;div id="cache-paths-message" style="margin-top: 15px;"&gt;&lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        
        &lt;script type="text/javascript"&gt;
        jQuery(document).ready(function($) {
            // 刷新缓存信息
            $('#refresh-cache-info').on('click', function() {
                var $btn = $(this);
                var $msg = $('#cache-action-message');
                
                $btn.prop('disabled', true).text('刷新中...');
                $msg.html('&lt;div class="notice notice-info"&gt;&lt;p&gt;正在刷新缓存信息...&lt;/p&gt;&lt;/div&gt;');
                
                $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: {
                        action: 'nginx_cache_get_info',
                        nonce: '&lt;?php echo wp_create_nonce("nginx_cache_tools"); ?&gt;'
                    },
                    success: function(response) {
                        if (response.success) {
                            var info = response.data;
                            $msg.html('&lt;div class="notice notice-success"&gt;&lt;p&gt;刷新成功！缓存大小: ' + info.size_formatted + ', 文件数: ' + info.file_count_formatted + '&lt;/p&gt;&lt;/div&gt;');
                            // 更新页面显示
                            if (info.accessible) {
                                $('th:contains("缓存大小")').next('td').html('&lt;strong&gt;' + info.size_formatted + '&lt;/strong&gt;');
                                $('th:contains("缓存文件数")').next('td').html('&lt;strong&gt;' + info.file_count_formatted + '&lt;/strong&gt; 个文件');
                            }
                        } else {
                            $msg.html('&lt;div class="notice notice-error"&gt;&lt;p&gt;刷新失败: ' + (response.data || '未知错误') + '&lt;/p&gt;&lt;/div&gt;');
                        }
                    },
                    error: function() {
                        $msg.html('&lt;div class="notice notice-error"&gt;&lt;p&gt;请求失败，请重试&lt;/p&gt;&lt;/div&gt;');
                    },
                    complete: function() {
                        $btn.prop('disabled', false).text('刷新信息');
                    }
                });
            });
            
            // 清除全部缓存
            $('#purge-all-cache').on('click', function() {
                if (!confirm('确定要清除全部缓存吗？此操作不可恢复！')) {
                    return;
                }

                var $btn = $(this);
                var $msg = $('#cache-action-message');

                $btn.prop('disabled', true).text('清除中...');
                $msg.html('&lt;div class="notice notice-info"&gt;&lt;p&gt;正在清除全部缓存，请稍候...&lt;/p&gt;&lt;/div&gt;');

                $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: {
                        action: 'nginx_cache_purge_all',
                        nonce: '&lt;?php echo wp_create_nonce("nginx_cache_tools"); ?&gt;'
                    },
                    success: function(response) {
                        if (response.success) {
                            $msg.html('&lt;div class="notice notice-success"&gt;&lt;p&gt;' + (response.data.message || '缓存清除成功！') + '&lt;/p&gt;&lt;/div&gt;');
                            // 自动刷新缓存信息
                            setTimeout(function() {
                                $('#refresh-cache-info').trigger('click');
                            }, 1000);
                        } else {
                            $msg.html('&lt;div class="notice notice-error"&gt;&lt;p&gt;清除失败: ' + (response.data || '未知错误') + '&lt;/p&gt;&lt;/div&gt;');
                        }
                    },
                    error: function() {
                        $msg.html('&lt;div class="notice notice-error"&gt;&lt;p&gt;请求失败，请重试&lt;/p&gt;&lt;/div&gt;');
                    },
                    complete: function() {
                        $btn.prop('disabled', false).text('清除全部缓存');
                    }
                });
            });

            // 显示缓存文件列表
            $('#show-cache-paths').on('click', function() {
                var $section = $('#cache-paths-section');
                if ($section.is(':visible')) {
                    $section.hide();
                    $(this).text('查看缓存文件');
                } else {
                    $section.show();
                    $(this).text('隐藏缓存文件');
                    loadCachePaths();
                }
            });

            // 刷新缓存文件列表
            $('#refresh-cache-paths').on('click', function() {
                loadCachePaths();
            });

            // 当限制数量改变时重新加载
            $('#cache-paths-limit').on('change', function() {
                loadCachePaths();
            });

            function loadCachePaths() {
                var $content = $('#cache-paths-content');
                var $msg = $('#cache-paths-message');
                var limit = $('#cache-paths-limit').val();

                $content.html('&lt;p class="description"&gt;正在加载缓存文件列表...&lt;/p&gt;');
                $msg.empty();

                $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: {
                        action: 'nginx_cache_get_paths',
                        limit: limit,
                        nonce: '&lt;?php echo wp_create_nonce("nginx_cache_tools"); ?&gt;'
                    },
                    success: function(response) {
                        if (response.success) {
                            var data = response.data;
                            var html = '';

                            if (data.paths &amp;&amp; data.paths.length &gt; 0) {
                                html += '&lt;table class="widefat striped"&gt;';
                                html += '&lt;thead&gt;&lt;tr&gt;';
                                html += '&lt;th&gt;缓存文件路径&lt;/th&gt;';
                                html += '&lt;th&gt;文件大小&lt;/th&gt;';
                                html += '&lt;th&gt;修改时间&lt;/th&gt;';
                                html += '&lt;th&gt;MD5&lt;/th&gt;';
                                html += '&lt;/tr&gt;&lt;/thead&gt;';
                                html += '&lt;tbody&gt;';

                                data.paths.forEach(function(item) {
                                    html += '&lt;tr&gt;';
                                    html += '&lt;td&gt;&lt;code style="word-break: break-all;"&gt;' + item.path + '&lt;/code&gt;&lt;/td&gt;';
                                    html += '&lt;td&gt;' + formatBytes(item.size) + '&lt;/td&gt;';
                                    html += '&lt;td&gt;' + new Date(item.mtime * 1000).toLocaleString() + '&lt;/td&gt;';
                                    html += '&lt;td&gt;&lt;code&gt;' + item.md5 + '&lt;/code&gt;&lt;/td&gt;';
                                    html += '&lt;/tr&gt;';
                                });

                                html += '&lt;/tbody&gt;&lt;/table&gt;';

                                if (data.has_more) {
                                    html += '&lt;p class="description"&gt;显示前 ' + data.limit + ' 个文件，共 ' + data.total_count + ' 个缓存文件。&lt;/p&gt;';
                                } else {
                                    html += '&lt;p class="description"&gt;共 ' + data.total_count + ' 个缓存文件。&lt;/p&gt;';
                                }
                            } else {
                                html = '&lt;p class="description"&gt;没有找到缓存文件。&lt;/p&gt;';
                            }

                            $content.html(html);
                        } else {
                            $content.html('&lt;p class="description"&gt;加载失败。&lt;/p&gt;');
                            $msg.html('&lt;div class="notice notice-error"&gt;&lt;p&gt;加载缓存路径失败: ' + (response.data || '未知错误') + '&lt;/p&gt;&lt;/div&gt;');
                        }
                    },
                    error: function() {
                        $content.html('&lt;p class="description"&gt;请求失败。&lt;/p&gt;');
                        $msg.html('&lt;div class="notice notice-error"&gt;&lt;p&gt;请求失败，请重试&lt;/p&gt;&lt;/div&gt;');
                    }
                });
            }

            function formatBytes(bytes) {
                if (bytes === 0) return '0 B';
                var k = 1024;
                var sizes = ['B', 'KB', 'MB', 'GB'];
                var i = Math.floor(Math.log(bytes) / Math.log(k));
                return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
            }
        });
        &lt;/script&gt;
        &lt;?php
    }
    
    /**
     * AJAX: 获取缓存信息
     */
    public function ajax_get_cache_info() {
        check_ajax_referer("nginx_cache_tools", "nonce");
        
        if (!current_user_can("manage_options")) {
            wp_send_json_error("权限不足");
        }
        
        $info = $this-&gt;get_cache_info();
        
        wp_send_json_success(array(
            "accessible" =&gt; $info["accessible"],
            "size" =&gt; $info["size"],
            "size_formatted" =&gt; $this-&gt;format_bytes($info["size"]),
            "file_count" =&gt; $info["file_count"],
            "file_count_formatted" =&gt; number_format($info["file_count"]),
        ));
    }
    
    /**
     * AJAX: 清除全部缓存
     */
    public function ajax_purge_all_cache() {
        check_ajax_referer("nginx_cache_tools", "nonce");

        if (!current_user_can("manage_options")) {
            wp_send_json_error("权限不足");
        }

        $result = $this-&gt;purge_all_cache();

        if ($result["success"]) {
            wp_send_json_success(array(
                "message" =&gt; $result["message"],
                "deleted_count" =&gt; $result["deleted_count"],
            ));
        } else {
            wp_send_json_error($result["message"]);
        }
    }

    /**
     * AJAX: 获取缓存路径列表
     */
    public function ajax_get_cache_paths() {
        check_ajax_referer("nginx_cache_tools", "nonce");

        if (!current_user_can("manage_options")) {
            wp_send_json_error("权限不足");
        }

        $paths = $this-&gt;get_cache_paths();

        if (isset($paths['error'])) {
            wp_send_json_error($paths['error']);
        }

        // 数据已经由 Lua 脚本处理，直接返回
        wp_send_json_success(array(
            "paths" =&gt; $paths,
            "total_count" =&gt; count($paths),
            "has_more" =&gt; false, // Lua 脚本已经限制了数量
            "limit" =&gt; 100,
        ));
    }
    
    /**
     * 获取缓存信息
     */
    private function get_cache_info() {
        $info = array(
            "accessible" =&gt; false,
            "size" =&gt; 0,
            "file_count" =&gt; 0,
        );
        
        // 检查文件系统访问权限
        if ($this-&gt;fs_access_cache === null) {
            $this-&gt;fs_access_cache = $this-&gt;check_fs_access();
        }
        
        if (!$this-&gt;fs_access_cache) {
            // 尝试使用 shell 命令获取信息
            return $this-&gt;get_cache_info_via_shell();
        }
        
        // 使用 PHP 文件系统函数
        if (@is_dir($this-&gt;cache_path)) {
            $info["accessible"] = true;
            $info["size"] = $this-&gt;get_dir_size($this-&gt;cache_path);
            $info["file_count"] = $this-&gt;count_files($this-&gt;cache_path);
        }
        
        return $info;
    }
    
    /**
     * 通过 shell 命令获取缓存信息
     */
    private function get_cache_info_via_shell() {
        $info = array(
            "accessible" =&gt; false,
            "size" =&gt; 0,
            "file_count" =&gt; 0,
        );
        
        if (!function_exists("exec")) {
            return $info;
        }
        
        $disabled_functions = explode(",", ini_get("disable_functions"));
        if (in_array("exec", $disabled_functions)) {
            return $info;
        }
        
        // 获取目录大小
        $size_command = sprintf("du -sb %s 2&gt;/dev/null | cut -f1", escapeshellarg($this-&gt;cache_path));
        @exec($size_command, $size_output, $size_return);
        if ($size_return === 0 &amp;&amp; !empty($size_output)) {
            $info["size"] = intval($size_output[0]);
            $info["accessible"] = true;
        }
        
        // 获取文件数量
        $count_command = sprintf("find %s -type f 2&gt;/dev/null | wc -l", escapeshellarg($this-&gt;cache_path));
        @exec($count_command, $count_output, $count_return);
        if ($count_return === 0 &amp;&amp; !empty($count_output)) {
            $info["file_count"] = intval(trim($count_output[0]));
        }
        
        return $info;
    }
    
    /**
     * 获取目录大小（递归）
     */
    private function get_dir_size($dir) {
        $size = 0;
        
        if (!@is_dir($dir)) {
            return 0;
        }
        
        $files = @scandir($dir);
        if ($files === false) {
            return 0;
        }
        
        foreach ($files as $file) {
            if ($file === "." || $file === "..") {
                continue;
            }
            
            $path = $dir . "/" . $file;
            
            if (@is_file($path)) {
                $size += @filesize($path);
            } elseif (@is_dir($path)) {
                $size += $this-&gt;get_dir_size($path);
            }
        }
        
        return $size;
    }
    
    /**
     * 统计文件数量（递归）
     */
    private function count_files($dir) {
        $count = 0;
        
        if (!@is_dir($dir)) {
            return 0;
        }
        
        $files = @scandir($dir);
        if ($files === false) {
            return 0;
        }
        
        foreach ($files as $file) {
            if ($file === "." || $file === "..") {
                continue;
            }
            
            $path = $dir . "/" . $file;
            
            if (@is_file($path)) {
                $count++;
            } elseif (@is_dir($path)) {
                $count += $this-&gt;count_files($path);
            }
        }
        
        return $count;
    }
    
    /**
     * 获取示例缓存 MD5
     */
    private function get_sample_cache_md5() {
        $scheme = "https";
        $method = "GET";
        $host = $this-&gt;get_domains()[0] ?? "example.com";
        $path = "/";

        $cache_key_string = $scheme . $method . $host . $path;
        $md5 = md5($cache_key_string);

        $level1 = substr($md5, -1);
        $level2 = substr($md5, -3, 2);
        $file_path = $this-&gt;cache_path . "/" . $level1 . "/" . $level2 . "/" . $md5;

        return array(
            "key" =&gt; $cache_key_string,
            "md5" =&gt; $md5,
            "path" =&gt; $file_path,
        );
    }

    /**
     * 获取缓存路径列表（通过 Lua 脚本）
     */
    private function get_cache_paths() {
        // 获取域名列表，使用第一个域名作为 Host
        $domains = $this-&gt;get_domains();
        if (empty($domains)) {
            return array("error" =&gt; "未配置域名");
        }

        $host = $domains[0];
        $url = "http://127.0.0.1/cache-paths";

        $args = array(
            "method" =&gt; "GET",
            "timeout" =&gt; 30,
            "headers" =&gt; array(
                "Host" =&gt; $host,
            ),
            "sslverify" =&gt; false,
            "blocking" =&gt; true,
        );

        $response = wp_remote_request($url, $args);

        if (is_wp_error($response)) {
            return array("error" =&gt; "HTTP 请求失败: " . $response-&gt;get_error_message());
        }

        $code = wp_remote_retrieve_response_code($response);
        $body = wp_remote_retrieve_body($response);

        if ($code != 200) {
            return array("error" =&gt; "请求失败 (HTTP {$code}): " . $body);
        }

        $json = json_decode($body, true);
        if (!$json || !isset($json["status"]) || $json["status"] != "success") {
            return array("error" =&gt; "响应格式错误: " . $body);
        }

        return $json["paths"] ?? array();
    }
    
    /**
     * 清除全部缓存
     */
    private function purge_all_cache() {
        $result = array(
            "success" =&gt; false,
            "message" =&gt; "",
            "deleted_count" =&gt; 0,
        );
        
        // 优先使用 HTTP 请求调用 Lua 脚本（与现有机制一致，避免权限问题）
        $http_result = $this-&gt;purge_all_cache_via_http();
        if ($http_result["success"]) {
            return $http_result;
        }
        
        // 如果 HTTP 请求失败，回退到直接文件操作
        if ($this-&gt;debug) {
            $this-&gt;log("HTTP 清除全部缓存失败，尝试使用文件系统方式: " . $http_result["message"]);
        }
        
        // 检查文件系统访问权限
        if ($this-&gt;fs_access_cache === null) {
            $this-&gt;fs_access_cache = $this-&gt;check_fs_access();
        }
        
        // 使用 shell 命令（更快更可靠）
        if (function_exists("exec")) {
            $disabled_functions = explode(",", ini_get("disable_functions"));
            if (!in_array("exec", $disabled_functions)) {
                return $this-&gt;purge_all_cache_via_shell();
            }
        }
        
        // 回退到 PHP 文件系统函数
        if ($this-&gt;fs_access_cache) {
            return $this-&gt;purge_all_cache_via_php();
        }
        
        $result["message"] = "无法清除缓存，请检查权限或 Nginx 配置";
        return $result;
    }
    
    /**
     * 通过 HTTP 请求调用 Lua 脚本清除全部缓存
     */
    private function purge_all_cache_via_http() {
        $result = array(
            "success" =&gt; false,
            "message" =&gt; "",
            "deleted_count" =&gt; 0,
        );
        
        // 获取域名列表，使用第一个域名作为 Host（清除全部缓存只需要调用一次）
        $domains = $this-&gt;get_domains();
        if (empty($domains)) {
            $result["message"] = "未配置域名";
            return $result;
        }
        
        $host = $domains[0]; // 使用第一个域名
        $purge_url = "http://127.0.0.1/purge-all"; // 使用本地回环，避免外部网络开销
        
        $args = array(
            "method" =&gt; "GET",
            "timeout" =&gt; 30, // 清除全部缓存可能需要较长时间
            "headers" =&gt; array(
                "Host" =&gt; $host,
            ),
            "sslverify" =&gt; false,
            "blocking" =&gt; true, // 必须阻塞，否则无法判断结果
        );
        
        $response = wp_remote_request($purge_url, $args);
        
        if (is_wp_error($response)) {
            $result["message"] = "HTTP 请求失败: " . $response-&gt;get_error_message();
            if ($this-&gt;debug) {
                $this-&gt;log(sprintf("HTTP PURGE-ALL 失败: %s - %s", $purge_url, $response-&gt;get_error_message()));
            }
            return $result;
        }
        
        $code = wp_remote_retrieve_response_code($response);
        $body = wp_remote_retrieve_body($response);
        
        // 解析 JSON 响应
        $json = json_decode($body, true);
        
        if ($code == 200 &amp;&amp; $json &amp;&amp; isset($json["status"]) &amp;&amp; $json["status"] == "success") {
            $result["success"] = true;
            $result["deleted_count"] = isset($json["deleted_count"]) ? intval($json["deleted_count"]) : 0;
            $result["message"] = isset($json["message"]) ? $json["message"] : "缓存清除成功";
            
            if ($this-&gt;debug) {
                $this-&gt;log(sprintf("HTTP PURGE-ALL 成功: %s (code=%d, deleted=%d)", $purge_url, $code, $result["deleted_count"]));
            }
        } else {
            $error_msg = isset($json["message"]) ? $json["message"] : "未知错误";
            $result["message"] = sprintf("清除失败 (HTTP %d): %s", $code, $error_msg);
            
            if ($this-&gt;debug) {
                $this-&gt;log(sprintf("HTTP PURGE-ALL 失败: %s (code=%d) - %s", $purge_url, $code, $error_msg));
            }
        }
        
        return $result;
    }
    
    /**
     * 通过 shell 命令清除全部缓存
     */
    private function purge_all_cache_via_shell() {
        $result = array(
            "success" =&gt; false,
            "message" =&gt; "",
            "deleted_count" =&gt; 0,
        );
        
        // 先统计文件数量
        $count_command = sprintf("find %s -type f 2&gt;/dev/null | wc -l", escapeshellarg($this-&gt;cache_path));
        @exec($count_command, $count_output, $count_return);
        $file_count_before = ($count_return === 0 &amp;&amp; !empty($count_output)) ? intval(trim($count_output[0])) : 0;
        
        // 删除所有缓存文件
        $delete_command = sprintf("find %s -type f -delete 2&gt;/dev/null", escapeshellarg($this-&gt;cache_path));
        @exec($delete_command, $delete_output, $delete_return);
        
        if ($delete_return === 0) {
            $result["success"] = true;
            $result["deleted_count"] = $file_count_before;
            $result["message"] = sprintf("成功清除 %d 个缓存文件", $file_count_before);
            
            if ($this-&gt;debug) {
                $this-&gt;log(sprintf("清除全部缓存成功，删除 %d 个文件", $file_count_before));
            }
        } else {
            $result["message"] = "清除缓存失败，请检查权限";
        }
        
        return $result;
    }
    
    /**
     * 通过 PHP 文件系统函数清除全部缓存
     */
    private function purge_all_cache_via_php() {
        $result = array(
            "success" =&gt; false,
            "message" =&gt; "",
            "deleted_count" =&gt; 0,
        );
        
        if (!@is_dir($this-&gt;cache_path)) {
            $result["message"] = "缓存目录不存在";
            return $result;
        }
        
        $deleted_count = 0;
        $this-&gt;delete_dir_contents($this-&gt;cache_path, $deleted_count);
        
        $result["success"] = true;
        $result["deleted_count"] = $deleted_count;
        $result["message"] = sprintf("成功清除 %d 个缓存文件", $deleted_count);
        
        if ($this-&gt;debug) {
            $this-&gt;log(sprintf("清除全部缓存成功，删除 %d 个文件", $deleted_count));
        }
        
        return $result;
    }
    
    /**
     * 递归删除目录内容（保留目录结构）
     */
    private function delete_dir_contents($dir, &amp;$deleted_count) {
        if (!@is_dir($dir)) {
            return;
        }
        
        $files = @scandir($dir);
        if ($files === false) {
            return;
        }
        
        foreach ($files as $file) {
            if ($file === "." || $file === "..") {
                continue;
            }
            
            $path = $dir . "/" . $file;
            
            if (@is_file($path)) {
                if (@unlink($path)) {
                    $deleted_count++;
                }
            } elseif (@is_dir($path)) {
                $this-&gt;delete_dir_contents($path, $deleted_count);
                // 删除空目录
                @rmdir($path);
            }
        }
    }
    
    /**
     * 格式化字节大小
     */
    private function format_bytes($bytes, $precision = 2) {
        $units = array("B", "KB", "MB", "GB", "TB");
        
        $bytes = max($bytes, 0);
        $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
        $pow = min($pow, count($units) - 1);
        
        $bytes /= pow(1024, $pow);
        
        return round($bytes, $precision) . " " . $units[$pow];
    }
}

// 初始化插件
if (class_exists("Nginx_Cache_Purge_Multi_Domain")) {
    new Nginx_Cache_Purge_Multi_Domain();
}
</pre>
<p>6.重启openresty ，启用wp插件：</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">systemclt reload openresty</pre>
<p>实际效果 <a href="https://www.itdog.cn/http/https://zhongxiaojie.cn" target="_blank" rel="noopener">快速测试</a>：</p>
<p><a href="https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205053.png" data-lbwps-width="1890" data-lbwps-height="1357" data-lbwps-srcsmall="https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205053-665x477.png" data-lightbox="gal[270]"><img decoding="async" class="alignnone size-full wp-image-271" src="https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205053.png" alt="" width="1890" height="1357" srcset="https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205053.png?v=1769518277 1890w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205053-300x215.png?v=1769518277 300w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205053-1024x735.png?v=1769518277 1024w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205053-150x108.png?v=1769518277 150w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205053-768x551.png?v=1769518277 768w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205053-1536x1103.png?v=1769518277 1536w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205053-665x477.png?v=1769518277 665w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205053-362x260.png?v=1769518277 362w" sizes="(max-width: 1890px) 100vw, 1890px" /></a></p>
<p>系统负载 btop：</p>
<p><a href="https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205217.png" data-lbwps-width="3075" data-lbwps-height="1890" data-lbwps-srcsmall="https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205217-665x409.png" data-lightbox="gal[270]"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-272" src="https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205217-scaled.png" alt="" width="2560" height="1573" srcset="https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205217-scaled.png?v=1769518357 2560w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205217-300x184.png?v=1769518357 300w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205217-1024x629.png?v=1769518357 1024w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205217-150x92.png?v=1769518357 150w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205217-768x472.png?v=1769518357 768w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205217-1536x944.png?v=1769518357 1536w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205217-2048x1259.png?v=1769518357 2048w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205217-665x409.png?v=1769518357 665w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205217-423x260.png?v=1769518357 423w" sizes="auto, (max-width: 2560px) 100vw, 2560px" /></a></p>
<p>lighthouse:</p>
<p><a href="https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205341.png" data-lbwps-width="3766" data-lbwps-height="1888" data-lbwps-srcsmall="https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205341-665x333.png" data-lightbox="gal[270]"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-273" src="https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205341-scaled.png" alt="" width="2560" height="1283" srcset="https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205341-scaled.png?v=1769518449 2560w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205341-300x150.png?v=1769518449 300w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205341-1024x513.png?v=1769518449 1024w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205341-150x75.png?v=1769518449 150w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205341-768x385.png?v=1769518449 768w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205341-1536x770.png?v=1769518449 1536w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205341-2048x1027.png?v=1769518449 2048w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205341-665x333.png?v=1769518449 665w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205341-519x260.png?v=1769518449 519w" sizes="auto, (max-width: 2560px) 100vw, 2560px" /></a></p>
<p>缓存管理：</p>
<p><a href="https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205448.png" data-lbwps-width="1472" data-lbwps-height="1848" data-lbwps-srcsmall="https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205448.png" data-lightbox="gal[270]"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-274" src="https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205448.png" alt="" width="1472" height="1848" srcset="https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205448.png?v=1769518502 1472w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205448-239x300.png?v=1769518502 239w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205448-816x1024.png?v=1769518502 816w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205448-119x150.png?v=1769518502 119w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205448-768x964.png?v=1769518502 768w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205448-1223x1536.png?v=1769518502 1223w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205448-665x835.png?v=1769518502 665w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/Screenshot-2026-01-27-205448-207x260.png?v=1769518502 207w" sizes="auto, (max-width: 1472px) 100vw, 1472px" /></a></p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zhongxiaojie.cn/2026/01/270/feed/</wfw:commentRss>
			<slash:comments>68</slash:comments>
		
		
			</item>
		<item>
		<title>PHP 8 探针 粉萌版</title>
		<link>https://zhongxiaojie.cn/2026/01/79/</link>
					<comments>https://zhongxiaojie.cn/2026/01/79/#comments</comments>
		
		<dc:creator><![CDATA[obaby]]></dc:creator>
		<pubDate>Fri, 16 Jan 2026 06:08:52 +0000</pubDate>
				<category><![CDATA[程序媛]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[探针]]></category>
		<guid isPermaLink="false">https://zhongxiaojie.cn/?p=79</guid>

					<description><![CDATA[一个功能强大的 PHP 服务器环境探针工具，支持 PHP 7.x 和 PHP 8.x 全系列版本。 下载地址： [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116140808_530_42.jpg" data-lbwps-width="1280" data-lbwps-height="1920" data-lbwps-srcsmall="https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116140808_530_42.jpg" data-lightbox="gal[79]"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-81" src="https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116140808_530_42.jpg" alt="" width="1280" height="1920" srcset="https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116140808_530_42.jpg?v=1768543721 1280w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116140808_530_42-200x300.jpg?v=1768543721 200w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116140808_530_42-683x1024.jpg?v=1768543721 683w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116140808_530_42-768x1152.jpg?v=1768543721 768w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116140808_530_42-1024x1536.jpg?v=1768543721 1024w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116140808_530_42-665x998.jpg?v=1768543721 665w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116140808_530_42-173x260.jpg?v=1768543721 173w" sizes="auto, (max-width: 1280px) 100vw, 1280px" /></a></p>
<p>一个功能强大的 PHP 服务器环境探针工具，支持 PHP 7.x 和 PHP 8.x 全系列版本。</p>
<p><span id="more-79"></span></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-80" src="https://zhongxiaojie.cn/wp-content/uploads/2026/01/2026-01-16-14.06.11-zhongxiaojie.com-67af5889e303-scaled.jpg" alt="" width="1168" height="2560" srcset="https://zhongxiaojie.cn/wp-content/uploads/2026/01/2026-01-16-14.06.11-zhongxiaojie.com-67af5889e303-scaled.jpg?v=1768543599 1168w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/2026-01-16-14.06.11-zhongxiaojie.com-67af5889e303-137x300.jpg?v=1768543599 137w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/2026-01-16-14.06.11-zhongxiaojie.com-67af5889e303-467x1024.jpg?v=1768543599 467w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/2026-01-16-14.06.11-zhongxiaojie.com-67af5889e303-768x1684.jpg?v=1768543599 768w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/2026-01-16-14.06.11-zhongxiaojie.com-67af5889e303-701x1536.jpg?v=1768543599 701w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/2026-01-16-14.06.11-zhongxiaojie.com-67af5889e303-934x2048.jpg?v=1768543599 934w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/2026-01-16-14.06.11-zhongxiaojie.com-67af5889e303-665x1458.jpg?v=1768543599 665w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/2026-01-16-14.06.11-zhongxiaojie.com-67af5889e303-119x260.jpg?v=1768543599 119w" sizes="auto, (max-width: 1168px) 100vw, 1168px" /></p>
<p>下载地址：https://gitee.com/obaby/php8-probe</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zhongxiaojie.cn/2026/01/79/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>警告（禁止）	unserialize(): Error at offset 4351 of 4374 bytes</title>
		<link>https://zhongxiaojie.cn/2026/01/73/</link>
					<comments>https://zhongxiaojie.cn/2026/01/73/#comments</comments>
		
		<dc:creator><![CDATA[obaby]]></dc:creator>
		<pubDate>Fri, 16 Jan 2026 02:44:15 +0000</pubDate>
				<category><![CDATA[程序媛]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WP]]></category>
		<guid isPermaLink="false">https://zhongxiaojie.cn/?p=73</guid>

					<description><![CDATA[解决数据库替换 url 导致的错误。 警告（禁止） unserialize(): Error at offse [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116104025_529_42.jpg" data-lbwps-width="1280" data-lbwps-height="1920" data-lbwps-srcsmall="https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116104025_529_42.jpg" data-lightbox="gal[73]"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-74" src="https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116104025_529_42.jpg" alt="" width="1280" height="1920" srcset="https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116104025_529_42.jpg?v=1768531341 1280w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116104025_529_42-200x300.jpg?v=1768531341 200w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116104025_529_42-683x1024.jpg?v=1768531341 683w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116104025_529_42-768x1152.jpg?v=1768531341 768w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116104025_529_42-1024x1536.jpg?v=1768531341 1024w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116104025_529_42-665x998.jpg?v=1768531341 665w, https://zhongxiaojie.cn/wp-content/uploads/2026/01/微信图片_20260116104025_529_42-173x260.jpg?v=1768531341 173w" sizes="auto, (max-width: 1280px) 100vw, 1280px" /></a></p>
<p>解决数据库替换 url 导致的错误。</p>
<p><span id="more-73"></span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">警告（禁止）	unserialize(): Error at offset 4351 of 4374 bytes	
wp-includes/functions.php:655
unserialize()
wp-includes/functions.php:655
maybe_unserialize()
wp-includes/functions.php:655
array_map()
wp-includes/meta.php:692
get_metadata_raw()
wp-includes/meta.php:602
get_metadata()
wp-includes/post.php:2712
get_post_meta()
wp-admin/includes/class-wp-privacy-policy-content.php:69
WP_Privacy_Policy_Content::text_change_check()
wp-includes/class-wp-hook.php:341
do_action('admin_init')
wp-admin/admin.php:180</pre>
<p>修复代码：</p>
<pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php
/**
 * WordPress 序列化数据修复脚本
 * 修复因直接 SQL REPLACE 导致的序列化数据损坏问题
 * 
 * 使用方法：
 * 1. 修改下面的数据库连接信息
 * 2. 在命令行运行: php fix-unserialize-error.php
 * 3. 或者通过浏览器访问（需要配置 web 服务器）
 */

// ========== 配置区域 ==========
define('DB_HOST', '127.0.0.1');
define('DB_NAME', 'zxj');
define('DB_USER', 'root');
define('DB_PASS', 'zxj');
define('DB_PREFIX', 'wp_'); // 表前缀

// 旧 URL 和新 URL（用于修复）
define('OLD_URL', 'http://test.h4ck.org.cn:18888');
define('NEW_URL', 'https://zhongxiaojie.cn');

// ========== 主程序 ==========

// 连接数据库
try {
    $pdo = new PDO(
        "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4",
        DB_USER,
        DB_PASS,
        [
            PDO::ATTR_ERRMODE =&gt; PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE =&gt; PDO::FETCH_ASSOC
        ]
    );
} catch (PDOException $e) {
    die("数据库连接失败: " . $e-&gt;getMessage() . "\n");
}

echo "==========================================\n";
echo "WordPress 序列化数据修复工具\n";
echo "==========================================\n\n";

/**
 * 修复序列化字符串中的 URL
 * 正确更新序列化数据中的长度信息
 */
function fix_serialized_url($serialized, $old_url, $new_url) {
    // 如果不是序列化数据，直接替换
    if (!is_serialized($serialized)) {
        return str_replace($old_url, $new_url, $serialized);
    }
    
    // 尝试反序列化
    $data = @unserialize($serialized);
    
    // 如果反序列化失败，尝试修复
    if ($data === false &amp;&amp; $serialized !== serialize(false)) {
        // 尝试修复常见的序列化问题
        $fixed = fix_broken_serialize($serialized, $old_url, $new_url);
        $data = @unserialize($fixed);
        
        if ($data === false &amp;&amp; $fixed !== serialize(false)) {
            return false; // 无法修复
        }
        
        $serialized = $fixed;
        $data = @unserialize($serialized);
    }
    
    // 递归替换数组或对象中的 URL
    if (is_array($data)) {
        $data = array_map(function($value) use ($old_url, $new_url) {
            if (is_string($value)) {
                return str_replace($old_url, $new_url, $value);
            } elseif (is_array($value)) {
                return array_map(function($v) use ($old_url, $new_url) {
                    return is_string($v) ? str_replace($old_url, $new_url, $v) : $v;
                }, $value);
            }
            return $value;
        }, $data);
    } elseif (is_object($data)) {
        foreach ($data as $key =&gt; $value) {
            if (is_string($value)) {
                $data-&gt;$key = str_replace($old_url, $new_url, $value);
            }
        }
    } elseif (is_string($data)) {
        $data = str_replace($old_url, $new_url, $data);
    }
    
    // 重新序列化
    return serialize($data);
}

/**
 * 检查字符串是否是序列化数据
 */
function is_serialized($data) {
    if (!is_string($data)) {
        return false;
    }
    $data = trim($data);
    if ('N;' == $data) {
        return true;
    }
    if (strlen($data) &lt; 4) {
        return false;
    }
    if (':' !== $data[1]) {
        return false;
    }
    $semi = strpos($data, ';');
    if (false === $semi) {
        return false;
    }
    $token = $data[0];
    switch ($token) {
        case 's':
            if ('"' !== $data[$semi - 1]) {
                return false;
            }
        case 'a':
        case 'O':
            return (bool) preg_match("/^{$token}:[0-9]+:/s", $data);
        case 'b':
        case 'i':
        case 'd':
            return (bool) preg_match("/^{$token}:[0-9.E-]+;/", $data);
    }
    return false;
}

/**
 * 尝试修复损坏的序列化数据
 */
function fix_broken_serialize($serialized, $old_url = null, $new_url = null) {
    // 如果包含旧 URL，先替换
    if ($old_url &amp;&amp; $new_url &amp;&amp; strpos($serialized, $old_url) !== false) {
        $serialized = str_replace($old_url, $new_url, $serialized);
    }
    
    // 尝试修复长度信息
    // 匹配字符串长度模式: s:数字:"内容"
    // 注意：需要处理转义字符和嵌套引号
    $pattern = '/s:(\d+):"((?:[^"\\\\]|\\\\.)*)"/';
    $serialized = preg_replace_callback($pattern, function($matches) {
        // 计算实际字符串长度（考虑转义字符）
        $str = $matches[2];
        $length = strlen($str);
        return 's:' . $length . ':"' . $str . '"';
    }, $serialized);
    
    return $serialized;
}

/**
 * 检测并修复损坏的序列化数据
 */
function detect_and_fix_broken_serialize($serialized) {
    // 如果不是序列化数据，直接返回
    if (!is_serialized($serialized)) {
        return ['fixed' =&gt; false, 'data' =&gt; $serialized, 'error' =&gt; null];
    }
    
    // 清除之前的错误
    @error_clear_last();
    
    // 尝试反序列化
    $data = @unserialize($serialized);
    
    // 检查是否有错误
    $error = error_get_last();
    
    // 如果反序列化成功且没有错误，返回原数据
    if ($data !== false &amp;&amp; ($error === null || strpos($error['message'], 'unserialize') === false)) {
        // 特殊处理：false 的序列化结果是 'b:0;'
        if ($serialized === 'b:0;' || $serialized === serialize(false)) {
            return ['fixed' =&gt; false, 'data' =&gt; $serialized, 'error' =&gt; null];
        }
        return ['fixed' =&gt; false, 'data' =&gt; $serialized, 'error' =&gt; null];
    }
    
    // 反序列化失败，记录错误
    $original_error = $error ? $error['message'] : 'Unserialize failed';
    
    // 尝试修复长度信息
    $fixed = fix_broken_serialize($serialized);
    @error_clear_last();
    $test_data = @unserialize($fixed);
    $test_error = error_get_last();
    
    if ($test_data !== false &amp;&amp; ($test_error === null || strpos($test_error['message'], 'unserialize') === false)) {
        return ['fixed' =&gt; true, 'data' =&gt; $fixed, 'error' =&gt; $original_error];
    }
    
    // 如果还是失败，尝试更激进的修复
    // 修复所有字符串长度（更精确的匹配）
    $fixed2 = preg_replace_callback('/s:(\d+):"((?:[^"\\\\]|\\\\.)*)"/', function($m) {
        $str = $m[2];
        $len = strlen($str);
        return 's:' . $len . ':"' . $str . '"';
    }, $serialized);
    
    @error_clear_last();
    $test_data2 = @unserialize($fixed2);
    $test_error2 = error_get_last();
    
    if ($test_data2 !== false &amp;&amp; ($test_error2 === null || strpos($test_error2['message'], 'unserialize') === false)) {
        return ['fixed' =&gt; true, 'data' =&gt; $fixed2, 'error' =&gt; $original_error];
    }
    
    return ['fixed' =&gt; false, 'data' =&gt; $serialized, 'error' =&gt; $original_error];
}

$fixed_count = 0;
$error_count = 0;
$broken_count = 0;

// 修复 wp_postmeta 表
echo "[1/4] 检查 wp_postmeta 表中的序列化数据...\n";

// 首先查找所有序列化数据
$stmt = $pdo-&gt;prepare("SELECT meta_id, post_id, meta_key, meta_value FROM " . DB_PREFIX . "postmeta WHERE meta_value LIKE 'a:%' OR meta_value LIKE 'O:%' OR meta_value LIKE 's:%' OR meta_value LIKE 'i:%' OR meta_value LIKE 'b:%' OR meta_value LIKE 'd:%'");
$stmt-&gt;execute();
$all_serialized = $stmt-&gt;fetchAll();

echo "找到 " . count($all_serialized) . " 条可能的序列化数据记录\n";
echo "开始检测损坏的数据...\n\n";

$update_stmt = $pdo-&gt;prepare("UPDATE " . DB_PREFIX . "postmeta SET meta_value = ? WHERE meta_id = ?");
$broken_records = [];

foreach ($all_serialized as $row) {
    $result = detect_and_fix_broken_serialize($row['meta_value']);
    
    if ($result['fixed']) {
        $broken_count++;
        $broken_records[] = [
            'meta_id' =&gt; $row['meta_id'],
            'post_id' =&gt; $row['post_id'],
            'meta_key' =&gt; $row['meta_key'],
            'error' =&gt; $result['error']
        ];
        
        try {
            $update_stmt-&gt;execute([$result['data'], $row['meta_id']]);
            $fixed_count++;
            if ($fixed_count % 10 == 0) {
                echo "  已修复 {$fixed_count} 条损坏的记录...\n";
            }
        } catch (PDOException $e) {
            echo "  ✗ 更新失败 meta_id={$row['meta_id']}: " . $e-&gt;getMessage() . "\n";
            $error_count++;
        }
    }
}

if ($broken_count &gt; 0) {
    echo "\n发现并修复了 {$broken_count} 条损坏的序列化数据\n";
    if (count($broken_records) &lt;= 20) {
        echo "\n损坏的记录详情：\n";
        foreach ($broken_records as $rec) {
            echo "  - meta_id={$rec['meta_id']}, post_id={$rec['post_id']}, meta_key={$rec['meta_key']}\n";
        }
    }
} else {
    echo "未发现损坏的序列化数据\n";
}

// 也检查包含旧 URL 的记录（即使已经修复了长度问题，URL 可能还需要更新）
echo "\n检查是否还有包含旧 URL 的记录...\n";
$stmt = $pdo-&gt;prepare("SELECT meta_id, post_id, meta_key, meta_value FROM " . DB_PREFIX . "postmeta WHERE meta_value LIKE ?");
$stmt-&gt;execute(['%' . OLD_URL . '%']);
$url_rows = $stmt-&gt;fetchAll();

if (count($url_rows) &gt; 0) {
    echo "找到 " . count($url_rows) . " 条包含旧 URL 的记录，正在修复...\n";
    foreach ($url_rows as $row) {
        $original = $row['meta_value'];
        $fixed = fix_serialized_url($original, OLD_URL, NEW_URL);
        
        if ($fixed !== false &amp;&amp; $fixed !== $original) {
            try {
                $update_stmt-&gt;execute([$fixed, $row['meta_id']]);
                $fixed_count++;
            } catch (PDOException $e) {
                $error_count++;
            }
        }
    }
}

echo "\n[2/4] 检查 wp_options 表中的序列化数据...\n";

// 检查所有序列化数据
$stmt = $pdo-&gt;prepare("SELECT option_id, option_name, option_value FROM " . DB_PREFIX . "options WHERE option_value LIKE 'a:%' OR option_value LIKE 'O:%' OR option_value LIKE 's:%' OR option_value LIKE 'i:%' OR option_value LIKE 'b:%' OR option_value LIKE 'd:%'");
$stmt-&gt;execute();
$all_options = $stmt-&gt;fetchAll();

echo "找到 " . count($all_options) . " 条可能的序列化选项\n";
echo "开始检测损坏的数据...\n\n";

$update_stmt = $pdo-&gt;prepare("UPDATE " . DB_PREFIX . "options SET option_value = ? WHERE option_id = ?");
$broken_options = [];

foreach ($all_options as $row) {
    // 跳过 siteurl 和 home
    if (in_array($row['option_name'], ['siteurl', 'home'])) {
        continue;
    }
    
    $result = detect_and_fix_broken_serialize($row['option_value']);
    
    if ($result['fixed']) {
        $broken_count++;
        $broken_options[] = [
            'option_id' =&gt; $row['option_id'],
            'option_name' =&gt; $row['option_name'],
            'error' =&gt; $result['error']
        ];
        
        try {
            $update_stmt-&gt;execute([$result['data'], $row['option_id']]);
            $fixed_count++;
        } catch (PDOException $e) {
            $error_count++;
        }
    }
}

if (count($broken_options) &gt; 0) {
    echo "发现并修复了 " . count($broken_options) . " 条损坏的选项\n";
    if (count($broken_options) &lt;= 20) {
        echo "\n损坏的选项详情：\n";
        foreach ($broken_options as $opt) {
            echo "  - option_id={$opt['option_id']}, option_name={$opt['option_name']}\n";
        }
    }
}

// 检查包含旧 URL 的选项
echo "\n检查是否还有包含旧 URL 的选项...\n";
$stmt = $pdo-&gt;prepare("SELECT option_id, option_name, option_value FROM " . DB_PREFIX . "options WHERE option_value LIKE ?");
$stmt-&gt;execute(['%' . OLD_URL . '%']);
$url_options = $stmt-&gt;fetchAll();

if (count($url_options) &gt; 0) {
    echo "找到 " . count($url_options) . " 条包含旧 URL 的选项，正在修复...\n";
    foreach ($url_options as $row) {
        if (in_array($row['option_name'], ['siteurl', 'home'])) {
            continue;
        }
        
        $original = $row['option_value'];
        $fixed = fix_serialized_url($original, OLD_URL, NEW_URL);
        
        if ($fixed !== false &amp;&amp; $fixed !== $original) {
            try {
                $update_stmt-&gt;execute([$fixed, $row['option_id']]);
                $fixed_count++;
            } catch (PDOException $e) {
                $error_count++;
            }
        }
    }
}

echo "\n[3/4] 检查其他元数据表...\n";
$tables = [
    DB_PREFIX . 'usermeta' =&gt; ['umeta_id', 'user_id', 'meta_key', 'meta_value'],
    DB_PREFIX . 'commentmeta' =&gt; ['meta_id', 'comment_id', 'meta_key', 'meta_value'],
    DB_PREFIX . 'termmeta' =&gt; ['meta_id', 'term_id', 'meta_key', 'meta_value']
];

foreach ($tables as $table =&gt; $columns) {
    if (!table_exists($pdo, $table)) {
        continue;
    }
    
    echo "检查 {$table}...\n";
    
    // 检查所有序列化数据
    $stmt = $pdo-&gt;prepare("SELECT {$columns[0]}, {$columns[1]}, {$columns[2]}, {$columns[3]} FROM {$table} WHERE {$columns[3]} LIKE 'a:%' OR {$columns[3]} LIKE 'O:%' OR {$columns[3]} LIKE 's:%' OR {$columns[3]} LIKE 'i:%' OR {$columns[3]} LIKE 'b:%' OR {$columns[3]} LIKE 'd:%'");
    $stmt-&gt;execute();
    $all_rows = $stmt-&gt;fetchAll();
    
    if (count($all_rows) &gt; 0) {
        echo "  找到 " . count($all_rows) . " 条序列化数据，检测中...\n";
        $update_stmt = $pdo-&gt;prepare("UPDATE {$table} SET {$columns[3]} = ? WHERE {$columns[0]} = ?");
        
        foreach ($all_rows as $row) {
            $result = detect_and_fix_broken_serialize($row[$columns[3]]);
            
            if ($result['fixed']) {
                $broken_count++;
                try {
                    $update_stmt-&gt;execute([$result['data'], $row[$columns[0]]]);
                    $fixed_count++;
                } catch (PDOException $e) {
                    $error_count++;
                }
            }
        }
    }
    
    // 也检查包含旧 URL 的记录
    $stmt = $pdo-&gt;prepare("SELECT {$columns[0]}, {$columns[1]}, {$columns[2]}, {$columns[3]} FROM {$table} WHERE {$columns[3]} LIKE ?");
    $stmt-&gt;execute(['%' . OLD_URL . '%']);
    $url_rows = $stmt-&gt;fetchAll();
    
    if (count($url_rows) &gt; 0) {
        echo "  找到 " . count($url_rows) . " 条包含旧 URL 的记录，正在修复...\n";
        $update_stmt = $pdo-&gt;prepare("UPDATE {$table} SET {$columns[3]} = ? WHERE {$columns[0]} = ?");
        
        foreach ($url_rows as $row) {
            $original = $row[$columns[3]];
            $fixed = fix_serialized_url($original, OLD_URL, NEW_URL);
            
            if ($fixed !== false &amp;&amp; $fixed !== $original) {
                try {
                    $update_stmt-&gt;execute([$fixed, $row[$columns[0]]]);
                    $fixed_count++;
                } catch (PDOException $e) {
                    $error_count++;
                }
            }
        }
    }
}

echo "\n[4/4] 查找可能导致错误的特定记录...\n";
echo "根据错误信息 'Error at offset 4351 of 4374 bytes'，查找长度接近的记录...\n";

// 查找长度在 4300-4400 字节之间的序列化数据
$stmt = $pdo-&gt;prepare("SELECT meta_id, post_id, meta_key, meta_value, LENGTH(meta_value) as value_length FROM " . DB_PREFIX . "postmeta WHERE (meta_value LIKE 'a:%' OR meta_value LIKE 'O:%' OR meta_value LIKE 's:%') AND LENGTH(meta_value) BETWEEN 4300 AND 4400 ORDER BY value_length");
$stmt-&gt;execute();
$suspicious = $stmt-&gt;fetchAll();

if (count($suspicious) &gt; 0) {
    echo "找到 " . count($suspicious) . " 条可疑记录（长度在 4300-4400 字节之间）\n";
    echo "这些记录可能是导致错误的原因：\n\n";
    
    $update_stmt = $pdo-&gt;prepare("UPDATE " . DB_PREFIX . "postmeta SET meta_value = ? WHERE meta_id = ?");
    
    foreach ($suspicious as $sus) {
        echo "  - meta_id={$sus['meta_id']}, post_id={$sus['post_id']}, meta_key={$sus['meta_key']}, length={$sus['value_length']}\n";
        
        // 直接尝试反序列化完整数据
        @error_clear_last();
        $test_data = @unserialize($sus['meta_value']);
        $test_error = error_get_last();
        
        // 检查是否有 unserialize 错误
        if ($test_error &amp;&amp; strpos($test_error['message'], 'unserialize') !== false) {
            echo "    ✗ 检测到损坏: {$test_error['message']}\n";
            echo "    正在修复...\n";
            
            // 尝试修复
            $fix_result = detect_and_fix_broken_serialize($sus['meta_value']);
            
            if ($fix_result['fixed']) {
                try {
                    $update_stmt-&gt;execute([$fix_result['data'], $sus['meta_id']]);
                    echo "    ✓ 已修复并更新数据库\n";
                    $fixed_count++;
                    $broken_count++;
                } catch (PDOException $e) {
                    echo "    ✗ 更新失败: " . $e-&gt;getMessage() . "\n";
                    $error_count++;
                }
            } else {
                // 如果自动修复失败，尝试手动修复字符串长度
                echo "    尝试手动修复字符串长度...\n";
                $manual_fixed = preg_replace_callback('/s:(\d+):"((?:[^"\\\\]|\\\\.)*)"/', function($m) {
                    $str = $m[2];
                    $len = strlen($str);
                    if ($len != $m[1]) {
                        return 's:' . $len . ':"' . $str . '"';
                    }
                    return $m[0];
                }, $sus['meta_value']);
                
                @error_clear_last();
                $manual_test = @unserialize($manual_fixed);
                $manual_error = error_get_last();
                
                if ($manual_test !== false &amp;&amp; ($manual_error === null || strpos($manual_error['message'], 'unserialize') === false)) {
                    try {
                        $update_stmt-&gt;execute([$manual_fixed, $sus['meta_id']]);
                        echo "    ✓ 手动修复成功并更新数据库\n";
                        $fixed_count++;
                        $broken_count++;
                    } catch (PDOException $e) {
                        echo "    ✗ 更新失败: " . $e-&gt;getMessage() . "\n";
                        $error_count++;
                    }
                } else {
                    echo "    ✗ 无法修复此记录\n";
                    echo "    建议：如果这个 meta_key 不重要，可以考虑删除\n";
                    echo "    DELETE FROM " . DB_PREFIX . "postmeta WHERE meta_id = {$sus['meta_id']};\n";
                    $error_count++;
                }
            }
        } else {
            echo "    ✓ 数据正常（未检测到错误）\n";
        }
        echo "\n";
    }
}

function table_exists($pdo, $table) {
    try {
        $stmt = $pdo-&gt;query("SHOW TABLES LIKE '{$table}'");
        return $stmt-&gt;rowCount() &gt; 0;
    } catch (PDOException $e) {
        return false;
    }
}

echo "\n==========================================\n";
echo "修复完成！\n";
echo "==========================================\n";
echo "成功修复: {$fixed_count} 条记录\n";
echo "发现损坏: {$broken_count} 条记录\n";
echo "修复失败: {$error_count} 条记录\n";
echo "\n";

if ($fixed_count &gt; 0) {
    echo "✓ 已修复 {$fixed_count} 条损坏的序列化数据\n";
    echo "\n建议：\n";
    echo "1. 清除 WordPress 缓存（对象缓存、页面缓存）\n";
    echo "2. 刷新后台页面，检查错误是否消失\n";
    echo "3. 如果仍有问题，请提供新的错误信息\n";
} else {
    echo "<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 未发现损坏的序列化数据\n";
    echo "\n可能的原因：\n";
    echo "1. 错误来自其他表或数据\n";
    echo "2. 错误是动态生成的（不是数据库中的数据）\n";
    echo "3. 需要查看完整的错误堆栈信息\n";
    echo "\n建议：\n";
    echo "1. 启用 WordPress 调试模式（wp-config.php 中设置 WP_DEBUG = true）\n";
    echo "2. 查看错误日志，找到具体的 meta_id 或 option_id\n";
    echo "3. 检查 wp-includes/functions.php:655 附近的代码\n";
}

echo "\n";
</pre>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zhongxiaojie.cn/2026/01/73/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
