1. 接口简介
Filter_Plugin_Post_Save 是 ZBlogPHP 中非常核心的一个接口(Hook)。顾名思义,它在 文章(或页面)保存成功后 触发。
这个接口是开发插件时处理“后置任务”的最佳切入点。无论是在后台发布文章、编辑旧文章,还是通过 API 接口写入文章,只要调用了 $article->Save() 方法,并在保存成功后,系统都会自动执行挂载在这个接口上的函数。
2. 触发时机
该接口位于 Post::Save() 方法的末尾。
这意味着当你的挂载函数被调用时:
- 数据已落库:文章的数据已经成功写入数据库。
- ID 已生成:如果是新建文章,此时
$article->ID已经有值了(这是与“保存前”接口最大的区别,也是它适合做数据同步的关键原因)。
3. 注册方式
在插件的 include.php 文件的 ActivePlugin_插件ID 函数中进行挂载:
function ActivePlugin_YourPluginID()
{
// 挂载接口
Add_Filter_Plugin('Filter_Plugin_Post_Save', 'YourPlugin_Post_Save');
}
4. 回调函数说明
回调函数接收一个参数,即当前保存成功的文章对象 $article。
/**
* 文章保存后的回调函数
* @param object $article 当前保存的文章对象(Post类型)
*/
function YourPlugin_Post_Save($article)
{
global $zbp;
// 1. 获取文章ID
$id = $article->ID;
// 2. 获取文章标题
$title = $article->Title;
// 3. 判断是新建还是修改?
// 虽然接口本身不直接提供标识,但可以通过业务逻辑判断。
// 通常我们不在意是新建还是修改,只关注“最新状态”。
// 4. 判断文章类型
// ZC_POST_TYPE_ARTICLE (0) 是普通文章
// ZC_POST_TYPE_PAGE (1) 是页面
if ($article->Type == ZC_POST_TYPE_ARTICLE) {
// 处理普通文章逻辑
}
}
5. 常见应用场景
场景一:搜索引擎/三方服务同步(如迅搜、百度推送)
这是最典型的用法。因为此时文章内容已确认为最新,且有 ID,可以将 ID、标题、内容、URL 发送给迅搜建立索引,或推送给百度站长平台。
function YourPlugin_Sync_Xunsearch($article)
{
// 仅同步普通文章
if ($article->Type != ZC_POST_TYPE_ARTICLE) return;
// 获取需要的数据
$data = [
'id' => $article->ID,
'title' => $article->Title,
'content' => $article->Content,
'url' => $article->Url
];
// 调用第三方同步逻辑...
Xunsearch_Update($data);
}
场景二:清除缓存
如果文章更新影响了首页、分类页的显示,可以在这里触发清除静态缓存或删除 Redis 缓存的操作。
场景三:自动生成元数据
比如文章保存后,根据文章内容自动生成摘要(Intro)或提取关键词(Tag),并再次保存(注意:需小心死循环)。
⚠️ 警告:避免死循环
如果你在Filter_Plugin_Post_Save的回调函数中再次调用了$article->Save(),会再次触发Filter_Plugin_Post_Save,导致无限递归死循环。
解决方法:
- 修改
$article属性后只操作数据库(直接 SQL Update),不调用 Save()。- 或者在 Save() 前移除钩子,Save() 后再挂载回来(较为繁琐)。
6. 总结
Filter_Plugin_Post_Save 是 ZBlogPHP 插件开发中处理数据流转的“枢纽”。掌握它,你就可以让你的插件在内容更新的瞬间,即时响应,连接万物。