2009-09-24 20 views
1

我有一個基本上只設置和檢索會話變量的會話類, 我之所以這麼做的原因是我可以很容易地將它改爲使用會話或類似於memcache的 來設置項目和讓他們可以訪問多個頁面而不會觸及數據庫關於會話存儲類設計的反饋

然後我有這個用戶類,它使用會話對象來獲取會話變量。
我想添加到這個用戶類雖然,爲了使它更加封裝我想能夠設置我在這個類中檢索的變量 所以現在我可以顯示用戶ID $ user-> userid ;我想首先有一個方法或東西,從會話對象設置它的價值我猜 這聽起來是一個好主意或可能很多開銷嗎?

如果我想要做的是一個好主意,也許你可以建議/展示我應該怎麼做的例子?我在想,如果我添加該方法,那麼我應該將__construct方法中的代碼移動到它自己的方法中

基本上,我在構造方法中使用的類的頂部列出了變量,如果我在課堂上有多種方法,但是我需要將它們全部設置在頂部嗎?

<?PHP 
//user.class.php file 
class User 
{ 
    public $userid; 
    public $name; 
    public $pic_url; 
    public $gender; 
    public $user_role; 
    public $location_lat; 
    public $location_long; 
    public $newuser; 

    function __construct() 
    { 
     global $session; 
     if($session->get('auto_id') != ''){ 
      //set user vars on every page load 
      $this->userid = $session->get('auto_id'); //user id number 
      $this->name = $session->get('disp_name'); 
      $this->pic_url = $session->get('pic_url'); 
      $this->gender = $session->get('gender'); 
      $this->user_role = $session->get('user_role'); 
      $this->location_lat = $session->get('lat'); 
      $this->location_long = $session->get('long'); 
      $this->newuser = $session->get('newregister'); 
     }else{ 
      return false; 
     } 
    } 
} 

//with the class above I can easily show some user variables I have saved into a session like this below 
$user = new user(); 
$user->userid; 

?> 
+4

爲什麼不通過構造函數傳遞會話而不是將其用作全局?這會使依賴更加明顯。 – cdmckay 2009-09-24 20:35:28

+0

@cdmckay好主意我可能會這麼做 – JasonDavis 2009-09-24 21:42:08

回答

2

一般來說你的想法是一個很好的 3件事我會做出不同:

1)在您的實現似乎並不認爲有幾個用戶。即同一類的幾個實例。

2)我會使用factories而不是在構造函數中使用IF。 因此,對於已保存在會話的用戶,你會打電話:

$savedUser = User::fromSession($userId); 

新用戶

$user = new User() 

3)使用serialize和unserialze功能的數據保存到會話

那麼你的類可以可以實現爲

public static function fromSession($userId) { 
    return unserialize($session->get('users_'.$userId)); 
} 

public function save() { 
    return $session->set('users_'.$this->id , serialize($this)); 
} 
+0

我唯一要做的調整就是將'fromSession'和'save'移入他們自己的類(甚至更好 - 界面),以使測試變得更簡單。讓'用戶'處理用戶數據的東西,讓其他東西處理保存/序列化/檢索/創建 – rojoca 2009-09-24 21:28:41

+0

感謝您的示例,我很好奇,爲什麼序列化和反序列化會話的東西,目前我使用會話沒有這樣做,他們工作正常如果有什麼好處呢?我的意思是基本的是$ _SESSION ['userid']可以在任何地方使用,而無需serializng或反序列化? – JasonDavis 2009-09-24 21:36:33

+0

其優點是它可以在一個步驟中序列化對象的所有屬性。 所以你不需要得到$ _SESSION ['userid'],$ _SESSION ['username']等。 – elviejo79 2009-09-25 01:24:16

0

我會成立一個新的會話中包含「ValuesInSession」的名字真還是取決於你是否擁有對你的用戶類中的字段會話值假。然後,在會話\用戶類,你可以檢查該會話是否是真的還是假的,並據此設定值(從現有會話IE或爲空字符串\ 0)

編輯:你可以,或者到把代碼在用戶或會話類,寫一個新的類,可以與您的用戶類正常設置值(也許它可以延長會議類?)

1

我想這是含糊不清的答案是「這是一個好主意「的問題。根據我的理解,在會話中查找變量與從數據庫刷新變量是複雜查詢和反序列化數據之間的折衷問題。會話數據不是免費的魔術緩存,它可以逃避數據庫調用,它只是一個數據庫調用的便捷包裝,您不必處理。您放置在會話中的任何變量必須是可序列化的。然後管理整個序列化數據的集合;服務器使用會話密鑰獲取數據,將其全部反序列化,並將其交給php腳本。然後,當它關閉該請求 - 響應週期的會話時,它會將其全部序列化並將其放回db中。

所以,在處理所有可能的混亂,在某些情況下,比打開連接和直接要求db相同的東西(或東西的子集)的混亂更糟糕。

我會說在會話中放置一個或兩個關鍵值是一個很好的停止位置,並且依賴於它過於嚴重的狀態性是一個不太理想的計劃。

0

但是,我不確定我是否理解這個問題,但是,如果您使用的是PHP 5,則可以使用__set魔術方法來解決此問題。

修改當前類:

class User 
{ 
    private $id; 
    private $data = array(); 

    public function __construct() 
    { 
      global $session; 
      $this->id = $session->get('auto_id'); 
      $this->data = array(
       'disp_name'=>$session->get('disp_name'), 
       'pic_url'=>$session->get('pic_url'), 
       'gender'=>$session->get('gender'), 
       'user_role'=>$session->get('user_role'), 
       'lat'=>$session->get('lat'), 
       'long'=>$session->get('long'), 
       'newregister'=>$session->get('newregister') 
     ); 
    } 

    // return the user id 
    public function id() 
    { 
     return $this->id; 
    } 

    // the __get magic method is called when trying to retrieve a value of a 
    // property that has not been defined. 
    public function __get($name) 
    { 
     if(array_key_exists($name, $this->data)) 
     { 
      return $this->data[$name]; 
     } 
     return null; 
    } 


    // the __set magic method is called when trying to store a value in a property 
    // that has not been defined. 
    public function __set($name, $value) 
    { 
     global $session; 
     // check if the key exists in the 'data' array. 
     // if so, set the value in the array as well as the session 
     if(array_key_exists($name, $this->data)) 
     { 
      $this->data[$name] = $value; 
      $session->set($name, $value); 
     } 
    } 
} 

這樣你仍然可以獲取和設置值,你是一樣的,但也將存儲在會話類的設定值。

爲了測試這個:

$user = new User; 
if($user->id()) 
{ 
    echo $user->disp_name; 
    $user->disp_name = 'new name'; 
    echo $session->get('disp_name'); 
} 
0

我不會建議你,因爲:

  1. 這不是一個很好的做法,選擇「在未來的需求情況」的架構('的原因我是這樣做的,所以我可以輕易改變')。檢查http://www.startuplessonslearned.com(Eric Ries)或http://highscalability.com文章
  2. 您的代碼很難/無法測試(有關更多信息,請參見Misko Hevery的博客(A谷歌傳播者)http://misko.hevery.com)。
  3. 您正在使用「全局」(如果要跟蹤依賴關係,從來就不是一個好主意)。
  4. 最好分離「業務邏輯」(User類)和佈線/建築物(例如工廠類)。 (見http://en.wikipedia.org/wiki/Single_responsibility_principle和「關注點分離」)

對於真正的好代碼示例(和了解哪些OO法律不應該被打破),我可以建議你MISKO的博客(也不要錯過他在谷歌技術講座你可以在YouTube上找到)。我相信你會愛上它們的。

希望這會有所幫助。