我想要一个在同一个请求中维护状态的库类。我的用例是我想将'messages'传递给类,然后在视图中随时调用它们。消息可以从应用程序的任何部分添加。
我最初是通过静态方法完成的,效果很好。但是,作为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,但这似乎不合适,除非我遗漏了什么。
我可以创建一个类(非静态),但是如何确保所有消息都写入同一个对象 - 以便我以后可以检索它们?
解决这个问题的最佳方法是什么?
答案 0 :(得分:3)
我看起来你可以从使用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
实例。但是,如果实例已存在,则需要返回该实例。
基本上,单身人士是其自身实例的看门人,并且它固执地拒绝让自身存在多个实例。
答案 1 :(得分:1)
听起来你想要做一个 Singleton 类。这将在一个类中创建一个实例,并允许您访问另一个类中的同一个实例。查看http://www.developertutorials.com/tutorials/php/php-singleton-design-pattern-050729-1050/了解详情。
答案 2 :(得分:1)
如何让它成为单身人士课程?
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
答案 3 :(得分:0)
您需要的是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();
答案 4 :(得分:0)
听起来有点像你想要单身,虽然as an anti-pattern我会避免它。
您可以执行完整的静态类,其中每个静态成员都调用self::_isBuilt();
方法来执行构造元素。破坏有点棘手。
您需要的最佳案例可能是您正在构建的普通(非静态)类,然后从全局访问...不是超级整洁,但允许构造/破坏和成员,以及您的静态使用$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(..);