所有插件都应该封装在一个类中吗?

时间:2011-08-17 作者:Jamie

开发插件时,是否应将函数分组到一个类中以避免名称空间冲突?

使用类是否会给PHP带来性能开销?

如果性能受到影响,是否应该预先修复函数名?

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

开发插件时,是否应将函数分组到一个类中以避免名称空间冲突?

是的,但这只是一个小论点。事实上,这不是OOAD.

使用类是否会给PHP带来性能开销?

不,不明显。糟糕的设计和/或糟糕的编写代码或过早的优化会比实际的语言功能产生更多的性能问题。

如果性能受到影响,是否应该预先修复函数名?

如前所述,没有性能影响。写得不好的代码比写得好的代码会对性能造成更大的影响,写得好的代码会有更多的代码行,但不会强迫你做坏事。

<小时>

Bottom Line:

您可以为插件使用不同的类。您可以使用它们来创建某种名称空间,并将它们“仅仅”用于全局函数。最直接的形式是静态类函数,下面的代码示例显示了这两种函数,首先是全局函数,然后是全局静态类函数:

/* global function */
function myplug_hook()
{
}

add_filter(\'the_hook\', \'myplug_hook\');


/* global static function */
class myplug
{
    public static function hook()
    {
    }
}

add_filter(\'the_hook\', \'myplug::hook\');
这只是一个小示例,说明您需要为单个挂钩键入更多内容。此外,它还显示了名称空间的工作原理:您可以更轻松地替换单个类名,以重命名所有静态函数,然后搜索和替换myplug:: 这可能会更难myplug_ 因为误报。但最终差别不大。

关键是:static class functions Docs 那就没什么别的了global functionsDocs.

这个示例也显示了:名称空间很好,但对于WorpPress,名称空间停止使用挂钩:回调函数是硬编码的,因此当您使用wordpress对挂钩名称进行干预时,使用类(基名的一个位置,类名)的名称空间的好处没有帮助。

真正的好处始于使用实际的类实例和非静态函数。这样做的好处是,您可以开始使用OO原则,并且可以简化代码。静态类函数与其说是一个解决方案,不如说是一个问题。

那就不仅仅是句法上的糖分了。

关键点是:做一些可以帮助您编写易于处理和维护的代码的事情。不要过分评价性能,这是一个常见的错误。更重要的是,您编写的代码很容易阅读和理解,可以满足您的需要。也许这个问题和答案有助于从更大的角度来看这一问题:Multiple Custom Metabox Help.

对于较小的插件,我有一种常见的方法,即使用静态助手函数实例化插件,其余的则驻留在插件实例中。这有助于封装主插件逻辑,并受益于使用挂钩的名称空间,以及可以在挂钩之间重用私有成员,这在标准全局函数中是不可能的。以下代码示例显示了该模式:

<?php
/** Plugin Headers ... */

return MyPlugin::bootstrap(); 

class MyPlugin
{
    /** @var MyPlugin */
    static $instance;
    static public function bootstrap() {
        if (NULL === self::$instance) {
            self::$instance = new __CLASS__;
        }
        return self::$instance;
    }
    # ...
}
这是我用于基本插件文件的常见模式。plugin类一方面表示wordpress的插件,另一方面它允许开始为自己的代码使用面向对象的范例,这些代码甚至可以完全面向对象(但不需要)。它是一种控制器,作为请求与整个wordpress API接口。

如示例所示,将创建插件的一个实例。这允许您使用已知的公共资源,如Constructor Docs (__construct) 要初始化实际插件,请执行以下操作:

# ...
class MyPlugin
{
    # ...
    public function __construct()
    {
        add_filter(\'the_hook\', array($this, \'hook\'));
    }

    public function hook()
    {
    }
    # ...
}
在钩子注册时,这个插件对象已经从它的设计中获益:您已经停止对具体插件的实际钩子函数进行硬编码。这是可能的,因为类绑定到回调的对象实例。听起来很复杂,只是说:$this 是插件。可用于钩子回调,比较Registering Class methods as hook callbacks.

这种模式允许更容易地与wordpress进行接口:注入被简化为挂钩的名称以及它们提供的数据。然后,您可以开始直接实现到这个插件类中,或者根据它重构您的实现,以便只将代码放在插件类中,这是根据wordpress定义插件接口的最低要求,但不要使用wordpress的一般逻辑。这就是乐趣的开始,也很可能是每个插件作者想要实现的长期目标。

因此,不要使用worpdress编程,而要反对它。由于worpdress非常灵活,因此没有通用或易于描述的接口可供编程使用。一个基本插件类可以扮演这个角色,使您能够更灵活地编写自己的代码,从而使代码更简单,性能更好。

因此,名称间距不仅仅有好处。我能给你的最好建议是:试试你自己。你不会失去太多,只会发现新的东西。

在通过wordpress的一些主要更新后,您很可能会注意到不同之处,同时保持插件的兼容性。

警告:如果您的插件直接与wordpress集成以完成任务,那么使用一个或两个公共功能可能更适合您。使用适合工作的工具。

SO网友:kaiser

类别与功能集性能

General: 好了,类和函数集之间的“性能”没有区别。

Detail:

如果你质疑function_exists() vs。class_exists() 像往常一样,你有很多函数(~ 1.800(?)wp核心)与等级(约100(?)在wp core中)。因此,让东西“可插拔”,并因此质疑其存在,是执行时间上的差异


架构-东西是如何工作的:

function set: 通常,函数在调用它的行中执行。所以每次你打电话的时候,如果你不得不多次打电话的话,你必须再写一次。

Class: 课程有不同的方法。最接近函数集的类是“factory”类(wikipedia/google). 在我看来,它几乎与一组函数相同,但封装在一个类中。但也有其他“类型”的类。例如,您可以编写一个抽象类或父类类,并使用子类进行扩展。在一个真实的示例中:假设有一个类构建了一些静态文本字段。在您的__construct() 功能您有一组场景,如“left\\u column”、“right\\u column”&;“footer\\u字段”。然后你打电话$text_field = new TextFieldClass(); 实例化类。然后你只需打电话$text_field->add( $case => \'left_column\', \'case\' => \'foo text\' );$text_field->add( $case => \'footer_field\', \'case\' => \'bar text\' );. 然后,在实例化类时,所有条件和其他条件都已经执行,在构建文本字段时,只调用了两个类函数。在这个szenario中,您可以节省一些毫秒的执行时间。

个人观点如果你写得很好,那么你在表现上会有一个次要的优势。但你会有一个组织良好的结构来工作。到目前为止还没有什么壮观的场面。但是如果您考虑插件中类和函数的以下“拆分”用例,那么您将得到我的最终观点:Class is internal, functions are API. 只要您仅通过公开使用的函数(然后调用类或类函数)提供API,您就可以节省进一步开发插件的时间。您可以自由更改插件的内部结构,甚至更改插件的可能性,而不影响用户的任何时间和地点。

Example:

// construction of object
if ( ! class_exists( \'WPSE_HelloWorld\' ) )
{

class WPSE_HelloWorld
{
    function __construct( $args = array( \'text\', \'html\', \'echo\' ) )
    {
        // call your object building procedures here
        $this->hello_world( \'text\', \'html\', \'echo\' );
    }

    function hello_world( \'text\', \'html\', \'echo\' )
    {
        $start_el = \'<{$html}>\';
        $end_el = \'</{$html}>\';
        if ( $echo )
        {
            return print "{$start_el}{$some}{$end_el}";
        }

        return "{$start_el}{$some}{$end_el}";
    }
} // END Class 

}

// API: public functions
function the_hello_world( $args( \'echo\' => true ) )
{
    $new = new WPSE_HelloWorld();
    return $new->hello_world( $args );
}

function get_hello_world( array( $args( \'echo\' => false) ) )
{
    $new = new WPSE_HelloWorld();
    return $new->hello_world( $args );
}

// then you can call it like get_the_title() or the_title(), which you know from the WP API:
// \'echo\' is set to false per default:
$some_var = get_hello_world( array( \'text\' => \'hello reader\', \'html\' => \'strong\' ) );
# *returns* "<strong>hello reader</strong>"

// \'echo\' is set to true per default:
the_hello_world( array( \'text\' => \'hello reader\', \'html\' => \'strong\' ) );
# *prints/echos* "<strong>hello reader</strong>"
注意:请同时阅读Q评论中发布的t310s链接

SO网友:Otto

这纯粹是插件作者的风格选择。在速度方面没有真正的区别。

SO网友:Bainternet

课程通常不会在性能方面提供任何好处,但它们也很少有任何负面影响。它们真正的好处在于使代码更清晰,避免名称空间冲突。

SO网友:zeedre

大多数情况下,如果你使用函数,你会在每个函数名中加入插件的名称,因此,如果插件有十几个函数,那么你会有效地重复该名称十几次,这有点拖沓。

对于类,您可能只需要在类名中输入插件的名称一次。

此外,您可以使用继承或其他oo构造以非常干净的方式实现行为。这里有一个例子:

class animalplugin{
  //plugin functions...
  function talk(){print "animalnoise";}
}
class animalplugin_with_cat_mods extends abcplugin{
  //cat functions overrides
  function talk(){print "meow";}
}
if (iscat()){
  new animalplugin_with_cat_mods();
} else {
  new animalplugin();
}

结束

相关推荐

主页(index.php)上的评论在帖子下重复

我在我的索引主页上显示WP评论。php文件,但我的问题是,每个帖子下面都会显示一些注释。评论编号可以,但评论分配给帖子的位置错误。但是,当显示单个页面时,一切正常。我检查了DB中评论的ID,看起来也不错。你知道怎么回事吗?我在索引中使用以下代码。php显示注释:<?php global $withcomments; $withcomments = 1; comments_template(); ?> Here is the whole index.php 如果有帮助here 是实际页面