在INSERT_WITH_MARKS过程中出现错误“Call to a Members Function Switch_to_Locale()on NULL”

时间:2019-11-20 作者:Rick Hellewell

我的插件更新htaccess文件时出现问题。我使用的代码是:

insert_with_markers($htaccess_file, $marker, $lines);
该函数中使用的参数先前已正确定义。错误消息为:

    Uncaught Error: Call to a member function switch_to_locale() on null 
in /home2/path/to/site/fstraptest/wp-includes/l10n.php:1582
我尝试确保已加载switch\\u to\\u locale()使用的各种函数:

if (! function_exists(\'get_home_path\')) 
        {include_once(ABSPATH . \'wp-admin/includes/file.php\');}
    if (! function_exists(\'insert_with_markers\')) 
        {include_once(ABSPATH . \'wp-admin/includes/misc.php\');}
    if (! function_exists(\'switch_to_locale\')) 
        {
        include_once(ABSPATH . \'wp-admin/includes/l10n.php\');
        include_once(ABSPATH . \'wp-includes/class-wp-locale-switcher.php\');
        }
    if (! function_exists(\'got_mod_rewrite\')) 
        {include_once(ABSPATH . \'wp-admin/includes/misc.php\');}
    if (! function_exists(\'is_multisite\')) 
        {include_once(ABSPATH . \'wp-admin/includes/load.php\');}
但这并没有解决问题。

这是WP 5.3、PHP 7.3.11的版本。类似的代码以前曾使用过;这可能是从WP 5.3开始的,但不确定。

谷歌没有帮助解决这个错误。该网站的语言为“en-US”。插件没有任何语言文件。主题改为“二十三”;错误也会发生在其他主题中,因此不会与主题相关。

Additional Code

在插件文件的顶部,此代码初始化设置

add_action( \'admin_init\', \'CWPSO_settings_init\' );  // does register_setting, add_settings_section add_settings_field, etc
TheCWPSO_settings_init() 做注册的事情,然后有一堆add_settings_field() 设置选项。所有这些看起来都类似于此:

add_settings_field( 
        \'CWPSO_protect_config_file\',                    // field name
        __( \'\', \'CWPSO_namespace\' ),    // message before field (not used)
        \'CWPSO_protect_config_file_render\',         // render function
        \'pluginPage\',                   // plugin page name
        \'CWPSO_pluginPage_section\'      // plugin section name
    );  
此代码清理该输入字段:

if (isset($_POST[\'CWPSO_protect_config_file\'])) {
                $new_input[\'CWPSO_protect_config_file\'] = "1";} else { $new_input[\'CWPSO_protect_config_file\'] = "0";}
这段代码设置了htaccess文件可能发生的一系列事情

if (($options[\'CWPSO_protect_config_file\'])  and ($_GET[\'page\'] == \'cellarweb_private_function\')) {
     $change_htaccess[] = \'CWPSO_protect_config_file\';
 }
这段代码检查以前的htaccess数组,并构建要放入htaccess的语句

if (in_array(\'CWPSO_protect_config_file\', $change_htaccess) ) {
        $lines[] = \'  # protect wp-config.php file from direct access\';
        $lines[] = \'     <files wp-config.php>\';
        $lines[] = \'       order allow,deny\';
        $lines[] = \'       deny from all\';
        $lines[] = \'     </files>\';
    }
此代码执行实际的htaccess文件修改($之前已设置标记)

$success = insert_with_markers($htaccess_file, $marker, $lines);
还有那个insert_with_markers() 行导致错误。请注意,插件使用/创建/保存的所有设置都工作正常。如果我把insert_with_markers() 第行,插件设置正确显示/保存。

2 个回复
最合适的回答,由SO网友:Rick Hellewell 整理而成

我发现在导致错误的行上方有一个额外的“-”字符。在我的编辑器中很难看到(可能是因为屏幕上有灰尘)。

我的编辑器(Rapid PHP 2018)中的语法检查器并没有感觉到这个错误,只是通过仔细观察,我找到了额外的字符。删除该选项修复了问题。

吸取的教训(再次)是,有时报告的错误行不是问题所在。错误也可能由报告行之前的语句引起。

但感谢您的帮助;也从他们身上学到了一些东西。所以,净“赢”。。。尽管弄明白这件事很令人沮丧。

SO网友:Sally CJ

根据您的评论:

那些htaccess 更改不会由于add_action. 也许他们应该?

Yes, they should.

原因如下

insert_with_markers() 呼叫switch_to_locale() 其中使用$GLOBALS[\'wp_locale_switcher\'] (或$wp_locale_switcher) 在中初始化wp-settings.php, 但只有在WordPress运行setup_theme

查看问题中的错误line #1582 在里面wp-includes/l10n.php 这是return $wp_locale_switcher->switch_to_locale( $locale );, 发生该错误的最可能原因是全局变量$wp_locale_switcher 尚未定义或初始化。这表明你打过电话insert_with_markers() 太早了。

所以如果你想使用insert_with_markers(), 确保使用正确的挂钩;例如load-{$page_hook}update_option_{$option}:

// Example 1:
add_action( \'admin_menu\', function () {
    $hookname = add_menu_page( ... );
    add_action( \'load-\' . $hookname, function () {
        // Call insert_with_markers()
    } );
} );

// Example 2:
add_action( \'update_option_my_field\', function ( $old_value, $value ) {
    // Call insert_with_markers()
}, 10, 2 );
均已尝试(&T);在WordPress 5.2.4和5.3上进行测试。

但也可能有插件或自定义代码$wp_locale_switcher, 所以如果使用钩子的时间晚于setup_theme 不适合你,你可以尝试停用插件