在保持向后兼容性的同时更新插件:常规

时间:2013-03-02 作者:helgatheviking

如何使更新成为我的公共插件,而不破坏所有现有用户的插件。

Firstly, 我想更改主插件的类/名称空间,因为我希望它与它扩展的插件中的其他类相似。

所以我想改变一下

class some_class(){}

class Some_Class(){}
Secondly, 整个类被实例化并保存在全局变量中。

global $some_class;
$some_class = new some_class();
在这里的某个地方,我看到了一个很好的示例,说明了如何在没有全局的情况下实例化一个类(当然,现在找不到它,#doh)。用户可以使用global添加/删除几个模板。有没有一种方法可以在不完全破坏可能使用它来操纵模板的人的主题的情况下摆脱global?

Thirdly, 与上述内容相关,我的主插件文件变得非常大,为了我自己的理智,我想把它分成几部分。但是,如果some_templates() 方法位于some_class() 是否可以将其移动到front_end_class() 不破坏用户的东西?

For example

在我的插件中取消挂钩操作

function remove_method(){
  global $some_class;
  remove_action(\'wp_head\', array($someclass, \'some_templates\'));
}
add_action(\'init\',\'remove_method\');
可以在不破坏这一点的情况下调整类结构和全局变量设置吗。我怎样才能提醒人们这已经改变了?_doing_it_wrong() ?

Finally, 我一直在将一些post meta保存为“是”或“否”,以代替布尔值。改变这一点有意义吗?

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

PHP中的类名不区分大小写(使用one exception), 所以这应该不是问题。

可以使用静态方法访问类的主插件实例get_instance() (example). 你不必为此构建一个单例。而且它不应该破坏向后兼容性。

如果旧代码中有公共方法,并且这些方法已被第三方代码使用,则必须保留准确的签名。因此,要么保留该方法并将调用传递给新类的实例,要么(如果有许多这样的方法)使用__call() 将所有这些方法集于一身。

(更新)remove_action() … 这很棘手。如果您现在从另一个类添加此回调,则没有安全的方法保持向后兼容,因为您无法“监视”remove_action() 呼叫
您可以注册旧回调并实现Observer 如果已移除,请注意。

我一直在为未来的项目考虑一个想法:将公共API与内部逻辑分离。

示例:创建类Plugin_API 并在设置时将工作代码中的所有对象传递到该类中。调用该API中的方法时,在内部将该调用传递给负责的对象,而不向公众公开插件结构。

示例代码

add_action( \'wp_loaded\', array ( Plugin_Controller::get_instance(), \'plugin_setup\' ) );

class Plugin_Controller
{
    protected static $instance = NULL;

    public static function get_instance()
    {
        NULL === self::$instance and self::$instance = new self;

        return self::$instance;
    }

    public function plugin_setup()
    {
        $api = Plugin_API::get_instance();
        $api->add_object( \'post_type\',    new Plugin_Custom_Post_Type );
        $api->add_object( \'taxonomy\',     new Plugin_Custom_Taxonomy );
        $api->add_object( \'options_page\', new Plugin_Options_Page );

        add_action( \'wp_head\', array ( $api, \'wp_head\' ) );
    }
}

class Plugin_Custom_Post_Type {}
class Plugin_Custom_Taxonomy {}
class Plugin_Options_Page {}

class Plugin_API
{
    protected static $instance = NULL;

    protected $objects;

    public static function get_instance()
    {
        NULL === self::$instance and self::$instance = new self;

        return self::$instance;
    }

    public function add_object( $name, $object )
    {
        $this->objects[ $name ] = $object;
    }

    public function wp_head()
    {
        $this->objects[\'post_type\']->wp_head_callback();
        $this->objects[\'taxonomy\']->wp_head_callback();
    }
}
现在,另一个插件可以删除该操作…

remove_action( \'wp_head\', array ( Plugin_API::get_instance(), \'wp_head\' ) );
…您仍然可以随时更改插件结构。

这只是一个想法,我没有用过。但对于一个包含大量类的复杂插件来说,值得一试。不确定它将如何与过滤器一起工作,但无论如何,这些都更容易移动。

更新数量未知的post元字段可能会很昂贵。我不会碰那个。

结束

相关推荐