PDA

View Full Version : آموزش: ذخیره سازی سشن ها در دیتابیس به روش PDO



Mori Bone
سه شنبه 04 شهریور 1393, 10:02 صبح
سلام خدمت همه ی دوستان گرامی.
براتون یه کلاس گذاشتم که که شاید براتون مفید باشه. البته این کلاس در این تاپیک (http://barnamenevis.org/showthread.php?286634) به وسیله آقای شهرکی معرفی شده بود که گفتم تبدیلش کنم به pdo.

هماهنگ شده با مهندس شهرکی

122697

saeed-71
سه شنبه 04 شهریور 1393, 10:39 صبح
دیتابیسم لطفا ضمیمه کنید

Mori Bone
سه شنبه 04 شهریور 1393, 10:46 صبح
دیتابیسم لطفا ضمیمه کنید

فایل ضمیمه کامل شد.

Mori Bone
سه شنبه 04 شهریور 1393, 10:47 صبح
سلام مجدد. گفتم کد هارو هم بگذارم.
<?PHP// Copyright محمد مصطفي شهركي @ http://www.ncis.ir AND Changed by مرتضی زندیه


ini_set('session.save_handler','user');


class MySessionHandler
{


//------------------------------------------- Fields --------------------------------------------------
//-------------------------------------------------------------------------------------------------------
private $_connection ; //PDO connection that is between I and database
//--- - --- - --- - --- - --- - --- - --- - --- - --- - --- - ---
private $_time_out ; //Time out for session
//--- - --- - --- - --- - --- - --- - --- - --- - --- - --- - ---
private $_salt ; //Salt, an uniq string
//--- - --- - --- - --- - --- - --- - --- - --- - --- - --- - ---
private $_browser_hash ; //Browser hash
//--- - --- - --- - --- - --- - --- - --- - --- - --- - --- - ---
private $_server ; //Server name
//--- - --- - --- - --- - --- - --- - --- - --- - --- - --- - ---
private $_user ; //User name
//--- - --- - --- - --- - --- - --- - --- - --- - --- - --- - ---
private $_pass ; //Pass word
//--- - --- - --- - --- - --- - --- - --- - --- - --- - --- - ---
private $_db ; //Database name
//-------------------------------------------------------------------------------------------------------




//___________________________________________ Open __________________________________________________ __
//-------------------------------------------------------------------------------------------------------
public function Open($save_path, $session_name)
{
//Initialize your need here.
//In my case, I need nothing.
return true;
}
//___________________________________________ Close __________________________________________________ __
//-------------------------------------------------------------------------------------------------------
public function Close()
{
//Just deinitialize your resources
return true;
}
//___________________________________________ Write __________________________________________________ _
//-------------------------------------------------------------------------------------------------------
public function Write( $id, $data )
{
$hash = $this->_browser_hash;
$now = date("Y-m-d H:i:s");
$sql = $this->_connection->prepare("INSERT INTO `sessions` (`id`,`data`,`modified`,`hash`) VALUES (:id, :data, :now, :hash)
ON DUPLICATE KEY UPDATE `data`=:data, `modified`=:now, `hash`=:hash");
try {
$sql->execute(array(':id'=>$id, ':data'=>$data, ':now'=>$now, ':hash'=>$hash));
}
catch(Exception $e) {
return false;
}
return true;
}
//___________________________________________ Read __________________________________________________ __
//-------------------------------------------------------------------------------------------------------
public function Read( $id )
{
$sql = $this->_connection->prepare('SELECT * FROM `sessions` WHERE `id`=:id');
try {
$sql->execute(array(':id'=>$id));
}
catch(Exception $e) {
return '';
}


if ($sql->rowCount() != 1) { return ''; }

$data = $sql->fetch(PDO::FETCH_ASSOC);
$time = strtotime($data['modified']);
$hash = $data['hash'];


if(time()-$time > $this->_time_out || strcasecmp($this->_browser_hash, $hash) != 0) {
return '';
}


return $data['data'];
}
//___________________________________________ Distroy _________________________________________________
//-------------------------------------------------------------------------------------------------------
public function Destroy( $id )
{
$sql = $this->_connection->prepare('DELETE FROM `sessions` WHERE `id`=:id');
try {
$sql->execute(array(':id'=>$id));
}
catch(Exception $e) {
return false;
}
$this->GC($this->_time_out);
return true;
}
//___________________________________________ GC __________________________________________________ ____
//-------------------------------------------------------------------------------------------------------
public function GC( $maxlifetime )
{
//You can use your timeout instead of this.
$date = time() - $maxlifetime;
$date_str = date("Y-m-d H:i:s",$date);
$sql = $this->_connection->prepare("DELETE FROM `sessions` WHERE `modified`<:date");
try {
$sql->execute(array(':data'=>$data));
}
catch(Exception $e) {
return false;
}
return true;
}
//___________________________________________ Connect _________________________________________________
//-------------------------------------------------------------------------------------------------------
private function connect()
{
try {
$this->_connection = new PDO('mysql:host='.$this->_server.';dbname='.$this->_db, $this->_user, $this->_pass);
$this->_connection->exec('SET NAMES \'utf8\'');
}
catch(Exception $e) {
die('Connection Error');
}
}
//___________________________________________ Constroctor _____________________________________________
//-------------------------------------------------------------------------------------------------------
public function __construct($server, $user, $pass, $db, $time_out = 600, $salt='')
{
date_default_timezone_set('Asia/Tehran');
if( $salt == '' ) {
$salt = md5('ThisClassUseToSeveSessionInDatabase');
}
$this->_server = $server;
$this->_user = $user;
$this->_pass = $pass;
$this->_db = $db;
$this->_time_out = $time_out;
$this->_salt = $salt;
$this->calcHash();
$this->connect();
session_set_save_handler(array(&$this,'Open'), array(&$this,'Close'), array(&$this,'Read'), array(&$this,'Write'), array(&$this,'Destroy'), array(&$this,'GC'));
}
//___________________________________________ calcHash ________________________________________________
//-------------------------------------------------------------------------------------------------------
private function calcHash()
{
$ip = isset( $_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : "Unknown";
$ip .= isset( $_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : "Unknown";
$ip .= isset( $_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "Unknown";
$agent = isset( $_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "NoUserAgent";
$browser_data = $this->_salt . $ip . $agent;
$this->_browser_hash = md5($browser_data);
}
}

فراخوانی هم به صورت زیر:
require_once('sssh.class.php');
$session = new MySessionHandler('localhost','root','','session_db ');
session_start();
$_SESSION['test']='http://www.ncis.ir';
echo isset($_SESSION['test'])?$_SESSION['test']:'Test session is not defined';

saeed-71
سه شنبه 04 شهریور 1393, 10:58 صبح
-----------

saeed-71
سه شنبه 04 شهریور 1393, 11:11 صبح
این تابعبه چه درد میخوره؟
calcHash
اون هش به چه درد میخوره؟

Mori Bone
سه شنبه 04 شهریور 1393, 11:26 صبح
این تابعبه چه درد میخوره؟
calcHash
اون هش به چه درد میخوره؟

یه رشته یکتاست که از یوزر ایجنت و IP کاربر ساخته میشه که اگه کاربر IPش عوض شد یا سیستمشو عوض کرد. نتونه از اون سشن استفاده کنه و نتونه همزمان با دو مرورگر وارده سایت بشه

saeed-71
سه شنبه 04 شهریور 1393, 19:40 عصر
این تابعcalcHash رو باید صدا زد تا ایپی گرفته بشه و ذخیره یا خودکار صدا زده میشه؟

Mori Bone
سه شنبه 04 شهریور 1393, 20:09 عصر
این تابعcalcHash رو باید صدا زد تا ایپی گرفته بشه و ذخیره یا خودکار صدا زده میشه؟
نه private هستش. خوده کلاس فراخونیش میکنه

saeed-71
سه شنبه 04 شهریور 1393, 20:49 عصر
سشنای تاریخ گذشته حذف نمیشن.

Mori Bone
سه شنبه 04 شهریور 1393, 20:54 عصر
سشنای تاریخ گذشته حذف نمیشن.
سوال شما توی تاپیک اصلی (http://barnamenevis.org/showthread.php?286634-%D8%B0%D8%AE%D9%8A%D8%B1%D9%87-Session-%D8%AF%D8%B1-DB-%D8%A8%D9%87-%D8%AC%D8%A7%D9%8A-%D9%81%D8%A7%D9%8A%D9%84&highlight=%D8%B0%D8%AE%DB%8C%D8%B1%D9%87+session) توضیح داده شده

saeed-71
سه شنبه 04 شهریور 1393, 21:16 عصر
سوال شما توی تاپیک اصلی (http://barnamenevis.org/showthread.php?286634-%D8%B0%D8%AE%D9%8A%D8%B1%D9%87-Session-%D8%AF%D8%B1-DB-%D8%A8%D9%87-%D8%AC%D8%A7%D9%8A-%D9%81%D8%A7%D9%8A%D9%84&highlight=%D8%B0%D8%AE%DB%8C%D8%B1%D9%87+session) توضیح داده شده

ندیدم کدوم پستش؟

Mori Bone
سه شنبه 04 شهریور 1393, 21:20 عصر
با سلام، مشكل خاصي پيش نمياد. من خودم هم به اين مسئله دقت كردم و ديدم وقتي از فايلها استفاده ميشه هم موقع خروج، اون فايل به طور خودكار حذف نميشه. احتمالاً اين مسئله بخاطر طراحي مرورگر هست. البته دارم روي كدي كار ميكنم كه اون رو از طريق Cron Jobs تنظيم كنيم و هرموقع اجرا بشه، Sessionهاي Expireشده رو حذف كنه. موفق باشيد.
از جناب شهرکی

saeed-71
پنج شنبه 06 شهریور 1393, 09:43 صبح
یه رشته یکتاست که از یوزر ایجنت و IP کاربر ساخته میشه که اگه کاربر IPش عوض شد یا سیستمشو عوض کرد. نتونه از اون سشن استفاده کنه و نتونه همزمان با دو مرورگر وارده سایت بشه

HTTP_CLIENT_IP و HTTP_X_FORWARDED_FOR ذخیره نمیشن.
بدون هش ذخیرشون کردم دیدم این دو تا Unknown ذخیره میشن.

shahriyar3
پنج شنبه 06 شهریور 1393, 15:53 عصر
بجای این خط میتونی از REPLACE INTO استفاده کنی .


INSERT INTO `sessions` (`id`,`data`,`modified`,`hash`) VALUES (:id, :data, :now, :hash) ON DUPLICATE KEY UPDATE `data`=:data, `modified`=:now, `hash`=:hash




جایگزین



REPLACE INTO `sessions` (`id`,`data`,`modified`,`hash`) VALUES (:id, :data, :now, :hash)

بجای اجرای 2 تا کوئری یک کوئری اجرا میشه. سرعت اجرا برنامه بیشتر میشه

Mori Bone
پنج شنبه 06 شهریور 1393, 16:01 عصر
بجای این خط میتونی از REPLACE INTO استفاده کنی .


INSERT INTO `sessions` (`id`,`data`,`modified`,`hash`) VALUES (:id, :data, :now, :hash) ON DUPLICATE KEY UPDATE `data`=:data, `modified`=:now, `hash`=:hash




جایگزین



REPLACE INTO `sessions` (`id`,`data`,`modified`,`hash`) VALUES (:id, :data, :now, :hash)

بجای اجرای 2 تا کوئری یک کوئری اجرا میشه. سرعت اجرا برنامه بیشتر میشه
با تشکر از توجه شما. من توی پست اول هم گفتم که من فقط این کلاس رو تبدیل کردم به pdo و اصلا به کدهایی به غیر از کدهای دیتابیس دست نزدم. در اولین فرصت تغییراتی که شما گفتین اعمال می شوند

behnamy01
چهارشنبه 30 مهر 1393, 11:42 صبح
برای حذف سشن یا همون کد بخش logout باید چه کار کنیم؟ تابع destroy کلاس رو صدا بزنیم یا مثل حالت معمولی unset کنیم فقط؟

Mori Bone
چهارشنبه 30 مهر 1393, 12:51 عصر
مثلا همون session می مونه. فقط کافیه از session_destroy استفاده کنید. روش دسترسی و ... هم مثله همون session معمولی می مونه

php_zone
چهارشنبه 12 آذر 1393, 11:13 صبح
کد ساخت session اشتباه است , موفق باشید

hassan20000
شنبه 01 فروردین 1394, 17:43 عصر
عید مبارک
سلام من کدهای زیرا نوشتم خطا می دهد لطفا
راهنمایی فرمایید
<?php


class session extends DB {


public $connection;
private $_time_out;
private $_salt;
private $_browser_hash;


public function __construct($time_out = 1200, $salt = '') {
parent::__construct();
date_default_timezone_set('Asia/Tehran');
if ($salt == '') {
$salt = md5('xcv#kj@KFG');
}


$this->_time_out = $time_out;
$this->_salt = $salt;
$this->calcHash();


session_set_save_handler(
array(&$this, 'Open'), array(&$this, 'Close'), array(&$this, 'Read'), array(&$this, 'Write'), array(&$this, 'Destroy'), array(&$this, 'GC')
);
ini_set('session.save_handler', 'user');
session_start();
}


//___________________________________________ Open __________________________________________________ __
//-------------------------------------------------------------------------------------------------------
public function Open($save_path, $session_name) {
return TRUE;
}


/**
* Deletes expired session
*/
private function _deleteExpired($maxlifetime) {
// $exxpire = time();
$date = time() - $maxlifetime;
$sql = $this->connection->prepare("DELETE FROM `tbl_session` WHERE (`modified` < $date)");
$sql->execute();
}


//___________________________________________ Close __________________________________________________ __
//-------------------------------------------------------------------------------------------------------
public function Close() {
$this->_deleteExpired($this->_time_out);
if (session_id() !== '') {
session_write_close();
}
return TRUE;
}


//___________________________________________ Write __________________________________________________ _
//-------------------------------------------------------------------------------------------------------
public function Write($id, $data) {
$hash = $this->_browser_hash;
$now = time();
// $sql = $this->connection->prepare("INSERT INTO `tbl_session` (`id`,`data`,`modified`,`hash`) VALUES (:id, :data, :now, :hash)
// ON DUPLICATE KEY UPDATE `data`=:data, `modified`=:now, `hash`=:hash");
$sql = $this->connection->prepare("REPLACE INTO `tbl_session` (`id`,`data`,`modified`,`hash`) VALUES (:id, :data, :now, :hash) ");


try {
$sql->execute(array(":id" => $id, ":data" => $data, ":now" => $now, ":hash" => $hash));
} catch (Exception $ex) {
return FALSE;
}
return TRUE;
}


//___________________________________________ Read __________________________________________________ __
//-------------------------------------------------------------------------------------------------------
public function Read($id) {
$sql = $this->connection->prepare("SELECT * FROM `tbl_session` WHERE (`id`=:id)");
try {
$sql->execute(array(":id" => $id));
} catch (Exception $ex) {
return '';
}


if ($sql->rowCount() != 1) {
return '';
}


$data = $sql->fetch(PDO::FETCH_ASSOC);
$time = $data['modified'];
$hash = $data['hash'];


if (time() - $this->_time_out || strcasecmp($this->_browser_hash, $hash) != 0) {
return '';
}


return $data['data'];
}


//___________________________________________ Distroy _________________________________________________
//-------------------------------------------------------------------------------------------------------
public function Destroy($id) {
$sql = $this->connection->prepare("DELETE FROM `tbl_session` WHERE (`id`=:id)");
try {
$sql->execute(array(":id" => $id));
} catch (Exception $ex) {
return FALSE;
}
$this->GC($this->_time_out);
return TRUE;
}


//___________________________________________ GC __________________________________________________ ____
//-------------------------------------------------------------------------------------------------------
public function GC($maxlifetime) {
$date = time() - $maxlifetime;
$sql = $this->connection->prepare("DELETE FROM `tbl_session` WHERE `modified`<:date");
try {
$sql->execute(array(':date' => $date));
} catch (Exception $ex) {
return FALSE;
}
return TRUE;
}


private function calcHash() {
$ip = isset($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : "Unknown";
$ip .= isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : "Unknown";
$ip .= isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'Unknown';
$agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "Unknown";
$browser_data = $this->_salt . $ip . $agent;
$this->_browser_hash = md5($browser_data);
}


}
؟>129618