如何在WordPress主题functions.php中重写wp_timezone_choice函数?
解决WordPress无法直接重写
wp_timezone_choice函数的方案 由于wp_timezone_choice不属于WordPress的可插拔函数(未被if ( ! function_exists( 'wp_timezone_choice' ) )包裹),无法直接在主题functions.php中通过重新定义覆盖它。以下提供三种可落地的解决思路:
方法一:利用runkit扩展重定义函数(需服务器支持)
如果你的服务器启用了PHP的runkit扩展,可以直接替换原函数逻辑,示例代码:
add_action('init', function() { if (function_exists('runkit_function_redefine')) { runkit_function_redefine( 'wp_timezone_choice', '$selected_zone, $locale = null', 'return my_custom_timezone_choice($selected_zone, $locale);' ); } }); function my_custom_timezone_choice($selected_zone, $locale = null) { // 复制wp-includes/functions.php中原函数的代码 // 替换时区列表为过滤后的结果,示例仅保留亚洲时区 $tzlist = timezone_identifiers_list(); $filtered_zones = array_filter($tzlist, function($zone) { return str_starts_with($zone, 'Asia/'); }); // 后续沿用原函数的HTML生成逻辑,将原时区列表替换为$filtered_zones // ... 补充原函数剩余代码 }
注意:runkit扩展默认未启用,需要服务器管理员配置PHP环境,兼容性有限。
方法二:前端JS动态移除不需要的时区选项(通用无依赖)
针对WordPress后台设置页面的时区选择器,直接通过JS删除不需要的选项,示例代码:
add_action('admin_footer-options-general.php', function() { ?> <script> const timezoneSelect = document.getElementById('timezone_string'); if (timezoneSelect) { // 示例:移除所有非亚洲时区选项 Array.from(timezoneSelect.options).forEach(option => { if (!option.value.startsWith('Asia/')) { timezoneSelect.removeChild(option); } }); } </script> <?php });
优点:无需服务器特殊配置,实现简单;缺点:仅对后台设置页面生效,其他调用wp_timezone_choice的场景不适用。
方法三:替换核心设置页面的时区字段(彻底自定义)
直接移除原时区设置字段,替换为自定义的选择器,示例代码:
add_action('load-options-general.php', function() { // 移除原时区设置字段 remove_settings_field('timezone_string', 'general'); // 添加自定义时区字段 add_settings_field( 'custom_timezone_string', __('Timezone'), 'render_custom_timezone_selector', 'general' ); }); function render_custom_timezone_selector() { $selected = get_option('timezone_string', 'UTC'); // 生成过滤后的时区列表 $tzlist = timezone_identifiers_list(); $filtered_zones = array_filter($tzlist, function($zone) { return str_starts_with($zone, 'Asia/'); }); ?> <select name="timezone_string" id="timezone_string"> <?php foreach ($filtered_zones as $zone) : ?> <option value="<?php echo esc_attr($zone); ?>" <?php selected($selected, $zone); ?>> <?php echo esc_html($zone); ?> </option> <?php endforeach; ?> </select> <?php }
这种方法完全可控,适合需要彻底自定义时区选项的场景,仅影响后台常规设置页面。
内容的提问来源于stack exchange,提问作者Darko
相关产品推荐
相关产品推荐

