我正在开发一个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文件,所以我将本地化对象存储在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()
在类i的sleep方法中取消关闭连接的变量
public function __sleep()
{
unset($this->_mysqli);
}
在唤醒方法中,我重新初始化连接,使其始终可用
public function __wakeup()
{
$this->_mysql = new MysqliConnect(); //My custom mysqliwrapper
}
我希望这对你有帮助。
关于睡眠和觉醒的进一步阅读在这里