如何在PHP/WordPress中处理含西里尔字母的URL?
修复混合拉丁/西里尔字母的URL抓取问题
问题
开发WordPress WooCommerce插件抓取合作店铺商品URL时,遇到URL包含拉丁字母与西里尔字母混合的情况:
原URL:garvan.bg/collections/шлемови-каски/products/шлемова-каска-размер-л-4
处理后变成:https://www.garvan.bg/collections/-/products/----4
导致访问返回404错误。
原因
sanitize_text_field的过滤问题:该函数会移除所有非ASCII字符(包括西里尔字母),将其替换为横杠,直接破坏URL结构。- 不必要的
urldecode:浏览器提交的URL通常已经是URL编码后的状态,提前解码会导致非ASCII字符暴露,后续处理时被过滤。
解决方案
1. 替换URL清理函数
使用esc_url_raw替代sanitize_text_field,它专门用于处理URL,会保留合法的Unicode字符并确保URL格式正确,不会过滤西里尔字母这类非ASCII字符。
2. 移除不必要的urldecode
除非明确知道URL是双重编码的,否则不要随意使用urldecode,避免破坏URL的编码结构。
3. 确保URL正确编码(可选)
如果输入的URL是未编码的原始字符,需要对路径部分进行URL编码,但注意不要编码域名部分。可以用parse_url拆分URL,对路径部分单独编码后重组。
修改后的代码示例
调试页面处理部分
function link_scraper_debugger_page() { ?> <div class="wrap"> <h1>Link Scraper Debugger</h1> <form method="post" action=""> <label for="scrape_url">Enter URL to Scrape:</label> <input type="text" id="scrape_url" name="scrape_url" style="width: 100%; max-width: 600px;"> <input type="submit" name="scrape_submit" value="Scrape" class="button button-primary"> </form> </div> <?php if (isset($_POST['scrape_submit'])) { // 用esc_url_raw替代sanitize_text_field $url = esc_url_raw($_POST['scrape_url']); if (!empty($url)) { link_scraper_debugger_process($url); } } }
URL处理函数部分
function link_scraper_debugger_process($url) { // 移除不必要的urldecode,直接使用清理后的URL $args = array( 'redirection' => 5, 'headers' => array( 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' ) ); $response = wp_remote_get($url, $args); if (is_wp_error($response)) { echo '<div class="notice notice-error is-dismissible"><p>Failed to fetch URL: ' . $response->get_error_message() . '</p></div>'; return; } // 后续处理逻辑... }
可选:手动编码URL路径(如果输入是未编码的原始URL)
如果用户输入的是未编码的原始URL(直接包含西里尔字母),可以用以下方法确保路径正确编码:
function encode_url_path($url) { $parsed = parse_url($url); if (!isset($parsed['path'])) { return $url; } // 拆分路径部分,逐个编码段 $path_segments = explode('/', $parsed['path']); $encoded_segments = array_map(function($segment) { return rawurlencode(rawurldecode($segment)); }, $path_segments); $parsed['path'] = implode('/', $encoded_segments); // 重组URL $encoded_url = ''; if (isset($parsed['scheme'])) { $encoded_url .= $parsed['scheme'] . '://'; } if (isset($parsed['host'])) { $encoded_url .= $parsed['host']; } if (isset($parsed['path'])) { $encoded_url .= $parsed['path']; } if (isset($parsed['query'])) { $encoded_url .= '?' . $parsed['query']; } return $encoded_url; } // 在处理URL时使用 $url = esc_url_raw($_POST['scrape_url']); $url = encode_url_path($url);
内容的提问来源于stack exchange,提问作者Simba
相关产品推荐
相关产品推荐

