Web-мастер: курс молодого бойца

Сериализация и десериализация _session - направте на путь истинный

 Страницы: 1 | 2 | 3 ... >>
 

 Добавлено 2011-04-25 20:45:27



Сообщений: 19
Зарегистрирован: 31.03.2011

Цитировать
Доброго времени суток.. Направте на путь истиный!!

загвозга вся в том что мне необходимо занести данные из сессии в БД.. нашел образец кода который заносит сессию в БД он работает идентификатор заносит, но у меня перестает отображаться содержимое корзины.. и заносит зашифрованную сессию-к примеру:

ids|a:3:{i:0;i:0;i:1;i:0;i:2;i:0;}counts|a:3:{i:0;i:0;i:1;i:0;i:2;i:0;}sym|d:30;

По рылся в нете и в учебниках понял что она- сессия сериализованна и мне ее надо десериализовать. Понятного примера и расписанного по шагам не нашел.
Вобщем дальше у меня большая пропасть в знаниях и я немогу ее заполнить!! у меня миллион вопросов на которые я не могу получить ответ, знакомых нету обратиться больше не к кому!!!! Помогите мне разобраться..

мне сначало надо десериализовать сессию а потом заносить ее в БД?? или занести а потом как вытаскивать десериализовывать?? И вообще надо ее заносить в БД?? я нашел файлы где хранится сессия мож лучше ее там оставить потому как корзина перестает работать??

САМЫЙ ГЛАВНЫЙ ВОПРОС как мне занести данные в БД вместе с контактными данными клиента????

Образец кода:

 <?
  
class session_db
  
{
      function 
session_db()
      {
          
session_set_save_handler(
              array(&
$this'session_open'),
              array(
get_class($this), 'session_close'),
              array(&
$this'session_read'),
              array(&
$this'session_write'),
              array(&
$this'session_delete'),
              array(&
$this'session_gc')
              );
      }
  
      function 
session_open($path$name)
      {
          return 
true;
      }
  
      function 
session_close()
      {
          return 
true;
      }
  
      function 
session_read($sid)
      {
          if (!
mysql_query("UPDATE sessions SET atime=NOW() WHERE sid='$sid'"))
                  die(
mysql_error()); // Стоит проверить права на UPDATE
  
          
if (!mysql_affected_rows()) // строки нет - надо создать
          
{
              if (!
mysql_query(
                  
"INSERT INTO sessions (sid) VALUES ('$sid')"
                  
))
                  die(
mysql_error()); // Может, вставка запрещена?
  
              
return ""// Т.к. данных нет, то возвращаю пустую строку
          
}
  
          
$res mysql_query("SELECT data FROM sessions WHERE sid='$sid'");
          if (!
$res)
              die(
mysql_error()); // Проблема с БД? Настройками балуемся?
  
          
$row mysql_fetch_row($res);
          
mysql_free_result($res);
  
          return 
$row[0];
      }
  
      function 
session_write($sid$data)
      {
          
$data mysql_escape_string($data); // Настоятельно рекомендую
          
mysql_query("REPLACE INTO sessions (sid, atime, data) " .
              
"VALUES ('$sid', NOW(), '$data')");
      }
  
      function 
session_delete($sid)
      {
          return 
mysql_query("DELETE FROM sessions WHERE sid='$sid'");
      }
  
      function 
session_gc($lifetime)
      {
          
mysql_query("DELETE FROM sessions " .
              
"WHERE atime < DATE_ADD(NOW(), INTERVAL -$lifetime SECOND)");
          
// Для оптимизации atime не должно участвовать в вычислении выражения
      
}
  }
  
  
mysql_connect("host""user""pass") or die(myqsl_error());
  
  
mysql_select_db("my_db");
  
  
$storage = new session_db;
  
  
session_name("MY_SESSION_ID"); // Имя у сессии будет такое
  
?>
Понял главный косяк этого кода что:

во-первых, upate сессии, не проверяет ее таймаут. Обычно сессия живет несклько минут или часов, если не используется, у тут она может получится вечной.

Помогите...
Наверх  Посмотреть профиль   Сайт автора  

 Добавлено 2011-04-26 22:14:09
evgenijj
Модератор




Сообщений: 1371
Зарегистрирован: 09.11.2007

Цитировать
Геннадий пишет:
сессия сериализованна и мне ее надо десериализовать. Понятного примера и расписанного по шагам не нашел.
serialize()
unserialize()

По поводу сессий - прочитай статью:
Сессии. Подробное описание работы и объяснение механизма
Я позволю себе процитировать:
Цитата
Сессии используют стандартные, хорошо известные способы передачи данных. Собственно, других-то просто и нет. Идентификатор - это обычная переменная. По умолчанию ее имя - PHPSESSID. Задача PHP отправить ее браузеру, чтобы тот вернул ее со следующим запросом. И переменную можно передать только двумя способами: в куках или POST/GET запросом. PHP использует оба варианта. За это отвечают две настройки в php.ini:

* session.use_cookies - если равно 1, то PHP передает идентификатор в куках, если 0 - то нет.
* session.use_trans_sid - если равно 1, то PHP передает его, добавляя к URL и формам, если 0 - то нет.

Менять эти и другие параметры сессий можно так же, как и другие настройки PHP - в файле php.ini, а так же с помощью команды ini_set() или в файлах настройки веб-сервера

Если включена только первая, то при старте сессии (при каждом вызове session_start()) клиенту устанавливается кука. Браузер исправно при каждом следующем запросе эту куку возвращает и PHP имеет идентификатор сессии. Проблемы начинаются, если браузер куки не возвращает. В этом случае, не получая куки с идентификатором, PHP будет все время стартовать новую сессию, и механизм работать не будет.

Если включена только вторая, то кука не выставляется. А происходит то, ради чего, в основном, собственно, и стоит использовать встроенный механизм сессий. После того, как скрипт выполняет свою работу, и страница полностью сформирована, PHP просматривает ее всю и дописывает к каждой ссылке и к каждой форме передачу идентификатора сессии. Это выглядит примерно так:

<a href="/index.php">Index</a>

превращается в

<a href="/index.php?PHPSESSID=9ebca8bd62c830d3e79272b4f585ff8f">Index</a>

а к формам добавляется скрытое поле

<input type="hidden" name="PHPSESSID" value="00196c1c1a02e4c37ac04f921f4a5eec" />

И браузер при клике на любую ссылку, или при нажатии на кнопку в форме, пошлет в запросе нужную нам переменную - идентификатор сессии! По очевидным причинам идентификатор добавляется только к относительным ссылкам.

Теоретически, в наших с вами самодельных сессиях на куках и базе, можно самому, руками приписать ко всем ссылками передачу PHPSESSID - и тогда наши собственные сессии будут работать независимо от кук. Но, согласитесь - приятнее, когда эту работу делает кто-то другой? ;-)

По умолчанию в последних версиях PHP включены обе опции. Как PHP поступает в этом случае? Кука выставляется всегда. А ссылки автодополняются только если РНР не обнаружил куку с идентификатором сессии. Когда пользователь в првый раз за этот сеанс заходит на сайт, ему ставится кука, и дополняются ссылки. При следующем запросе, если куки поддерживаются, PHP видит куку и перестает дополнять ссылки. Если куки не работают, то PHP продолжает исправно добавлять PHPSESSID к ссылкам, и сессия не теряется. Пользователи, у которых работают куки, увидят длинную ссылку с PHPSESSID только один раз.

Если объяснять совсем просто: когда один и тот же пользователь запрашивает две страницы с сайта, сервер не знает, что их запрашивает один и тот же человек. Протокол HTTP - без сохранения состояния. Но это крайне неудобно. Если пользователь авторизовался, мы должны об этом помнить, а не запрашивать каждый раз авторизацию. Если пользователь добавил товар в корзину, то мы должны эту информацию как-то сохранить.

Делается это так: когда мы в скрипте пишем session_start(), веб-сервер отправляет браузеру клиента указание сохранить некоторую информацию на компьютере пользователя - в файл cookie записывается переменная PHPSESSID=9ebca8bd62c830d3e79272b4f585ff8f. Название идентификатора сессии - "PHPSESSID", но его можно изменить при помощи параметра session.name в файле php.ini. Когда пользователь запрашивает вторую, третью страницу с сайта, браузер отправляет в заголовке PHPSESSID=9ebca8bd62c830d3e79272b4f585ff8f. PHP на сервере находит файл с именем 9ebca8bd62c830d3e79272b4f585ff8f в директории session.save_path (задается в php.ini). В этом файле - сериализованный массив $_SESSION. Остается только десериализовать строку, преобразовав ее в массив $_SESSION.

Время жизни cookie, которая хранит идентификатор сессии по умолчанию составляет 0 сек, т.е. кука храниться до того момента, как браузер будет закрыт. Это можно изменить при помощи параметра session.cookie_lifetime в файле php.ini.

В файле php.ini существует параметр session.gc_maxlifetime который указывает время в секундах, по истечению которого все устаревшие файлы сессий будут удалены из директории session.save_path.

Допустим, мы хотим задать время жизни сесии - 3 часа. Для этого в файле php.ini устанавливаем следующие параметры:

session.gc_maxlifetime = 10800
session.cookie_lifetime = 10800


Если нет возможности внести изменения в файл php.ini, то можно сделать установку этих параметров при помощи файла .htaccess. Для этого вносим в него следующие строки:

php_value session.gc_maxlifetime 10800
php_value session.cookie_lifetime 10800


Если по каким-то причинам не устраивает стандартный механизм PHP-сессий, можно использовать функцию session_set_save_handler(), чтобы задать пользовательские функции хранения сессии. Например, при хранении данных сессии в БД.


Денежные купюры пронумерованы для того, чтобы когда-нибудь я мог сложить их все одну к одной, по порядку.
Наверх  Посмотреть профиль   Сайт автора Отредактировано автором 26.04.2011

 Добавлено 2011-04-27 07:50:07



Сообщений: 19
Зарегистрирован: 31.03.2011

Цитировать
Я не могу понять одной фещи.. Подкинте мысль.. Как мне понять ЧТО заказал клиент?? ведь вся информация(контактная) о клиенте в БД!!! пусть к примеру 2-ва клиента в день и как мне понять какая сессия будет чьей и как выковырять данные из session( не из БД а из стандартной директории)??

Скажите во 2м примере:
//<? Здесь мы используем unserialize() для загрузки данных сессии в
// массив $session_data из строки, выбранной из БД.
// Этот пример использует одну из строк, описанных с помощью serialize().

$conn odbc_connect ("webdb""php""chicken");
$stmt odbc_prepare ($conn"SELECT data FROM sessions WHERE id = ?");
$sqldata = array ($PHP_AUTH_USER);
if (!
odbc_execute ($stmt, &$sqldata) || !odbc_fetch_into ($stmt, &$tmp)) {
// если выполнение или извлечение не прошло, инициализируется пустой массив
$session_data = array();
} else {
// мы не должны иметь сериализованных данных в $tmp[0].
$session_data unserialize ($tmp[0]);
if (!
is_array ($session_data)) {
// если что-то прошло не так, инициализировать пустой массив
$session_data = array();
}
}
?>
Это работа как занести значение из сессии в БД(unserialize) или прочитать сериализованное значение из БД предварительно его unserialize???
Наверх  Посмотреть профиль   Сайт автора Отредактировано автором 27.04.2011

 Добавлено 2011-04-27 11:05:37
evgenijj
Модератор




Сообщений: 1371
Зарегистрирован: 09.11.2007

Цитировать
Когда пользователь авторизовался на сайте, т.е. заполнил и отправил форму
<form action="auth.php" method="post">
E-mail: <input type="text" name="email" value="" /><br/>
Пароль: <input type="password" name="password" value="" /><br/>
<input type="submit" name="submit" value="Войти" />
</form>
мы на сервере проверяем, есть ли у нас такой пользователь:
<?php
$query 
"SELECT id, name, email, phone, address FROM users WHERE email='".mysql_escape_string($_POST['email'])."' AND password='".mysql_escape_string($_POST['password'])."'";
$res mysql_query$query );
if ( 
mysql_num_rows$res ) == ) {
  
$_SESSION['user'] = mysql_fetch_assoc$res );
  echo 
'Авторизация прошла успешно';
} else {
  echo 
'Неверный e-mail или пароль';
}
?>
Проверить, имеем мы дело с авторизованным пользователем теперь просто:
<?php
if ( isset( $_SESSION['user'] ) ) {
  echo 
'Авторизованный пользователь<br/>';
  echo 
'Имя: '.$_SESSION['user']['name'].'<br/>';
  echo 
'E-mail: '.$_SESSION['user']['email'].'<br/>';
  echo 
'Телефон: '.$_SESSION['user']['phone'].'<br/>';
} else {
  echo 
'Неавторизованный пользователь<br/>';
}
?>

Когда пользователь добавляет товар в корзину - мы отправляем данные формы
<h1>Золотое кольцо с топазом</h1>
<img src="/products/123.jpg" alt="Золотое кольцо с топазом" />
<form action="addtobasket.php" method="post">
<input type="hidden" name="code" value="123" />
Кол-во: <input type="text" name="count" value="1" />
<input type="submit" name="submit" value="В корзину" />
</form>

В обработчике формы мы добавляем товар в корзину
<?php
$_SESSION
['basket'][$_POST['code']] = $_POST['count'];
?>

Если определен массив $_SESSION['basket'] и количество элементов в нем больше нуля - значит в корзине есть товар.

$_SESSION['basket']['123'] = 2;
$_SESSION['basket']['456'] = 1;
$_SESSION['basket']['789'] = 3
;

В корзине сейчас 6 единиц товара трех артикулов:

товар с уникальным ID=123 в кол-ве 2 шт.
товар с уникальным ID=456 в кол-ве 1 шт.
товар с уникальным ID=789 в кол-ве 3 шт.


Денежные купюры пронумерованы для того, чтобы когда-нибудь я мог сложить их все одну к одной, по порядку.
Наверх  Посмотреть профиль   Сайт автора Отредактировано автором 27.04.2011

 Добавлено 2011-04-27 21:34:02



Сообщений: 19
Зарегистрирован: 31.03.2011

Цитировать
Евгений спасибо большое, но я не планировал делать авторизацию пользователей. хотел чтоб пользователь максимально просто зашел купил и не тратил время.. блин... если не найду решение то придется делать регистрацию!! Я так понимаю других решений нету кроме регистрации???

к примеру:
есть в БД заказы на имя:

Вася
Миша
Женя
Гена
Петя
Иорь
Саша

И допустим есть 7 сессий каждая со своим id
Вопрос как мне понять кому какая сессия принадлежит??
Наверх  Посмотреть профиль   Сайт автора  
 Страницы: 1 | 2 | 3 ... >>
 
Быстрый ответ
 
Цвет шрифта: Закрыть все теги
Сообщение
Защитный код