WordPress文章保存/更新时替换长链接为短URL的问题求助
修复WordPress文章内容自动替换长链接为YOURLS短链接的问题
我看了你的代码,发现几个关键问题导致链接替换没生效,咱们一步步来修复:
核心问题分析
str_replace未赋值:str_replace函数是返回新字符串,不会直接修改原变量,你之前的代码只是调用了函数但没把结果存回$new_content,等于白忙活。- 无重复处理判断:每次保存文章都会重新扫描所有链接,可能导致已经生成的短链接被再次提交到YOURLS,造成重复缩短。
- 缺少错误处理:没有判断CURL请求是否成功,也没处理YOURLS返回错误的情况,容易导致意外问题。
- 钩子逻辑不够严谨:没有排除自动保存、修订版本的情况,可能触发不必要的执行。
修复后的完整代码
add_action( 'save_post', 'replace_long_links_with_yourls', 10, 3 ); function replace_long_links_with_yourls( $post_id, $post, $update ) { // 排除自动保存、修订版本、非公开文章 if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) || $post->post_status !== 'publish' ) { return; } // 定义YOURLS配置 $yapikey = '********'; $api_url = 'https://yourdomain.com/yourls-api.php'; $yourls_domain = parse_url( $api_url, PHP_URL_HOST ); // 获取你的短链接域名,用于跳过已处理的链接 // 匹配文章内容中的所有链接(支持单/双引号的href) preg_match_all( '/<a.*?href=["\']([^"\']+)["\'].*?>(.*?)<\/a>/i', $post->post_content, $matches ); if ( empty( $matches[1] ) ) { return; // 没有链接就直接返回 } $new_content = $post->post_content; foreach ( $matches[1] as $index => $long_url ) { // 跳过已经是我们的短链接的地址,避免重复处理 $link_host = parse_url( $long_url, PHP_URL_HOST ); if ( $link_host === $yourls_domain ) { continue; } // 初始化CURL请求 $ch = curl_init(); curl_setopt( $ch, CURLOPT_URL, $api_url ); curl_setopt( $ch, CURLOPT_HEADER, 0 ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $ch, CURLOPT_POST, 1 ); curl_setopt( $ch, CURLOPT_POSTFIELDS, array( 'url' => $long_url, 'format' => 'json', 'action' => 'shorturl', 'signature' => $yapikey ) ); // 添加SSL验证(如果你的域名是HTTPS) curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, true ); curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 2 ); $response = curl_exec( $ch ); $curl_error = curl_error( $ch ); curl_close( $ch ); // 处理CURL错误 if ( $curl_error ) { error_log( "YOURLS CURL Error: " . $curl_error ); continue; } // 解析返回的JSON $data = json_decode( $response ); if ( !$data || !isset( $data->shorturl ) ) { error_log( "YOURLS API Error: " . ( isset( $data->message ) ? $data->message : 'Invalid response' ) ); continue; } // 替换长链接为短链接(这里一定要赋值给$new_content!) $new_content = str_replace( $long_url, $data->shorturl, $new_content ); } // 只有当内容确实变化了才更新,避免无限循环 if ( $new_content !== $post->post_content ) { // 临时移除钩子防止循环 remove_action( 'save_post', 'replace_long_links_with_yourls' ); wp_update_post( array( 'ID' => $post_id, 'post_content' => $new_content ) ); // 重新添加钩子 add_action( 'save_post', 'replace_long_links_with_yourls', 10, 3 ); } }
关键修改点说明
- 添加过滤条件:排除自动保存、修订版本和非公开文章,减少不必要的执行。
- 修复
str_replace赋值:把替换后的结果存回$new_content,这是你之前代码最核心的问题。 - 跳过已处理链接:通过解析链接域名,判断是否已经是你的短链接,避免重复提交。
- 完善错误处理:添加CURL错误捕获和YOURLS API错误处理,方便排查问题。
- 仅在内容变化时更新:对比新旧内容,只有确实有修改才执行
wp_update_post,避免触发无限循环。
内容的提问来源于stack exchange,提问作者wpdaniel
相关产品推荐
相关产品推荐

