我想要一个库类来维护同一请求的状态。我的用例是,我想将"消息"传递给类,然后随时从视图调用它们。可以从应用程序的任何部分添加消息。
我最初是通过静态方法完成的,效果很好。但是,作为lib的一部分,我还需要调用__construct
和__destruct()
,这在静态类上是无法完成的。
这里有一个非常简单的例子,我正在尝试做什么:
class Messages
{
private static $messages = array();
public function __construct()
{
// do something
}
public function __destruct()
{
// do something else
}
public static function add($message)
{
self::$messages[] = $message;
}
public static function get()
{
return self::$messages;
}
}
然后,我可以通过在代码中的任何位置添加消息
Messages::add('a new message');
如果可能的话,我希望避免使用静态(可测试性)。我看过DI,但它似乎不合适,除非我遗漏了什么。
我可以创建一个类(非静态),但我如何确保所有消息都写入同一个对象,以便以后可以检索所有消息?
解决这个问题的最佳方法是什么?
我认为您可以从使用Singleton模式中受益——它是为一个在整个请求中必须只有一个实例的对象设计的。基本上,您可以创建一个私有构造函数和一个静态方法来检索唯一的实例。下面是一个单例的例子,它将执行您所描述的操作。
<?php
class Messages
{
private static $_instance;
private $_messages = array();
private function __construct() {
// Initialize
}
static public function instance() {
if (! self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
public function add_message( $msg ) {
$this->_messages[] = $message;
}
public function get_messages() {
return $this->_messages;
}
private function __destruct() {
// Tear-down
}
}
$my_messages = Messages::instance();
$my_messages->add_message( 'How now, brown cow?' );
// ...
$your_messages = Messages::instance();
$msgs = $your_messages->get_messages();
echo $your_messages[0]; // Prints, "How now, brown cow?"
由于构造函数是私有的,因此只能从对象本身的方法中创建Messages
对象。由于您有一个静态方法instance()
,因此可以从中创建一个新的Messages
实例。但是,如果实例已经存在,则需要返回该实例。
基本上,单例是它自己实例的看门人,它顽固地拒绝让自己的多个实例存在。
听起来你想上一堂Singleton课。这将在一个类中创建一个实例,并允许您访问另一个类的同一实例。退房http://www.developertutorials.com/tutorials/php/php-singleton-design-pattern-050729-1050/了解更多信息。
让它成为一个单例类怎么样?
class Messages
{
// singleton instance of Messages
private static $instance;
public function __construct() { ... }
public static function getInstance()
{
if (!self::$instance)
{
self::$instance = new Messages();
}
return self::$instance;
}
}
这将确保所有消息都写入同一个对象,还允许您调用__construct
和__destruct
您需要的是Singleton模式:
final class Singleton {
// static variable to store the instance
private static $instance = NULL;
// disable normal class constructing
private function __construct() {}
// instead of using the normal way to construct the class you'll use this method
public static function getInstance() {
if (NULL === self::$instance) {
self::$instance = new self;
}
return self::$instance;
}
// disable external cloning of the object
private function __clone() {}
}
// get the instance across some of your scripts
$singleton = Singleton::getInstance();
听起来有点像你想要一个singleton,尽管作为一种反模式,我会避免它。
您可以创建一个完整的静态类,其中每个静态成员都调用一个self::_isBuilt();
方法来构造元素。破坏有点棘手。
对于您的需求,最好的情况可能是立即构建一个普通(非静态)类,然后从全局。。。不是非常整洁,但允许构造/析构函数和成员,以及您的statics使用$this
,这可能会有所帮助。如果你不喜欢全局变量,你也可以把它包装在一个方法中(JS中使用了一个技巧),但它并不整洁。
作为一个正常的全局类:
$myClass=new myClass();
//Access anywhere as:
globals['myClass']->myFunction(..);
包装在函数中
function my_class() {
static $var=null;
if ($var===null) $var=new myClass();
return $var;
}
//Access anywhere as:
my_class()->myFunction(..);