1

我想要实现的(PHP 5.3)是拥有一个访问器来访问我的表示,例如页面的 HTML 正文。与其直接回显所有内容,不如将其添加到该单例中的条目数组中。例子:myBodyClass::add('<h1>Title</h1>');

add()被声明为public static function add($strEntry) {}

现在我应该将它们添加到静态数组 $entries 中,例如self::$entries[] = $strEntry;类 VersionB)还是应该使用类似的实例self::getInstance()->entries[] = $strEntry;?(类 VersionA ) (因此 getInstance() 当然会实例化 '...new self;' 如有必要)

恐怕我还不太明白其中的区别。

我的问题的第二部分是如何打印对象。PHP手册关于为什么 __toString() 不能是静态的有点薄 - 但是我再次理解解析器在区分echo myBodyClass常量时存在问题(这就是原因吗?)

理想情况下,我想add()根据需要经常调用以添加主体的所有部分,然后echo myHeaderClass, myBodyClass, myFooterClass;在脚本末尾使用类似的东西,它应该调用__toString()类中的方法。

感谢您为我指明正确的方向。

代码示例

class VersionA
{
    private static $instance = null;
    private $entries = array();
    private final function __construct(){}
    private final function __clone(){}

    private static final function getInstance()
    {
        if (self::$instance === null) :
            self::$instance = new self;
        endif;
        return self::$instance;
    }
    public static function add($sString)
    {
        self::getInstance()->entries[] = $sString;
    }
    public static function getHtml()
    {
        return implode("\r\n", self::getInstance()->entries);
    }
}

class VersionB
{
    private static $entries = array();
    private final function __construct(){}
    private final function __clone(){}

    public static function add($sString)
    {
        self::$entries[] = $sString;
    }
    public static function getHtml()
    {
        return implode("\r\n", self::$entries);
    }
}
4

3 回答 3

1

您可能不应该使用静态添加方法。

单例的想法是您创建一个类的单个实例,以便外部对象可以与该实例交互。这意味着您的 add 方法不应该是静态的。

您可以执行以下操作:

class MyBodyClass
{
    protected $entries = array();

    protected $instance;

    public static function getInstance()
    {
        if (is_null($this->instance)) {
            $this->instance = new self();
        }
        return $this->instance;
    }

    private function __construct() {}

    public function add($strEntry)
    {
        $this->entires[] = $strEntry;
    }
}

并这样称呼它:

MyBodyClass::getInstance()->add('<h1>blah</h1>');
于 2013-01-11T12:52:57.040 回答
1

(根据OP的要求,从评论中复制...)

你错过了单例的意义。单例对象和静态类是有区别的。如果你想使用作用于对象的方法(比如 __toString()),那么你需要它是一个对象;静态类还不够好​​。如果您想避免getInstance一直调用,则根据依赖注入模式为对象设置一个变量,并像处理其他对象一样将其传递到任何地方。无论如何,这可能是最佳实践建议。

静态类的问题在于它不是真正的 OOP。它只是一堆具有共享类名的全局函数。也可以使用带有命名空间声明的普通函数。

但是使用真正的单例的主要原因是可交换性。假设您遵循我上面的建议并创建对您在代码中传递的对象的单个引用,那么交换替代对象会变得容易得多,因为您没有到处引用硬编码的类名. 这使得为​​使用该类的代码编写体面的单元测试变得更加容易。

希望有帮助。

于 2013-01-15T13:52:10.743 回答
0

像这样的东西应该工作:

class MySingleton
{

    public static function getInstance()
    {
        static $inst = null;
        if ($inst === null) {
            $inst = new MySingleton();
        }
    return $inst;
    }

    private function __construct() { }

    public static function add() {}

    public function __toString() {
        echo 'Something';
    }

}

$body = MySingleton::getInstance();
$body::add('Something');
echo $body;
于 2013-01-11T12:51:55.093 回答