封装PHP会话

封装PHP会话,php,session,design-patterns,Php,Session,Design Patterns,我的一位同事搬到了另一家公司,我得到了他现有项目的源代码。 我很震惊代码看起来是多么的混乱。我不是一名PHP开发人员,所以这可能是一个愚蠢的问题,但在我看来,他使用了太多的$\u会话,我们在会话方面遇到了很多错误。我想知道是否应该封装$\u会话,并为他使用的每个值编写一个自己的方法 我看到这段代码的问题是,他像这样使用session对象 $_SESSION['customer']['items'] = getItems() //returns an array $_SESSION['articl

我的一位同事搬到了另一家公司,我得到了他现有项目的源代码。 我很震惊代码看起来是多么的混乱。我不是一名PHP开发人员,所以这可能是一个愚蠢的问题,但在我看来,他使用了太多的
$\u会话
,我们在会话方面遇到了很多错误。我想知道是否应该封装
$\u会话
,并为他使用的每个值编写一个自己的方法

我看到这段代码的问题是,他像这样使用session对象

$_SESSION['customer']['items'] = getItems() //returns an array
$_SESSION['article'][$Id]['name'] = utf8_decode[$received[1]];
因此,从我的角度来看,我会将他的所有内容存储在简单的POPO中,并将其放入会话中

因此,客户的Popo如下所示

class CustomerPopo
{

    private $_id;

    private $_salutation;

    private $_name;

    private $_surename;

        public function getId()
    {
        return $this->_id;
    }

    public function setId($value)
    {
        $this->_id = $value;
    }

    public function getSalutation()
    {
        return $this->_salutation;
    }

    public function setSalutation($value)
    {
        $this->_salutation = $value;
    }

    public function getName()
    {
        return $this->_name;
    }

    public function setName($value)
    {
        $this->_name = $value;
    }

    public function getSurename()
    {
        return $this->_surename;
    }

    public function setSurename($value)
    {
        $this->_surename = $value;
    }

    function CustomerPopo() {

    }
}
class SessionManager
{

    private static function getValue($valueName)
    {
        $value = SessionManager::getValueFromSession($valueName);
        if (is_null($value)) {
             //Handle stuff and do further checks
        }
        return $value;
    }

    private static function getValueFromSession($valueName)
    {
        $value = null;
        if (isset($_SESSION[$valueName])) {
            $value = $_SESSION[$valueName];
        }
        return $value;
    }

    private static function setValue($valueName, $value)
    {
        $_SESSION[$valueName] = $value;
    }

    private static function clearValue($valueName)
    {
        if (isset($_SESSION[$valueName])) {
            unset($_SESSION[$valueName]);
        }
    }

    public static function getCustomer()
    {
        $customer = '';
        try {
            $customer = SessionManager::getValue('customer');
        } catch (Exception $e) {
            $customer = '';
        }
        return $customer;
    }

    public static function setCustomer($customer)
    {
        SessionManager::setValue('customer', $customer);
    }
}
我想象会话管理员是这样的

class CustomerPopo
{

    private $_id;

    private $_salutation;

    private $_name;

    private $_surename;

        public function getId()
    {
        return $this->_id;
    }

    public function setId($value)
    {
        $this->_id = $value;
    }

    public function getSalutation()
    {
        return $this->_salutation;
    }

    public function setSalutation($value)
    {
        $this->_salutation = $value;
    }

    public function getName()
    {
        return $this->_name;
    }

    public function setName($value)
    {
        $this->_name = $value;
    }

    public function getSurename()
    {
        return $this->_surename;
    }

    public function setSurename($value)
    {
        $this->_surename = $value;
    }

    function CustomerPopo() {

    }
}
class SessionManager
{

    private static function getValue($valueName)
    {
        $value = SessionManager::getValueFromSession($valueName);
        if (is_null($value)) {
             //Handle stuff and do further checks
        }
        return $value;
    }

    private static function getValueFromSession($valueName)
    {
        $value = null;
        if (isset($_SESSION[$valueName])) {
            $value = $_SESSION[$valueName];
        }
        return $value;
    }

    private static function setValue($valueName, $value)
    {
        $_SESSION[$valueName] = $value;
    }

    private static function clearValue($valueName)
    {
        if (isset($_SESSION[$valueName])) {
            unset($_SESSION[$valueName]);
        }
    }

    public static function getCustomer()
    {
        $customer = '';
        try {
            $customer = SessionManager::getValue('customer');
        } catch (Exception $e) {
            $customer = '';
        }
        return $customer;
    }

    public static function setCustomer($customer)
    {
        SessionManager::setValue('customer', $customer);
    }
}
有了这个,我可以消除一些由customer/customer/cusomter这个词的不同拼写引起的错误。 我想SessionManager会变得越来越大,因为代码中有大约30个会话变量

有没有一种设计模式,我可以遵循它来实现这样一个会话管理器,而最终不会让它变得更糟?如上所述,我对PHP还不是很熟悉

编辑


既然这种方法似乎是有效的,那么我如何处理我提到的30个会话变量呢?如果我有一个set/get,也许每个值都有一个清晰的方法,那么我最终会得到60-90个方法,这是一个好主意,让一个对象封装对全局变量的访问,例如
$\u SERVER
$\u get
$\u POST
$\u SESSION
,如您的示例所示。在MVC体系结构中,这样做是常见的做法

类是否应该有IDE完成的方法?这实际上取决于您,但在我工作的工作场所,通常的做法是不使用字段,而是使用字段的
const
字符串标识符,然后通过对象(例如
SessionManager
)在全局
$\u会话
变量中指定索引


但即使这样,我也可能放弃静态方法,转而使用管理器的实例。使用带有静态方法的类可以防止键入错误,但不能解决全局状态问题,这在单元测试应用程序时可能是一个巨大的问题。

最好使用一个对象封装对全局变量的访问,例如
$\u SERVER
$\u GET
$\u POST
$\u SESSION
如您的示例所示。在MVC体系结构中,这样做是常见的做法

类是否应该有IDE完成的方法?这实际上取决于您,但在我工作的工作场所,通常的做法是不使用字段,而是使用字段的
const
字符串标识符,然后通过对象(例如
SessionManager
)在全局
$\u会话
变量中指定索引


但即使这样,我也可能放弃静态方法,转而使用管理器的实例。使用静态方法上课可能会防止拼写错误,但不能解决全局状态问题,这在单元测试应用程序时可能是一个巨大的问题。

我完全同意,像你的大学那样使用$\u会话是混乱的,因为你很难弄清楚会话中实际存储了什么

在我看来,CustomerPopo是一个非常好的主意,因为它很容易理解可用的数据。此外,IDE也可以理解它,并将此信息作为代码完成和检查提供给您

我也喜欢您的SessionManager,但我会尝试摆脱这些getValue/setValue函数,转而使用诸如getCustomer/setCustomer之类的详细函数。 我猜您没有使用PHP框架。我想你应该看看它们,它们非常方便(例如Symfony或Yii2)

最后一件事:始终记住,存储在会话对象中的所有数据都将为每个请求加载和解析,不管您是否使用它。因此,如果您存储了大量仅针对特定请求的数据,则应该考虑使用另一个位置来存储它,比如外部缓存。
此外,课程还引入了状态,如果可能的话,您应该避免使用状态。

我完全同意,像您所在的大学那样使用$\u课程是很麻烦的,因为您很难弄清楚课程中实际存储了什么

在我看来,CustomerPopo是一个非常好的主意,因为它很容易理解可用的数据。此外,IDE也可以理解它,并将此信息作为代码完成和检查提供给您

我也喜欢您的SessionManager,但我会尝试摆脱这些getValue/setValue函数,转而使用诸如getCustomer/setCustomer之类的详细函数。 我猜您没有使用PHP框架。我想你应该看看它们,它们非常方便(例如Symfony或Yii2)

最后一件事:始终记住,存储在会话对象中的所有数据都将为每个请求加载和解析,不管您是否使用它。因此,如果您存储了大量仅针对特定请求的数据,则应该考虑使用另一个位置来存储它,比如外部缓存。
此外,会话还引入了状态,如果可能的话,您应该避免使用状态。

getValue、setValue函数是私有的,由getCustomer和setCustomer使用,因此我不必多次编写所有错误处理代码。你会怎么做呢?getValue、setValue函数是私有的,由getCustomer和setCustomer使用,因此我不必多次编写所有错误处理代码。你会怎么做呢?我会看看如何修改代码,这样我就不用静态方法了。我会看看如何修改代码,这样我就不用静态方法了