簡體   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