WordPress钩子未触发:自定义站点地图函数无法随文章操作执行
问题排查与解决建议
核心问题分析
你绑定的钩子本身是有效的,大概率是函数执行时的环境问题导致生成sitemap失败,而非钩子未触发。结合你的代码,主要有以下几个关键点:
1. 文件路径错误
$file = 'sitemap.xml' 使用相对路径时,在后台保存文章的场景下,当前工作目录可能不是网站根目录(比如WordPress后台的admin目录),导致file_put_contents无法找到正确路径写入文件。
修复方案:
使用WordPress内置常量获取网站根目录的绝对路径:
$file = ABSPATH . 'sitemap.xml';
2. 未排除自动保存/修订版本
save_post钩子会在自动保存、修订版本创建时触发,这些场景下不需要生成sitemap,还可能导致执行异常。需要在函数开头添加判断:
function makeSitemap(){ // 排除自动保存和修订版本 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return; if (isset($_POST['post_ID']) && wp_is_post_revision($_POST['post_ID'])) return; // 原函数内容... }
3. 钩子绑定的参数不匹配
你的add_action声明了接受2个参数,但匿名函数未接收参数,虽不影响触发,但不符合规范,建议调整为只处理文章/页面类型:
add_action('save_post', function($post_id, $post){ // 仅在文章或页面更新时执行 if (!in_array($post->post_type, ['post', 'page'])) return; makeSitemap(); }, 10, 2);
4. 验证钩子是否真的触发
可以临时添加日志确认钩子执行状态:
function makeSitemap(){ // 临时日志,测试后删除 file_put_contents(ABSPATH . 'sitemap_log.txt', '钩子触发时间:' . date('Y-m-d H:i:s') . "\n", FILE_APPEND); // 原函数内容... }
如果日志文件生成,说明钩子已触发,问题出在后续逻辑(如路径、数据库查询)。
优化后的完整代码
function pull_active_pages(){ global $wpdb; // 用精确匹配替代LIKE,提升查询效率 $query = $wpdb->get_results("SELECT * FROM `wp_posts` WHERE (`post_type` = 'page' OR `post_type` = 'post') AND `post_status` = 'publish';", OBJECT); return $query; } function makeSitemap(){ // 排除自动保存和修订版本 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return; if (isset($_POST['post_ID']) && wp_is_post_revision($_POST['post_ID'])) return; $file = ABSPATH . 'sitemap.xml'; $query = pull_active_pages(); $output = '<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL; $output .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd http://www.google.com/schemas/sitemap-news/0.9 http://www.google.com/schemas/sitemap-news/0.9/sitemap-news.xsd">'.PHP_EOL; foreach((array)$query as $record){ $output .= '<url>'.PHP_EOL; $url = get_permalink($record->ID); // 添加URL转义,避免XML格式错误 $output .= '<loc>' . esc_url($url) . '</loc>'.PHP_EOL; $last_mod = $record->post_modified_gmt; $output .= '<lastmod>' . $last_mod .'</lastmod>'.PHP_EOL; $output .= '<priority>1.00</priority>'.PHP_EOL; $output .= '</url>'.PHP_EOL; } $output .= '</urlset>'; file_put_contents($file, $output); } add_action('save_post', function($post_id, $post){ // 仅处理文章和页面类型 if (!in_array($post->post_type, ['post', 'page'])) return; makeSitemap(); }, 10, 2);
额外优化点:
- 将
LIKE改为精确匹配=,提升数据库查询效率 - 添加
esc_url()处理链接,避免XML中出现特殊字符导致格式错误
内容的提问来源于stack exchange,提问作者billybadass
相关产品推荐
相关产品推荐

