小部件实例的索引在‘wp_Options’表中以‘2’开头

时间:2016-12-27 作者:Sebastian Kaczmarek


我有一个关于保存在中的小部件实例的有趣问题wp_options 桌子我花了很多时间才弄明白,但仍然不知道为什么会这样

Problem:<因此,问题是,当我拖动任何小部件并将其放到管理仪表板的任何侧栏上时,其ID以2开头。例如,当我删除文本小部件时,其ID为widget_text-2 尽管这是第一个小部件。当我去wp_options 表中的序列化数据并取消序列化widget_text 选项,我得到的是从2. 为什么?

1 个回复
最合适的回答,由SO网友:birgire 整理而成

这个why 零件可在票证中找到#24889.

让我来quote @阿扎奥兹:

当引入对多用途小部件的支持时,许多小部件同时从“单一”转换为“多”。为了保持向后兼容性并且不破坏现有的小部件,有一些转换代码可以将“单个”小部件实例设置为*-1 (不确定为什么不*-0, 那是很久以前的事了)。为了不覆盖转换后的数据,新的多窗口小部件实例必须从表单开始2. 正如@tyxla提到的,这不会破坏任何东西,如果更改为-0-1, 理论上,仍然可以覆盖某人的单个小部件。

可用的文本小部件列在全局$wp_registered_widgets 作为:

[text-1] => Array
    (
        [name] => Text
        [id] => text-1
        [callback] => Array
            (
                [0] => WP_Widget_Text Object
                    (
                        [id_base] => text
                        [name] => Text
                        [option_name] => widget_text
                        [alt_option_name] => 
                        [widget_options] => Array
                            (
                                [classname] => widget_text
                                [customize_selective_refresh] => 1
                                [description] => Arbitrary text or HTML.
                            )

                        [control_options] => Array
                            (
                                [id_base] => text
                                [width] => 400
                                [height] => 350
                            )

                        [number] => 1
                        [id] => text-1
                        [updated] => 
                    )

                [1] => display_callback
            )

        [params] => Array
            (
                [0] => Array
                    (
                        [number] => -1
                    )

            )

        [classname] => widget_text
        [customize_selective_refresh] => 1
        [description] => Arbitrary text or HTML.
    )
我认为text-1 id,来自WP_Widget::_register():

if ( $empty ) {
    // If there are none, we register the widget\'s existence with a generic template.
    $this->_set( 1 );
    $this->_register_one();
}
当可用的多窗口小部件与一起列出时wp_list_widgets(), 这个next_widget_id_number() 函数用于计算下一个小部件id号。定义如下:

function next_widget_id_number( $id_base ) {
    global $wp_registered_widgets;
    $number = 1;

    foreach ( $wp_registered_widgets as $widget_id => $widget ) {
        if ( preg_match( \'/\' . $id_base . \'-([0-9]+)$/\', $widget_id, $matches ) )
            $number = max($number, $matches[1]);
    }
    $number++;

    return $number;
}
对于text-1 id,下一个小部件id号为max( 1, 1 ) + 1 = 2.

因此,当我们将第一个multi-Text小部件拖动到可用的侧栏上时widget_text 选项存储为(为更好的可读性进行了调整):

a:2:{
i:2;a:3:{s:5:"title";s:0:"";s:4:"text";s:0:"";s:6:"filter";b:0;}s:12:"_multiwidget";i:1;
}
我们注意到i:2 零件和sidebars_widgets 选项将包含text_2 例子

希望有帮助。