Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> PHP aktualizuje zserializowany w sesji obiekt
macq
post
Post #1





Grupa: Zarejestrowani
Postów: 11
Pomógł: 0
Dołączył: 8.11.2012

Ostrzeżenie: (0%)
-----


Witam,

wykorzystywałem ostatnio sesje do przechowywania obiektów i spostrzegłem bardzo ciekawe zachowanie PHP, tj. jeżeli zapiszę obiekt do sesji to przy jego dalszej modyfikacji niejawnie aktualizowany jest on w sesji. Czy ktoś jest w stanie wytłumaczyć jak działa ten mechanizm 'pod spodem'?

Przygotowałem paczkę która prezentuje to zagadnienie:

SessionRegistry.php
  1. <?php
  2. class SessionRegistry{
  3. private static $instance;
  4.  
  5. private function __construct(){
  6.  
  7. }
  8.  
  9. static function instance(){
  10. if(!isset(static::$instance)){
  11. static::$instance = new self();
  12. }
  13.  
  14. return static::$instance;
  15. }
  16.  
  17. protected function get($name){
  18. if(!isset($_SESSION[__CLASS__][$name])){
  19. return NULL;
  20. }
  21.  
  22. return $_SESSION[__CLASS__][$name];
  23. }
  24.  
  25. protected function set($name, $val){
  26. $_SESSION[__CLASS__][$name] = $val;
  27. }
  28.  
  29. protected function unregister($name){
  30. unset($_SESSION[__CLASS__][$name]);
  31. }
  32.  
  33.  
  34. function SetManager(Manager $upload){
  35. $this->set('manager', $upload);
  36. }
  37.  
  38. function GetManager(){
  39. return $this->get('manager');
  40. }
  41.  
  42. function UnregisterManager(){
  43. $this->unregister('manager');
  44. }
  45.  
  46. function ManagerScreen(){
  47. return print_r($_SESSION[__CLASS__]['manager']);
  48. }
  49.  
  50. }
  51.  




Manager.php
  1. <?php
  2. class Manager{
  3. private $new = array();
  4. private $good = array();
  5. private $bad = array();
  6.  
  7.  
  8. function __construct(){
  9.  
  10. }
  11.  
  12. function hireWorkers($num=15){
  13. $num = (int)$num;
  14. for($i=0; $i<$num; $i++){
  15. $this->new[] = new Worker();
  16. }
  17. }
  18.  
  19.  
  20. function SaveToSession(){
  21. $Sess_reg = SessionRegistry::instance();
  22. $Sess_reg->SetManager($this);
  23. }
  24.  
  25. static function LoadFromSession(){
  26. $Sess_reg = SessionRegistry::instance();
  27. return $Sess_reg->GetManager();
  28. }
  29.  
  30.  
  31. static function SessionScreen(){
  32. $Sess_reg = SessionRegistry::instance();
  33. $Sess_reg->ManagerScreen();
  34. }
  35.  
  36.  
  37. function filterWorkers(){
  38. foreach($this->new as $worker){
  39. if(rand(0, 1) == 1){
  40. $this->good[] = $worker;
  41. }else{
  42. $this->bad[] = $worker;
  43. }
  44. }
  45.  
  46. $this->new = array();
  47. }
  48.  
  49. function undoFilter(){
  50. $this->new = array_merge($this->good, $this->bad);
  51. $this->good = array();
  52. $this->bad = array();
  53. }
  54.  
  55. function reset(){
  56. $this->new = array();
  57. $this->good = array();
  58. $this->bad = array();
  59. }
  60.  
  61. }
  62.  
  63.  
  64. class Worker{
  65. private $id;
  66.  
  67. function __construct(){
  68. $this->id = uniqid();
  69. }
  70. }




set.php
  1. <?php
  2. require_once 'loader.php';
  3.  
  4.  
  5. $Manager = new Manager();
  6.  
  7. $Manager->hireWorkers();
  8. $Manager->SaveToSession();
  9.  
  10. ?>




change.php
  1. <?php
  2. require_once 'loader.php';
  3.  
  4.  
  5.  
  6. $Manager = Manager::LoadFromSession();
  7.  
  8. $Manager->filterWorkers();
  9. //$Manager->undoFilter();
  10. ?>




show.php
  1. <pre>
  2. <?php
  3. require_once 'loader.php';
  4.  
  5.  
  6. print_r(Manager::SessionScreen());
  7.  
  8.  
  9. ?>
  10. </pre>




loader.php
  1. <?php
  2. function __autoload($class){
  3. require_once "{$class}.php";
  4. }
  5.  
  6. ?>






Przepływ zdarzeń:
1. Uruchamiam set.php
2. Uruchamiam show.php
3. Wynik print_r:
Kod
Manager Object
(
    [new:Manager:private] => Array
        (
            [0] => Worker Object
                (
                    [id:Worker:private] => 509b99e26056c
                )

            [1] => Worker Object
                (
                    [id:Worker:private] => 509b99e26094d
                )

            [2] => Worker Object
                (
                    [id:Worker:private] => 509b99e260d33
                )

            [3] => Worker Object
                (
                    [id:Worker:private] => 509b99e261148
                )

            [4] => Worker Object
                (
                    [id:Worker:private] => 509b99e261518
                )

        )

    [good:Manager:private] => Array
        (
        )

    [bad:Manager:private] => Array
        (
        )

)

Jak widać jest wszystko co powinno być. Manager utworzył instancje Workerów, i zapisał się do sesji - wynikiem jest uzupełniona tablica new.

4. Uruchamiam change.php (zwróćcie uwagę, że nie ma tam wywołania SaveToSession)
5. Ponownie uruchamiam show.php i tym razem na ekranie pojawia się coś takiego:
Kod
Manager Object
(
    [new:Manager:private] => Array
        (
        )

    [good:Manager:private] => Array
        (
            [0] => Worker Object
                (
                    [id:Worker:private] => 509b99e26094d
                )

            [1] => Worker Object
                (
                    [id:Worker:private] => 509b99e260d33
                )

            [2] => Worker Object
                (
                    [id:Worker:private] => 509b99e261d0e
                )

        )

    [bad:Manager:private] => Array
        (
            [0] => Worker Object
                (
                    [id:Worker:private] => 509b99e26056c
                )

            [1] => Worker Object
                (
                    [id:Worker:private] => 509b99e261148
                )

        )

)


Plik change.php zmienił obiekt, 'nie mówiąc nic o tym sesji', ale sesja 'sama zaktualizowała' jego stan... Czy nie powinno być przypadkiem tak, że sesja powinna utrzymywać 'pierwotny' stan obiektu? Bardzo proszę, w miarę możliwości, wytłumaczyć co się dzieje 'pod maską' tego przykładu.


Z góry serdecznie dziękuję,
Maciek

Ten post edytował macq 8.11.2012, 13:29:03
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 24.12.2025 - 02:54