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

Php 在类中使用mysqli对象,它应该存储在会话更好的方法中,php,class,session,mysqli,Php,Class,Session,Mysqli,我正在开发一个web应用程序,它需要有几种语言。对于每个注册用户,我将所选语言存储在数据库中 此外,登录用户可以选择一种不同的语言,然后动态更改,这意味着网站应该重新加载并以新选择的语言显示 翻译文件是简单的CSV文件,目前大约有600对键值对。 我现在实现了一个类本地化,它将所选语言的CSV文件加载到一个数组中。A因为我认为最好不要在每个新页面上读取CSV文件,所以我将本地化对象存储在会话中 现在的问题是,如果用户更改了语言,我希望更新数据库中选定的语言,还需要初始化支持的可选语言,这意味着我

我正在开发一个web应用程序,它需要有几种语言。对于每个注册用户,我将所选语言存储在数据库中

此外,登录用户可以选择一种不同的语言,然后动态更改,这意味着网站应该重新加载并以新选择的语言显示

翻译文件是简单的CSV文件,目前大约有600对键值对。 我现在实现了一个类本地化,它将所选语言的CSV文件加载到一个数组中。A因为我认为最好不要在每个新页面上读取CSV文件,所以我将本地化对象存储在会话中

现在的问题是,如果用户更改了语言,我希望更新数据库中选定的语言,还需要初始化支持的可选语言,这意味着我需要一个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,只需重新打开数据库连接。

谢谢您的回复。我终于想出了办法。 我仍然需要在我想要查询数据库的每个函数中使用require,但我可以接受它。 另一个问题是,我使用了require_一次,而不是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.";
        }
    }
}

在这些情况下,我使用的是classmethods(睡眠和唤醒)

在类的sleep方法中,我取消设置关闭连接的变量

public function __sleep()
{
    unset($this->_mysqli);
}
在唤醒方法中,我重新初始化连接,使其始终可用

public function __wakeup()
{
    $this->_mysql = new MysqliConnect(); //My custom mysqliwrapper
}
我希望这能帮到你

关于睡眠与觉醒的进一步阅读

A因为我认为最好不要在每个新页面上读取CSV文件,所以我将本地化对象存储在会话中

因此,您让应用程序在每个新页面上读取一个序列化文件,这一切都是一样的

因此,您使应用程序变得更加复杂,消耗了更多的资源,使自己陷入了困境,却一无所获


这就是为什么有人说过早优化是万恶之源。

正如我在帖子中提到的,我已经发现了。。。我还写到,我不知道如何打开数据库连接,因为不可能使用require。但我要避免的是,在类的每个函数中硬编码连接。您可以使用require。无论如何,我假设您的应用程序需要您的MySQL连接。为什么主应用程序文件/配置中不包含此文件$mysqli是从构造函数设置的,因此您的应用程序可能已经打开了连接。我真的不知道将require_oncedb_connection.php放在哪里。如果我把它放在类定义之前,我就不能使用mysqli对象。如果我把它放在类中,我会得到一个解析器错误。在应用程序的其余部分,它包括在内。可以在类中使用require或include。基本上,这只有在加载类时才有意义。正如在另一篇评论中提到的,我真的不知道把require_oncedb_connection.php放在哪里。如果我把它放在类定义之前,我就不能使用mysqli对象。如果我把它放在类中,我会得到一个解析器错误。