[英]Use mysqli object in class, which should be stored in session - better approaches
我正在开发一个Web应用程序,它需要多种语言版本。 对于每个注册用户,我都会将所选语言存储在数据库中。
此外,已登录的用户可以选择其他语言,然后它应该随时更改,这意味着网站应该重新加载并以新的所选语言显示。
转换文件是带有键值对的简单CSV文件(目前约有600对)。 现在,我实现了一个Localization
类,该类将所选语言的CSV文件加载到数组中。 因为我认为最好不要在每个新页面上都读取CSV文件,所以我将Localization
对象存储在SESSION中。
现在的问题是,如果用户更改语言,则我想更新数据库中的所选语言,并且还需要初始化支持的(可选)语言,这意味着我需要mysqli连接。
class Localization
{
private $mysqli; // cannot be serialized and stored in session
private $language;
private $supportedLanguages;
public function __construct($language, $mysqli) {
$this->mysqli = $mysqli;
$this->initSupportedLanguages();
$this->setLanguage($language);
}
[...]
public function setLanguage($language) {
if ($language != $this->language)
{
if ($this->isSupportedLanguage($language))
{
$this->language = $language;
set_current_user_language($language, $this->mysqli);
// loads the csv file into an array
$this->loadTranslation($language);
}
else
{
echo "Language is not supported.";
}
}
}
private function initSupportedLanguages() {
$query = "SELECT * FROM Sprache";
if ($stmt = $this->mysqli->prepare($query))
{
$stmt->execute();
$result = $stmt->get_result();
foreach ($result as $row)
{
$this->supportedLanguages[$row['LanguageCode']] = $row['Name'];
}
}
else
{
echo "Could not create prepared statement.";
}
}
[...]
}
创建对象后,在首页上一切正常。 但是,如果用户访问下一页,则无法访问mysqli对象。
不幸的是,我发现无法序列化mysqli对象并将其存储在会话中,这导致无法访问它的问题。
我现在正在寻求一种以最佳实践方式处理数据库连接的方法。 值得一提的是,其他函数使用添加了require_once
功能的mysqli对象,但据我所知,不可能在类中使用require
或include
。
您不能序列化资源对象,这是没有意义的。
就您而言,如果$mysqli == null
,则重新打开数据库连接。
因为我认为最好不要在每个新页面上都读取CSV文件,所以我将Localization对象存储在SESSION中。
因此,您使应用程序读取了每个新页面上的序列化文件,它们都是一样的。
因此,您使应用程序变得更加复杂,消耗了更多资源,并使自己陷入困境,却一无所获。
这就是为什么有人说过早优化是万恶之源的原因。
感谢您的回复。 我终于想出了办法。 我仍然必须在每个要查询数据库的函数中使用require
,但是我可以接受。 另一个问题是,我使用了require_once
而不是显然不能正常工作的require
。
public function setLanguage($language) {
if ($language != $this->language)
{
if ($this->isSupportedLanguage($language))
{
$this->language = $language;
require(PATH_INCLUDES . '/db_connect.php');
set_current_user_language($language, $mysqli);
$this->loadTranslation($language);
}
else
{
echo "Language is not supported.";
}
}
}
在这些情况下,我使用的是__sleep()
和__wakeup()
在类的sleep方法中,我未设置关闭连接的变量
public function __sleep()
{
unset($this->_mysqli);
}
在唤醒方法中,我重新初始化连接,使其始终可用
public function __wakeup()
{
$this->_mysql = new MysqliConnect(); //My custom mysqliwrapper
}
希望这对您有所帮助。
在此处进一步阅读睡眠和唤醒
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.