2010-11-23 105 views
15

我對網絡編程相當陌生,過去我主要使用java創建桌面應用程序。在php中的對象持久性

我想弄清楚如何在php中創建持久對象。也許持久不是正確的詞,我不希望對象是每個客戶端獨特的,就像我會通過序列化它在一個會話變量。我希望在服務器上創建對象,並且始終可以訪問同一個對象。該對象將查詢數據庫並存儲一些數據。通過這種方式,每次頁面加載時,php代碼都會從相同的持久對象獲取數據,而不必每次都查詢數據庫。

我目前使用單身模式進行對象創建,因爲我最初的理解是它可以讓我完成我想要的。部分對象是一個數組,當我執行一個向數組添加值的php頁面,並在同一頁面上訪問該值時,它很好。但是,當我向數組添加一個值,然後加載訪問該值的另一​​個頁面時,該數組又回到了空白狀態。

這可能嗎?我是否反應過度,認爲查詢數據庫非常糟糕?在任何一秒鐘內,有時會有多達20個用戶請求數據,而且我覺得每次查詢數據庫都是可笑的。

感謝

+2

20用戶請求每秒不是很多 – Ben 2010-11-23 01:32:30

+0

更多用戶每頁加載超過20個查詢的數量並不多。這不是關鍵點。主要問題是在數據結構發生變化時維護數據庫。 – Tarion 2013-01-10 20:42:11

回答

9

通常你通過使用數據庫來獲得持久性。如果這是開始緩存數據的瓶頸,例如在memcached中,或者在您的Web服務器上使用serialized陣列的本地文件。

+2

對於速度更快的簡單查詢,可以反覆查詢數據庫中相同的數據,請緩存對象?假設查詢本身需要0.1秒。通常,哪個是更快的文件+序列化對象或數據庫+對象羣體? – 2012-02-08 13:24:05

+0

在你遇到真正的問題之前,你應該不關心表現。 – Tarion 2013-01-10 20:43:26

13

PHP不具有持久性的概念,Java那樣:在JVM允許Java應用程序在HTTP請求之間的內存持續;每當一個新的HTTP請求被提供時,web服務器會分叉一個新的PHP進程,因此對象的靜態變量不會在請求之間爲您保留數據。

使用數據庫來存儲持久性數據。 Web編程側重於併發性,所以你不應該擔心數據庫查詢 - 很少有20秒。如果達到數據庫的限制,可以通過添加只讀從站來添加緩存層或「擴展」硬件。

0

Web編程中的數據持久性是通過使用Cookie /會話並在Web頁面調用中傳遞Cookie /會話變量來完成的。理論上,任何類型的數據都可以存儲在這些變量中 - 但是對於大多數實際的目的,只有需要識別/重建所需對象(帶或不帶數據庫)的更重要的數據(看它們更像是令牌)才能傳輸到並從服務器和瀏覽器。

0

我建議你看看memcached。當您談論服務器負載和性能功能時,一個有用的指標通常是每秒鐘的頁數。如果您有專門的服務器和未經優化但密集型的內容,您可能只能提供5頁/秒。利用數據緩存是增加3到10倍的好方法。然而,就數據的陳舊程度而言,它總是一種折衷。您真的需要測試您的站點以正確理解(量化)其他可能的性能限制因素,例如每頁的其他連接(圖像,css等),文件I/O,其他網絡活動以及最後但並非最不重要的實際

0

停止使用單例並使用依賴注入。

最好的方法是使用DataMapper(http://www.martinfowler.com/eaaCatalog/dataMapper.html)並通過動態屬性將其附加到對象。讓數據映射器處理持久性。

$CS = new CookieStorage(); 
$SS = new SessionStorage(); 
$FS = new FileStorage('config/object.db'); 

$DM = new ObjectDataMapper($FS); 

$O = new Object($DM); 

$Object->DynamicProperty = 1; 

現在DynamicProperty將自動持續不斷,並自動從文件加載object.db。類定義:

class Object 
{ 
    public function __construct(MapperInstance $Storage = NULL) 
    { 
     $this->setMapper($Storage?: new ObjectDataMapper(new FileStorage('config/object.db'))); 
    } 

    public function __get($name) 
    { 
     $this->_Mapper->getProperty($name); 
    } 

    public function __isset($name) 
    { 
     $this->_Mapper->isProperty($name); 
    } 

    public function __set($name, $value) 
    { 
     $this->Mapper->setProperty($name, $value); 
    } 
} 
0

可以在當前會話中存儲對象。現在只需創建一個能夠存儲和重新創建對象本身的基類。任何派生的對象也將是持久的。

你可能想在這裏閱讀:persistent base class and example

據我所知會話存儲在RAM中,因此應該是快於序列化對象到磁盤,以實現持久性。

1

雖然它可能不是最漂亮的解決方案,但您可以使用SESSIONS這個問題。

$object = unserialize($_SESSION['object']); 

雖然ofcourse這種做法似乎最簡單的:

class SomeObject{ 

    public function __costructor{ 
     $_SESSION['object'] = serialize($this); 
    } 

} 

和另一個頁面上,你可以簡單地調用對象。它應該以最大的預防措施:

  1. 知道這取決於您的服務器的流量時,會話不應該在尺寸過大許多用戶同時要求每個會話。根據自己的判斷來調整尺寸。

  2. 總是序列化和反序列化,因爲會話沒有完成,所以會出現錯誤行爲。

什麼曾經航行你的船。在你自己的分析中這樣做。 goodluck