PHP中的单例模式....如何在请求之间保存状态

时间:2012-07-24 14:36:53

标签: php design-patterns singleton

通过使用静态变量和单例模式,我认为创建一个简单的购物车很容易记住购买另一个页面时购物车中的哪些商品。

我遇到的问题是购物车在刷新页面时不记得其中已有的内容。

我的代码是否存在问题,或者我应该使用全局或mysql数据库。

存储状态的最佳方式是什么..

<?php
//create a singleton class
class shoppingCart {

    private static $_shoppingCartItems = array();
    private static $_instance = null;

    private function __construct(){

    }

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


    public function add(ShoppingItem $item){
        $this->_shoppingCartItems[] = $item;
    }

    public function cartCount(){                 
        return count($this->_shoppingCartItems);
    }  
}
?>

实施

$item = new shoppingItem();

$shoppingCart = shoppingCart::getInstance();
$shoppingCart->add($item);
$shoppingCart->add($item);

//should increment by 2 on each page load but it doesn't
echo $shoppingCart->cartCount(); 

3 个答案:

答案 0 :(得分:5)

不同请求之间不保留静态类成员(或任何其他变量)。从不。

救援会议

唯一的例外是$_SESSION;这是一种允许这种情况的特殊机制。

通过脚本顶部的session_start()加注会话。

您现在可以像常规数组一样使用$_SESSION来存储和检索信息。会话属于单个用户,它不是在所有用户之间共享数据的方式。

查看here进行介绍。

沉默

在调用session_start()之前,您不能输出任何内容。也就是说,<?php必须是PHP脚本中希望使用会话的第一件事。此外,<?phpsession_start()之间不得有任何echo语句或任何其他输出生成函数。

输出缓冲

如果您在开始会话之前确实必须生成输出,则可以使用output buffering

备注

  • $_SESSION是健忘的。在用户一侧time处于非活动状态后,数据将被删除。
  • 如果收到以下错误消息,则违反了上述指导原则。另一种可能性是您的脚本具有BOM(Unicode字节顺序标记)。如果是这样,请将其删除。
  

警告:session_start():无法发送会话cookie - 标头   发送者(输出开始于

发生这种情况的原因是由于PHP处理输出的方式:它试图尽可能快地向用户输出输出。但是,HTTP协议传输某些控制数据(cookie,会话属于您等),在响应的所有输出(“正文”)之前称为“标题”。一旦输出任何内容,标题就需要发送 - 除非你使用输出缓冲。

答案 1 :(得分:2)

我想我可以在那里看到你的思维模式,但是你想要做的事情在很多方面都是错误的。

1。 Singleton不是一个模式,它是一个反模式

Singleton是一种反模式,应该不惜一切代价避免。有关原因,请参阅戈登的this great answer

2。 HTTP是无状态协议。

您在PHP中所做的任何事情都无法帮助您跨两个请求保留状态。您的$shoppingCart是从头开始为每个请求创建的,事实上,您的整个应用程序都是。您不应该尝试在对象中保留数据,而应该在每次请求后重新创建状态,方法是从其他位置获取相应的数据。在您的示例中可能来自某种数据库nosql或sql。

3。会话

您可以在超级全局$_SESSION中保留用户特定数据,但在大多数情况下,我建议不要这样做。您的用户会话应该包含身份验证和用户数据,但您应该避免在其中存储与业务逻辑相关的所有类型的数据。

答案 2 :(得分:1)

PHP不是应用程序服务器。它不会在请求之间自动保持“应用程序”状态。你必须通过$ _SESSION,cookies和/或你自己的私人方法自己做。

除非您采取措施保留数据,否则当调用脚本的HTTP请求结束时,应用程序的状态将被删除。