PHP5、继承、单例操作和筛选器挂钩限制

时间:2011-03-09 作者:Roman

我目前正在开发一个插件,它使用wordpress的内置cron功能。

我不想使用PHP4,而是想将PHP5与继承和单例设计模式结合使用。我在行动中遇到了一些限制&;过滤器挂钩机制,并想问,是否有其他方法解决此问题。

我已经从示例代码中去掉了所有不相关的部分。如果您需要演示的完整代码,请在此处发布,以便我可以添加pastbin链接。

Example:

在基类“Cron”中,我想声明所有描述Cron作业的方法。为了注册一个新的cron条目,我使用带有hookname和可调用方法的add\\u操作。

The problem:

要调用此操作挂钩,内置wordpress函数do\\u action需要从外部访问此方法。为了解决这个问题,我将该方法声明为public static。

但这似乎也不对。该方法不应可从外部访问。它应该是私人的。只有MyCron类应该具有访问此方法的权限。正如您在示例中的注释块中所看到的,我尝试了不同的方法。

只有将构造函数声明为public(这会破坏单例模式),才能将方法设置为private。但是,每次我添加事件时,都会创建一个新的MyCron对象。

有什么建议吗?

谢谢Roman


class Cron {
    private $_events;

    protected function __construct() {
        $this->_events = array();
    }

    protected function addEvent($timestamp, $recurrence, $hookname, $hookmethod, $args = array()) {
        $this->_events[] = $hookname;

        if (!wp_next_scheduled($hookname)) {
            wp_schedule_event($timestamp, $recurrence, $hookname, $args);
        }

        add_action($hookname, $hookmethod);
    }
}

class MyCron extends Cron {
    private static $_instance = null;

    public static function getInstance() {
        if (is_null(self::$_instance)) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }

    protected function __construct() {
        parent::__construct();

        /* Note: 
         * The passing action hook must be public static to be callable from outside. An other option is to declare the constructor
         * public. But this means, everytime I add e new event I will create an new object of MyCron. This is the reason why I
         * the singleton php design pattern with a private/protected constructor.
         * 
         * This doesn\'t work either:
         * 1) $this->addEvent(time(), \'daily\', \'webeo-daily-event\', \'MyCron::getInstance->myDailyEvent\');
         * 2) $this->addEvent(time(), \'daily\', \'webeo-daily-event\', \'MyCron::getInstance::myDailyEvent\');
         * 3) $this->addEvent(time(), \'daily\', \'webeo-daily-event\', array(\'MyCron::getInstance\', \'myDailyEvent\'));
         * 4) $this->addEvent(time(), \'daily\', \'webeo-daily-event\', create_function(\'\', \'return MyCron::getInstance()->myDailyEvent();\'));
         * 5) $this->addEvent(time(), \'daily\', \'webeo-daily-event\', function() { return MyCron::getInstance()->myDailyEvent(); });
         */
        $this->addEvent(time(), \'daily\', \'webeo-daily-event\', array($this, \'myDailyEvent\'));

    }

    public static function myDailyEvent() {
        // do this every day with wp cron
    }
}

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

您不必将构造函数声明为public,只需将动作挂钩函数声明为public即可。

示例:

<?php
/*
Plugin Name: Singleton Action
*/

class Singleton_Demo
{
    /**
     * @static $instance Objekt
     * @access private;
     */
    private static $_instance   = NULL;

    protected function __construct() {}
    private final function __clone() {}

    public static function getInstance()
    {
        if ( self::$_instance === NULL )
        {
            self::$_instance = new self;
        }

        return self::$_instance;
    }

    public function hook_test()
    {
        print \'<p>Works!</p>\';
    }
}

add_action( \'wp_footer\', array ( Singleton_Demo::getInstance(), \'hook_test\' ) );
不管怎样,我不会使用单件

结束

相关推荐

Using OOP in themes

我看到很多插件在没有必要的时候使用面向对象的编码。但更糟糕的是,主题开发人员也开始做同样的事情。商业主题和自由流行的主题,如Suffusion,甚至我最喜欢的主题-Hybrid,将它们的所有函数都塞进一个类中,在函数中实例化一次。php并以过程方式运行其函数:)世界跆拳道联盟?这样做有什么意义?显然,您不会同时使用同一主题的两个或多个实例。让我们假设插件是为名称空间这样做的(这很荒谬),但是主题的借口是什么呢?我错过了什么?编写这样的主题有什么好处?