Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [php] klasa obsługująca sesję
Black-Berry
post
Post #1





Grupa: Zarejestrowani
Postów: 663
Pomógł: 6
Dołączył: 3.06.2007
Skąd: Kraków

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


Wiem że to sporo ale może ktoś już to robił albo jest w sesjach mastacha i będzie w stanie to ocenić.
  1. <?php
  2.    class Main_Session
  3.    {
  4.        private $data = array(); //data storage
  5.        private $sessionName = 'edicoSession';
  6.        private $sessionId = 0;
  7.        private $sessionActiveTime = 900;
  8.        private $folder;
  9.        private $activesSessionsList = array();
  10.        
  11.        public function __construct()
  12.        {
  13.            //current session folder...
  14.            $this->folder = MAIN_PATH . 'edc_session/';
  15.            //starting session...
  16.            $this->_start();
  17.            //testing run of the session...
  18.            if (array_key_exists('run',$this->data)) {
  19.               $this->data['run'] = $this->data['run'] + 1;
  20.            } else {
  21.                $this->data['run'] = 0;
  22.                $this->data['sessionCookie'] = $this->sessionId;
  23.                $this->data['browser'] = $_SERVER['HTTP_USER_AGENT'];
  24.                $this->startIp = $_SERVER['REMOTE_ADDR'];
  25.            }
  26.            //removing old session files...
  27.            $this->_updateActiveSessionsList();
  28.        }
  29.        
  30.        public function __destruct()
  31.        {
  32.            //saving session data to file...
  33.            $this->_save();
  34.        }
  35.        
  36.        public function __get($aKey)
  37.        {
  38.            //handeling magic get method...
  39.            if (isset($this->data[$aKey])) {
  40.                return $this->data[$aKey];
  41.            }
  42.        }
  43.        
  44.        private function __set($aKey, $aValue)
  45.        {
  46.            //handeling magic set method...
  47.            $this->data[$aKey] = $aValue;
  48.        }
  49.        
  50.        private function _start()
  51.        {
  52.            if ($_COOKIE[$this->sessionName] == '') {
  53.                //create new session and  sessionId...
  54.                $this->sessionId = encrypt(time()*rand(0,999999)).random_string(6);
  55.                setcookie($this->sessionName, $this->sessionId);
  56.            } else {
  57.                //load existing session file to use by this session...
  58.                $data = $this->_load($_COOKIE[$this->sessionName]);
  59.                if ($data['browser'] == $_SERVER['HTTP_USER_AGENT']) {
  60.                    //use existing cookie as sessionId...
  61.                    $this->sessionId = $_COOKIE[$this->sessionName];
  62.                    $this->data = $data;
  63.                } else {
  64.                    //cookie could have been stolen; start new session...
  65.                    $this->sessionId = encrypt(time(0,999999)*rand()).random_string(6);
  66.                    setcookie($this->sessionName, $this->sessionId);
  67.                }
  68.            }
  69.        }
  70.        
  71.        private function _load($aSessionId)
  72.        {
  73.            //creating session file name...
  74.            $fileName = $this->folder.$aSessionId.'.dat';
  75.            if (file_exists($fileName)) {
  76.                // geting data from file...
  77.                $file = fopen($fileName, 'r');
  78.                $data = fread($file, filesize($fileName)+1);
  79.                $data = unserialize($data);
  80.                fclose($file);
  81.            }
  82.            return $data;
  83.        }
  84.        
  85.        private function _save()
  86.        {
  87.            create_folder($this->folder);
  88.            //saving data to a file based on session id...
  89.            $file = fopen($this->folder.$this->sessionId.'.dat', 'w');
  90.            $data = $this->data;
  91.            //serializing data...
  92.            $data = serialize($data);
  93.            fwrite ($file, $data);
  94.            fclose($file);
  95.        }
  96.        
  97.        private function _updateActiveSessionsList()
  98.        {
  99.            $folder = opendir($this->folder);
  100.            while (($file = readdir($folder)) !== false) {
  101.                if ($file != '.' and $file != '..') {
  102.                    if(time() - filemtime($this->folder.$file) > $this->sessionActiveTime) {
  103.                        //deleting session file older then $this->sessionActiveTime
  104.                        unlink($this->folder.$file);
  105.                    } else {
  106.                        //saving info about all sessions to a variable for other use...
  107.                        $sessionFile = fopen($this->folder.$file, 'r');
  108.                        $data = fread($sessionFile, filesize($this->folder.$file)+1);
  109.                        $this->activesSessionsList[] = unserialize($data);
  110.                        fclose($sessionFile);
  111.                    }
  112.                }
  113.            }
  114.            closedir($folder);
  115.        }
  116.    }
  117. ?>


Ten post edytował Black-Berry 14.09.2008, 23:41:06
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 11)
ahead
post
Post #2





Grupa: Zarejestrowani
Postów: 33
Pomógł: 2
Dołączył: 13.08.2008

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


  1. <?php
  2. if ($data['browser'] == $_SERVER['HTTP_USER_AGENT'] ) {
  3.                    //use existing cookie as sessionId...
  4.                    $this->sessionId = $_COOKIE[$this->sessionName];
  5.                    $this->data = $data;
  6.                } else {
  7.                    //cookie could have been stolen; start new session...
  8.                    $this->sessionId = encrypt(time(0,999999)*rand()).random_string(6);
  9.                    setcookie($this->sessionName, $this->sessionId);
  10.                }
  11. ?>


Dodał bym jeszcze przechowywanie adresu ip usera w $data i sprawdziłbym czy zgadza się z aktualnym w tym miejscu. W przeciwnym wypadku, cookie można podstawić do tej samej przeglądarki. Ogólnie chyba wszystko jest ok.

Ten post edytował ahead 15.09.2008, 08:25:11
Go to the top of the page
+Quote Post
Black-Berry
post
Post #3





Grupa: Zarejestrowani
Postów: 663
Pomógł: 6
Dołączył: 3.06.2007
Skąd: Kraków

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


wie ktoś może jak ogrinalna sesja php radzi sobie z autentyfikacją użytkownika? Czy sprawdza przeglądarkę i IP ? Może ma jeszcze jakieś inne metody ?
Go to the top of the page
+Quote Post
SHiP
post
Post #4





Grupa: Zarejestrowani
Postów: 697
Pomógł: 47
Dołączył: 19.12.2003
Skąd: Lublin

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


Jakie dużo (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) 120 linijek. Ja dawłem frameworka i ludzie odpowiadali (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif)
  1. <?php
  2.               $file = fopen($fileName, 'r');
  3.               $data = fread($file, filesize($fileName)+1);
  4.               $data = unserialize($data);
  5.               fclose($file);
  6. ?>


1. To mi się nie podoba, wygląda jak przekombinowane file_get_contents" title="Zobacz w manualu PHP" target="_manual.
2. Za każdym razem wywołujesz funkcję czyszczącą stare sesje, która sprawdza czasy wszystkich plików po kolei. Jak wszyscy wiemy operacje na plikach są zabójczo wolne. Nie lepiej zrobić cache w postaci zserializowanej tablicy plików i czasów w jedym pliku? Myślę, że byłoby optymalniej przy większej ilości sesji.
EDIT:
Zapomniałem dopisać, że ogólnie bardzo fajna klasa (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
3. dodaj __isset()

Ten post edytował SHiP 15.09.2008, 10:35:16
Go to the top of the page
+Quote Post
Black-Berry
post
Post #5





Grupa: Zarejestrowani
Postów: 663
Pomógł: 6
Dołączył: 3.06.2007
Skąd: Kraków

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


bez cache'a się nie obejdzie bo już mi zaczeło mulić.

Myślisz ze na bazie mysql byłoby szybciej ? Miałem nadzieję że pliki będą szybsze i dlatego takie coś.
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #6





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

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


Pliki sa prostsze (hmm, u mnie niewiele szybsze), ale nie zliczysz ilosci aktywnych userow. Baze (lub cos innego) bedziesz musial uzyc jak bedziesz mial wiele serwerow z aplikacjami, zeby user mial na kazdym dostep do swojej sesji.
Go to the top of the page
+Quote Post
Black-Berry
post
Post #7





Grupa: Zarejestrowani
Postów: 663
Pomógł: 6
Dołączył: 3.06.2007
Skąd: Kraków

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


słuszna uwaga z tymi wieloma serwerami. Mozna zliczyć pliki. Wtedy masz aktywnych userów. Nastawiam się na prędkość. Mam nadzieję że jak dodam cacha to będzie śmigac. Pracuję nad tym właśnie.
Go to the top of the page
+Quote Post
SHiP
post
Post #8





Grupa: Zarejestrowani
Postów: 697
Pomógł: 47
Dołączył: 19.12.2003
Skąd: Lublin

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


@dr_bonzo: dało by się coś takiego napisać, wykły count();

Najlepiej byłoby stworzyć 2 wersje (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) . Ale moim skromnym zdaniem baza będze dużo lepszym rozwiązaniem. Po prostu daje dużo większą elastyczność. Jeśli portal urośnie do rozmiarow kilku tys sesji to będzie problem z operowaniem na takiej tablicy w php. Oczywiście to tylko gdybanie ;-).
Go to the top of the page
+Quote Post
Black-Berry
post
Post #9





Grupa: Zarejestrowani
Postów: 663
Pomógł: 6
Dołączył: 3.06.2007
Skąd: Kraków

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


Po waszych radach i testach doszedłem do wniosku że pliki nie są takei fajne. Poza tym baza jest o niebo szybsza. Moje zmagania niech będą zatem przestrogą dla innych (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Nowy kod. Jeszcze raz prosze o sugestie

  1. <?php
  2.    class Main_Session extends Main_Object
  3.    {
  4.        private $data = array(); //data storage
  5.        private $sessionId = 0;
  6.        private $sessionName = 'edicoSession';
  7.        
  8.        public function __construct()
  9.        {
  10.            parent__construct();
  11.            $this->dbTable = $this->settings->dbPrefix . 'edc_session_main';
  12.            $this->_start();
  13.            //testing run of the session...
  14.            if (array_key_exists('run',$this->data)) {
  15.               $this->data['run'] = $this->data['run'] + 1;
  16.            } else {
  17.                $this->data['run'] = 0;
  18.                $this->data['sessionCookie'] = $this->sessionId;
  19.                $this->data['browser'] = $_SERVER['HTTP_USER_AGENT'];
  20.                $this->startIp = $_SERVER['REMOTE_ADDR'];
  21.                $this->_cleanDatabase();
  22.            }
  23.        }
  24.        
  25.        public function install()
  26.        {
  27.            $query = "DROP TABLE IF EXISTS $this->dbTable";
  28.            $this->dbDriver->query($query);
  29.            $query = "CREATE TABLE $this->dbTable (
  30.                    `id` VARCHAR(64) NOT NULL, PRIMARY KEY(`id`),
  31.                    `last_update` DATETIME, INDEX (`last_update`),
  32.                    `data` TEXT
  33.                ) ENGINE=InnoDB CHARACTER SET `utf8`;";
  34.            $this->dbDriver->query($query);
  35.        }
  36.        
  37.        public function __destruct()
  38.        {
  39.            $this->_save($this->sessionId);
  40.        }
  41.        
  42.        
  43.        public function __get($aKey)
  44.        {
  45.            //handeling magic get method...
  46.            if (isset($this->data[$aKey])) {
  47.                return $this->data[$aKey];
  48.            }
  49.        }
  50.        
  51.        private function __set($aKey, $aValue)
  52.        {
  53.            //handeling magic set method...
  54.            $this->data[$aKey] = $aValue;
  55.        }
  56.        
  57.        private function _start()
  58.        {
  59.            if ($_COOKIE[$this->sessionName] == '') {
  60.                //create new session and  sessionId...
  61.                $this->sessionId = encrypt(time()*rand(0,999999)).random_string(6);
  62.                setcookie($this->sessionName, $this->sessionId);
  63.            } else {
  64.                //load existing session file to use by this session...
  65.                $data = $this->_load($_COOKIE[$this->sessionName]);
  66.                if ($data['browser'] == $_SERVER['HTTP_USER_AGENT']) {
  67.                    //use existing cookie as sessionId...
  68.                    $this->sessionId = $_COOKIE[$this->sessionName];
  69.                    $this->data = $data;
  70.                } else {
  71.                    //cookie could have been stolen; start new session...
  72.                    $this->sessionId = encrypt(time(0,999999)*rand()).random_string(6);
  73.                    setcookie($this->sessionName, $this->sessionId);
  74.                }
  75.            }
  76.            $this->log->addEntry(_SYSTEM_LOG_USER_SESSION_STARTED_IN_FOLDER_, $this->folder, NOTE);
  77.        }
  78.        
  79.        private function _cleanDatabase()
  80.        {
  81.            $this->dbDriver->query(
  82.                "DELETE FROM $this->dbTable WHERE `last_update` <= NOW() - INTERVAL 15 MINUTE"
  83.            );
  84.        }
  85.        
  86.        private function _load($aSessionId)
  87.        {
  88.            $this->dbDriver->query(
  89.                "SELECT * FROM $this->dbTable WHERE `id` = '$aSessionId'"
  90.            );
  91.            $row = $this->dbDriver->fetchRow();
  92.            return unserialize($row['data']);
  93.        }
  94.        
  95.        private function _save($aSessionId)
  96.        {
  97.            $this->dbDriver->query(
  98.                "INSERT INTO $this->dbTable SET
  99.                    `id` = '$aSessionId',
  100.                    `data` = '".serialize($this->data)."',
  101.                    `last_update` = NOW()
  102.                ON DUPLICATE KEY UPDATE
  103.                    `data` = '".serialize($this->data)."',
  104.                    `last_update` = NOW()"
  105.            );
  106.        }
  107.    }
  108. ?>
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #10





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

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


Co do zlicania aktywnych userow na plikach - zapomnialem ze skrypt USUWA nieaktywne pliki sesji. Wtedy sie da.
Go to the top of the page
+Quote Post
kbsucha
post
Post #11





Grupa: Zarejestrowani
Postów: 113
Pomógł: 19
Dołączył: 2.08.2007

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


Cytat(Black-Berry @ 15.09.2008, 15:06:59 ) *
Po waszych radach i testach doszedłem do wniosku że pliki nie są takei fajne. Poza tym baza jest o niebo szybsza. Moje zmagania niech będą zatem przestrogą dla innych.


Wedlug mnie najlepiej by było, jakbyś zrobił możliwość wyboru (file, db), np. gdzies w pliku konfiguracyjnym. Wtedy miałbyś największe pole manewru w przyszlosci.

Pozdr
Go to the top of the page
+Quote Post
Black-Berry
post
Post #12





Grupa: Zarejestrowani
Postów: 663
Pomógł: 6
Dołączył: 3.06.2007
Skąd: Kraków

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


Cytat(kbsucha @ 15.09.2008, 16:00:50 ) *
Wedlug mnie najlepiej by było, jakbyś zrobił możliwość wyboru (file, db), np. gdzies w pliku konfiguracyjnym. Wtedy miałbyś największe pole manewru w przyszlosci.

Pozdr

nie głupi pomysł. tak chyba zrobie.
Go to the top of the page
+Quote Post

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.08.2025 - 17:37