我的一位同事搬到了另一家公司,我得到了现有项目的源代码。
令我震惊的是代码看起来有多乱。我不是PHP开发人员,所以这可能是一个愚蠢的问题,但在我看来他使用$_SESSION
太多了,我们在Sessions上遇到很多错误。我想知道封装$_SESSION
并为每个使用自己的方法的值编写是否合适。
我在这段代码中看到的问题是他使用像这样的会话对象
$_SESSION['customer']['items'] = getItems() //returns an array
$_SESSION['article'][$Id]['name'] = utf8_decode[$received[1]];
因此,从我的观点来看,我会将所有内容存储在简单的Popos中,并将它们放入Session中。
所以客户的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() {
}
}
我想像这样的SessionManager
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);
}
}
有了这个,我可以消除由于客户/客户/客户这个词的不同拼写而产生的一些错误。 我想SessionManager会变大,因为我们在代码中有~30个Session变量。
我是否有一个设计模式可以实现这样的SessionManager而不会让它最终变得更糟?如上所述,我对PHP(还)不是很熟悉。
修改:
由于该方法似乎有效,我如何处理我提到的30个Session变量?如果我对每个值都有一个set / get和一个明确的方法,我最终会得到60-90个方法
答案 0 :(得分:1)
最好让一个对象封装对全局变量的访问,例如$_SERVER
,$_GET
,$_POST
或$_SESSION
。 MVC架构中的常见做法是这样做。
该类是否应该具有IDE completition的方法?这实际上取决于你,但在我工作的工作场所的常见做法是不要使用它们,而是改为使用const
字段的字符串标识符,然后用于指定全局$_SESSION
中的索引通过对象变量,例如SessionManager
。
但即便如此,我可能会放弃静态方法,而是选择管理器的实例。使用静态方法的类可以防止打字错误,但不能修复全局状态问题,这在单元测试应用程序时可能是个大问题。
答案 1 :(得分:1)
我绝对同意像你的大学一样使用$ _SESSION很麻烦,因为你很难弄清楚会话中实际存储的内容。
在我看来,CustomerPopo是一个非常好的主意,因为它很容易理解可用的数据。此外,IDE也可以理解它,并在代码完成和检查时向您提供此信息。
我也喜欢你的SessionManager,但是我会尝试摆脱这些getValue / setValue函数并移动以移动像getCustomer / setCustomer这样的详细函数。 我猜你没有使用PHP框架。我想你应该看看它们,它们非常方便(例如Symfony或Yii2)。
最后一件事:始终记住,对于每个请求,将加载和解析存储在会话对象中的所有数据,不管您是否使用它。因此,如果您存储了大量仅用于特定请求的数据,则应考虑使用其他位置来存储它,如外部缓存。 此外,会话引入了状态,如果可能的话,应该避免使用状态。