繁体   English   中英

在类中使用mysqli对象,该对象应存储在会话中-更好的方法

[英]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对象,但据我所知,不可能在类中使用requireinclude

您不能序列化资源对象,这是没有意义的。

就您而言,如果$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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM