За последние 24 часа нас посетили 22748 программистов и 1228 роботов. Сейчас ищут 813 программистов ...

О сессиях на б.д.

Тема в разделе "PHP для новичков", создана пользователем sobachnik, 29 сен 2011.

  1. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Всем большой привет!
    Решил в очередном проекте реализовать сессии по-своему, на б.д. Не то, чтобы меня не устраивают стандартные сессии, но вот так захотелось, наверно из спортивного интереса. Сайт врядли когда-либо станет высоконагруженным проектом.
    Поскольку уже привык к простоте и удобству встроенных в php сессий (просто вносишь изменения в массив и оно всё само запоминается), захотел, чтобы мой алгоритм, хранящий данные в б.д., работал по аналогичному принцыпу. В конструкторе класса сессий должны получаться данные сессии и как-то передаваться в основную программу, ну а деструктор должен иметь доступ к обновлённому массиву переменных сессии, чтобы посмотреть, что там изменилось и при необходимости сохранить изменения в б.д. Сама работа с б.д. и проверка - что изменилось, что нет (что надо обновить, если надо) - тут всё просто. Основное, что меня интересует - как в деструкторе получить доступ к массиву сессии без вызова каких-то дополнительных методов (и передачи параметров) из основной программы. Я тут посидел, поэксперементировал и у меня получился такой тестовый код:
    PHP:
    1. <?php
    2. class test {
    3.     private $data;
    4.     public function __construct(&$Session = array()) {
    5.         $this->data = &$Session;
    6.         $this->data = array(
    7.             'a' => 'b',
    8.             'c' => 'd'
    9.         );
    10.     }
    11.     public function __destruct() {
    12.         echo('<pre>In destruct: ');
    13.         print_r($this->data);
    14.         echo('</pre>');
    15.     }
    16. }
    17. $test = new test($Session);
    18. unset($Session['a']);
    19. $Session['e'] = 'f';
    20. ?>
    Оно работает так, как мне и надо. Вывод скрипта:
    Код (Text):
    1. In destruct: Array
    2. (
    3.     [c] => d
    4.     [e] => f
    5. )
    А спросить хочу - это вообще, нормально? Т.е. это должно работать и в других версиях PHP (у меня 5.2.1 сейчас на локалхосте) или тут есть какой-то косяк?
     
  2. caballero

    caballero Активный пользователь

    С нами с:
    23 сен 2011
    Сообщения:
    18
    Симпатии:
    0
    session_set_save_handler позволяет перенаправлять сессии в базу или куда захочешь
     
  3. krow7

    krow7 Активный пользователь

    С нами с:
    12 авг 2009
    Сообщения:
    398
    Симпатии:
    0
    Адрес:
    из Азии
    caballero
    вы пост-то читали?)
     
  4. alexfer

    alexfer Активный пользователь

    С нами с:
    2 авг 2010
    Сообщения:
    239
    Симпатии:
    0
    sobachnik
    Пора бы уже на 5.3 перелезать ;)
    PHP:
    1.  
    2. <?php
    3. class TestSession {
    4.  
    5.     private $data = array(
    6.         'a' => 'b',
    7.         'c' => 'd'
    8.     );
    9.  
    10.     function __get($name) {
    11.         return $this->$name;
    12.     }
    13.  
    14.     function __set($name, $value) {
    15.         $this->$name = array_merge($this->data, $value);
    16.         return array_shift($this->$name);
    17.     }
    18. }
    19.  
    20. $session = new TestSession();
    21. $session->push = array('e' => 'f');
    22. print_r($session->push);
    Код (Text):
    1. Array ( [c] => d [e] => f )
     
  5. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    session.php

    PHP:
    1. <?php
    2.  
    3. define ( 'WRX_SESSION_NAME', 'WRXSID' );
    4. define ( 'WRX_SESSION_LIFETIME', 300 ); // активность юзера. если че - удаляем
    5.  
    6. class WRXToolsSession {
    7.  
    8.     const TABLE = 'wek_sessions';
    9.  
    10.     /**
    11.      * Сессия
    12.      * @var string
    13.      */
    14.     private $sSID = null;
    15.  
    16.     private $iCalls;
    17.  
    18.     private $iStart;
    19.  
    20.     private $iUpdate;
    21.  
    22.     private $aData;
    23.  
    24.     /**
    25.      * @return WRXToolsSession WRXToolsSession
    26.      */
    27.     static function getInstance() {
    28.  
    29.         static $oHandler = null;
    30.  
    31.         if (is_null ( $oHandler )) {
    32.             $oHandler = new WRXToolsSession ();
    33.         }
    34.  
    35.         return $oHandler;
    36.  
    37.     }
    38.  
    39.     public function __construct() {
    40.  
    41.     }
    42.  
    43.     /**
    44.      * @return WRXToolsDb WRXToolsDb
    45.      */
    46.     private function getDb() {
    47.         $oCore = WRXCore::getInstance ();
    48.         $oDB = $oCore->addTools ( 'WRXToolsDb' );
    49.         /* @var $oDB WRXToolsDb */
    50.         return $oDB;
    51.     }
    52.  
    53.     public function Init() {
    54.  
    55.         if (! isset ( $_COOKIE [WRX_SESSION_NAME] )) {
    56.             $this->setSid ( WRXToolsGUID::getGUID () );
    57.             $this->Create ();
    58.         } else {
    59.             $this->setSid ( $_COOKIE [WRX_SESSION_NAME] );
    60.             $this->Get ();
    61.         }
    62.  
    63.         setcookie ( WRX_SESSION_NAME, rawurlencode ( $this->getSid () ), 0, '/', $_SERVER ['HTTP_HOST'] );
    64.         //setcookie ( WRX_SESSION_NAME, rawurlencode ( $this->getSid () ) );
    65.  
    66.     }
    67.  
    68.     public function Create() {
    69.  
    70.         $oDB = $this->getDb();
    71.  
    72.         $iNow = time ();
    73.  
    74.         $this->iCalls = 1;
    75.         $this->iStart = $this->iUpdate = $iNow;
    76.         $this->aData = array ();
    77.  
    78.         $sSQL = "
    79.            INSERT INTO
    80.                `".self::TABLE."`
    81.            SET
    82.                `ses_name` = '" . $oDB->escape ( $this->getSid () ) . "',
    83.                `ses_calls` = " . $this->getCalls () . ",
    84.                `ses_start` = {$iNow},
    85.                `ses_update` = {$iNow},
    86.                `ses_data` = '" . $oDB->escape ( $this->getDataSerialize () ) . "'
    87.                ";
    88.         $oDB->query ( $sSQL );
    89.  
    90.         $this->CleanUp();
    91.  
    92.     }
    93.  
    94.     private function CleanUp() {
    95.  
    96.         $sSQL = "
    97.            DELETE FROM
    98.                `".self::TABLE."`
    99.            WHERE
    100.                `ses_update` < ".(time() - WRX_SESSION_LIFETIME)."
    101.        ";
    102.  
    103.         $this->getDb()->query ( $sSQL );
    104.  
    105.     }
    106.  
    107.     public function Get() {
    108.  
    109.         $oDB = $this->getDb();
    110.  
    111.         $sSQL = "
    112.            SELECT
    113.                *
    114.            FROM
    115.                `".self::TABLE."`
    116.            WHERE
    117.                `ses_name` = '" . $oDB->escape ( $this->getSid () ) . "'
    118.        ";
    119.         $oObject = $oDB->getObject ( $sSQL );
    120.  
    121.         if ($oObject === false) {
    122.             $this->setSid ( WRXToolsGUID::getGUID () );
    123.             $this->Create ();
    124.             $this->Get ();
    125.         } else {
    126.             $this->iCalls = $oObject->ses_calls;
    127.             $this->iStart = $oObject->ses_start;
    128.             $this->iUpdate = $oObject->ses_update;
    129.             $this->setDataSerialize ( $oObject->ses_data );
    130.         }
    131.     }
    132.  
    133.     public function Update() {
    134.  
    135.         $oDB = $this->getDb();
    136.  
    137.         $this->iCalls ++;
    138.         $this->iUpdate = time ();
    139.  
    140.         $sSQL = "
    141.            UPDATE
    142.                `".self::TABLE."`
    143.            SET
    144.                `ses_calls` = " . $this->iCalls . ",
    145.                `ses_update` = " . $this->iUpdate . ",
    146.                `ses_data` = '" . $oDB->escape ( $this->getDataSerialize () ) . "'
    147.            WHERE
    148.                `ses_name` = '" . $oDB->escape ( $this->getSid () ) . "'
    149.        ";
    150.         $oDB->query ( $sSQL );
    151.     }
    152.  
    153.     public function Delete() {
    154.  
    155.         $oDB = $this->getDb();
    156.  
    157.         $sSQL = "
    158.            DELETE FROM
    159.                `".self::TABLE."`
    160.            WHERE
    161.                `ses_name` = '" . $oDB->escape ( $this->getSid () ) . "'
    162.        ";
    163.         $oDB->query ( $sSQL );
    164.  
    165.     }
    166.  
    167.     public function getDataSerialize() {
    168.  
    169.         return serialize ( $this->aData );
    170.  
    171.     }
    172.  
    173.     public function setDataSerialize($sData) {
    174.  
    175.         if (empty ( $sData ))
    176.             $sData = serialize ( array () );
    177.  
    178.         return $this->aData = unserialize ( $sData );
    179.  
    180.     }
    181.  
    182.     public function setSid($sSid = null) {
    183.  
    184.         $this->sSID = $sSid;
    185.  
    186.     }
    187.  
    188.     /**
    189.      * Возвращает идентификатор сессии
    190.      */
    191.     public function getSid() {
    192.  
    193.         return $this->sSID;
    194.     }
    195.  
    196.     /**
    197.      * Записывает в в свойство класса пару ключ-значение
    198.      *
    199.      * @param string $sName
    200.      * @param mixed $mValue
    201.      */
    202.     public function setValue($sName, $mValue) {
    203.  
    204.         $this->aData [$sName] = $mValue;
    205.  
    206.         return $mValue;
    207.     }
    208.  
    209.     /**
    210.      * Возвращает значение по ключу
    211.      *
    212.      * @param string $sName
    213.      * @param mixed $mDefault
    214.      * @return mixed
    215.      */
    216.     public function getValue($sName, $mDefault = null) {
    217.  
    218.         return isset ( $this->aData [$sName] ) ? $this->aData [$sName] : $mDefault;
    219.     }
    220.  
    221.     /**
    222.      * Удаляет переменную из сессии
    223.      *
    224.      * @param $sName
    225.      * @return void
    226.      */
    227.     public function delValue($sName) {
    228.  
    229.         unset ( $this->aData [$sName] );
    230.     }
    231.  
    232.     public function getTimeStart() {
    233.  
    234.         return $this->iStart;
    235.     }
    236.  
    237.     public function getTimeUpdate() {
    238.  
    239.         return $this->iUpdate;
    240.     }
    241.  
    242.     public function getTimeEnd() {
    243.  
    244.         return $this->iUpdate + WRX_SESSION_LIFETIME;
    245.     }
    246.  
    247.     public function getCalls() {
    248.  
    249.         return $this->iCalls;
    250.     }
    251.  
    252.     /**
    253.      * Деструктор, вызывает finishWriteSession
    254.      *
    255.      */
    256.     public function __destruct() {
    257.  
    258.     }
    259.  
    260. }
    index.php

    PHP:
    1. <?php
    2.  
    3. require_once "../core/loader.php";
    4.  
    5. $oCore = WRXCore::getInstance ();
    6.  
    7. WRXToolsSession::getInstance ()->Init();
    8.  
    9. $oUser =  WRXUser::getInstance()->Track();
    10.  
    11. $oHTTPRequest = $oCore->addTools ( 'WRXHttpRequest' );
    12. /* @var  $oHTTPRequest WRXHttpRequest */
    13.  
    14. list ( $sClass, $sMethod ) = $oHTTPRequest->getEntity ();
    15.  
    16. try {
    17.     $oClass = new $sClass ();
    18. } catch ( WRXException $e ) {
    19.     throw new WRXException ( "Can't create entity [$sClass]", 0, __FILE__, __LINE__ );
    20. }
    21.  
    22. $sHTML = $oClass->$sMethod ();
    23.  
    24. WRXToolsSession::getInstance ()->Update ();
    25.  
    26. echo $sHTML;
    [sql]
    --
    -- Структура таблицы `wek_sessions`
    --

    CREATE TABLE IF NOT EXISTS `wek_sessions` (
    `ses_name` varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000',
    `ses_calls` int(10) unsigned NOT NULL default '0',
    `ses_start` int(11) NOT NULL,
    `ses_update` int(11) NOT NULL,
    `ses_data` text,
    PRIMARY KEY (`ses_name`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    [/sql]