Tôi cần phải giữ một phiên sống trong 30 phút và sau đó phá hủy nó.
Tôi cần phải giữ một phiên sống trong 30 phút và sau đó phá hủy nó.
Câu trả lời:
Bạn nên thực hiện một thời gian chờ phiên của riêng bạn. Cả hai tùy chọn được đề cập bởi những người khác ( session.gc_maxlifetime và session.cookie_lifetime ) đều không đáng tin cậy. Tôi sẽ giải thích lý do cho điều đó.
Đầu tiên:
session.gc_maxlifetime
session.gc_maxlifetime chỉ định số giây sau đó dữ liệu sẽ được xem là 'rác' và được dọn sạch. Thu gom rác xảy ra trong phiên bắt đầu.
Nhưng trình thu gom rác chỉ được bắt đầu với xác suất session.gc_probability chia cho session.gc_divisor . Và sử dụng các giá trị mặc định cho các tùy chọn đó (tương ứng 1 và 100), cơ hội chỉ ở mức 1%.
Chà, bạn có thể chỉ cần điều chỉnh các giá trị này để bộ thu gom rác được khởi động thường xuyên hơn. Nhưng khi bộ thu gom rác được khởi động, nó sẽ kiểm tra tính hợp lệ cho mỗi phiên đăng ký. Và đó là chi phí cao.
Hơn nữa, khi sử dụng các tệp session.save_handler mặc định của PHP , dữ liệu phiên được lưu trữ trong các tệp theo một đường dẫn được chỉ định trong session.save_path . Với trình xử lý phiên đó, tuổi của dữ liệu phiên được tính vào ngày sửa đổi cuối cùng của tệp và không phải là ngày truy cập cuối cùng:
Lưu ý: Nếu bạn đang sử dụng trình xử lý phiên dựa trên tệp mặc định, hệ thống tệp của bạn phải theo dõi thời gian truy cập (atime). Windows FAT không vì vậy bạn sẽ phải đưa ra một cách khác để xử lý rác thu thập phiên của bạn nếu bạn bị mắc kẹt với hệ thống tệp FAT hoặc bất kỳ hệ thống tệp nào khác không có tính năng theo dõi thời gian. Kể từ PHP 4.2.3, nó đã sử dụng mtime (ngày sửa đổi) thay vì atime. Vì vậy, bạn sẽ không gặp vấn đề với các hệ thống tập tin mà theo dõi atime không khả dụng.
Vì vậy, có thể xảy ra thêm rằng một tệp dữ liệu phiên bị xóa trong khi phiên vẫn được coi là hợp lệ vì dữ liệu phiên không được cập nhật gần đây.
Và thứ hai:
session.cookie_lifetime
session.cookie_lifetime chỉ định thời gian tồn tại của cookie trong vài giây được gửi tới trình duyệt. [Càng]
Vâng đúng vậy. Điều này chỉ ảnh hưởng đến tuổi thọ của cookie và bản thân phiên vẫn có thể hợp lệ. Nhưng đó là nhiệm vụ của máy chủ để vô hiệu hóa một phiên, không phải máy khách. Vì vậy, điều này không giúp được gì cả. Trên thực tế, việc đặt session.cookie_lifetime0
sẽ biến cookie của phiên thành cookie phiên thực sự chỉ có hiệu lực cho đến khi trình duyệt bị đóng.
Kết luận / giải pháp tốt nhất:
Giải pháp tốt nhất là thực hiện thời gian chờ phiên của riêng bạn. Sử dụng dấu thời gian đơn giản biểu thị thời gian của hoạt động cuối cùng (nghĩa là yêu cầu) và cập nhật nó với mọi yêu cầu:
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
// last request was more than 30 minutes ago
session_unset(); // unset $_SESSION variable for the run-time
session_destroy(); // destroy session data in storage
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp
Cập nhật dữ liệu phiên với mọi yêu cầu cũng thay đổi ngày sửa đổi của tệp phiên để phiên không bị xóa bởi trình thu gom rác sớm.
Bạn cũng có thể sử dụng dấu thời gian bổ sung để tạo lại ID phiên theo định kỳ để tránh các cuộc tấn công vào các phiên như sửa lỗi phiên :
if (!isset($_SESSION['CREATED'])) {
$_SESSION['CREATED'] = time();
} else if (time() - $_SESSION['CREATED'] > 1800) {
// session started more than 30 minutes ago
session_regenerate_id(true); // change session ID for the current session and invalidate old session ID
$_SESSION['CREATED'] = time(); // update creation time
}
Ghi chú:
session.gc_maxlifetime
ít nhất phải bằng tuổi thọ của trình xử lý hết hạn tùy chỉnh này (1800 trong ví dụ này);setcookie
hết hạn time()+60*30
để duy trì cookie phiên hoạt động.$_SESSION['LAST_ACTIVITY']
tương tự như $_SESSION['CREATED']
nơi bạn lưu trữ thời gian của hoạt động cuối cùng của người dùng nhưng cập nhật giá trị đó với mỗi yêu cầu. Bây giờ nếu chênh lệch của thời gian đó với thời gian hiện tại lớn hơn 1800 giây, thì phiên không được sử dụng quá 30 phút.
session_unset
không giống như $_SESSION = array()
.
ini_set('session.gc-maxlifetime', 1800)
không? Nếu không, thông tin phiên của bạn có thể bị hủy trong khi phiên của bạn vẫn được coi là hợp lệ, ít nhất là nếu cài đặt ini là 24 phút tiêu chuẩn. Hay tôi đang thiếu một cái gì đó?
files
được sử dụng. Vì vậy, session.gc_maxlifetime ít nhất phải bằng thời gian sử dụng của trình xử lý hết hạn tùy chỉnh này.
Lưu ý: nếu bạn muốn thay đổi thời gian, chỉ cần thay đổi 30 với thời gian bạn muốn và không thay đổi * 60: điều này sẽ cho số phút.
Trong phút: (30 * 60)
Trong ngày: (n * 24 * 60 * 60) n = không có ngày
<?php
session_start();
?>
<html>
<form name="form1" method="post">
<table>
<tr>
<td>Username</td>
<td><input type="text" name="text"></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="pwd"></td>
</tr>
<tr>
<td><input type="submit" value="SignIn" name="submit"></td>
</tr>
</table>
</form>
</html>
<?php
if (isset($_POST['submit'])) {
$v1 = "FirstUser";
$v2 = "MyPassword";
$v3 = $_POST['text'];
$v4 = $_POST['pwd'];
if ($v1 == $v3 && $v2 == $v4) {
$_SESSION['luser'] = $v1;
$_SESSION['start'] = time(); // Taking now logged in time.
// Ending a session in 30 minutes from the starting time.
$_SESSION['expire'] = $_SESSION['start'] + (30 * 60);
header('Location: http://localhost/somefolder/homepage.php');
} else {
echo "Please enter the username or password again!";
}
}
?>
<?php
session_start();
if (!isset($_SESSION['luser'])) {
echo "Please Login again";
echo "<a href='http://localhost/somefolder/login.php'>Click Here to Login</a>";
}
else {
$now = time(); // Checking the time now when home page starts.
if ($now > $_SESSION['expire']) {
session_destroy();
echo "Your session has expired! <a href='http://localhost/somefolder/login.php'>Login here</a>";
}
else { //Starting this else one [else1]
?>
<!-- From here all HTML coding can be done -->
<html>
Welcome
<?php
echo $_SESSION['luser'];
echo "<a href='http://localhost/somefolder/logout.php'>Log out</a>";
?>
</html>
<?php
}
}
?>
<?php
session_start();
session_destroy();
header('Location: http://localhost/somefolder/login.php');
?>
Login.php
các tiêu đề được gửi SAU nội dung, đó là xấu.
Đây có phải là để đăng xuất người dùng sau một thời gian thiết lập? Đặt thời gian tạo phiên (hoặc thời gian hết hạn) khi được đăng ký, sau đó kiểm tra xem trên mỗi lần tải trang có thể xử lý việc đó không.
Ví dụ:
$_SESSION['example'] = array('foo' => 'bar', 'registered' => time());
// later
if ((time() - $_SESSION['example']['registered']) > (60 * 30)) {
unset($_SESSION['example']);
}
Chỉnh sửa: Tôi đã có một cảm giác bạn có ý nghĩa khác mặc dù.
Bạn có thể loại bỏ các phiên sau một tuổi thọ nhất định bằng cách sử dụng session.gc_maxlifetime
cài đặt ini:
Chỉnh sửa: ini_set ('session.gc_maxlifetime', 60 * 30);
gc_maxlifetime
hay gc-maxlifetime
. Nó có hỗ trợ cả dấu gạch dưới và dấu gạch ngang không?
Bài đăng này cho thấy một số cách kiểm soát thời gian chờ phiên: http://bytes.com/topic/php/insights/889606-setting-timeout-php-sairs
IMHO tùy chọn thứ hai là một giải pháp tốt đẹp:
<?php
/***
* Starts a session with a specific timeout and a specific GC probability.
* @param int $timeout The number of seconds until it should time out.
* @param int $probability The probablity, in int percentage, that the garbage
* collection routine will be triggered right now.
* @param strint $cookie_domain The domain path for the cookie.
*/
function session_start_timeout($timeout=5, $probability=100, $cookie_domain='/') {
// Set the max lifetime
ini_set("session.gc_maxlifetime", $timeout);
// Set the session cookie to timout
ini_set("session.cookie_lifetime", $timeout);
// Change the save path. Sessions stored in teh same path
// all share the same lifetime; the lowest lifetime will be
// used for all. Therefore, for this to work, the session
// must be stored in a directory where only sessions sharing
// it's lifetime are. Best to just dynamically create on.
$seperator = strstr(strtoupper(substr(PHP_OS, 0, 3)), "WIN") ? "\\" : "/";
$path = ini_get("session.save_path") . $seperator . "session_" . $timeout . "sec";
if(!file_exists($path)) {
if(!mkdir($path, 600)) {
trigger_error("Failed to create session save path directory '$path'. Check permissions.", E_USER_ERROR);
}
}
ini_set("session.save_path", $path);
// Set the chance to trigger the garbage collection.
ini_set("session.gc_probability", $probability);
ini_set("session.gc_divisor", 100); // Should always be 100
// Start the session!
session_start();
// Renew the time left until this session times out.
// If you skip this, the session will time out based
// on the time when it was created, rather than when
// it was last used.
if(isset($_COOKIE[session_name()])) {
setcookie(session_name(), $_COOKIE[session_name()], time() + $timeout, $cookie_domain);
}
}
Vâng, tôi hiểu câu trả lời của aboves là đúng nhưng chúng ở cấp độ ứng dụng, tại sao chúng ta không đơn giản sử dụng .htaccess
tệp để đặt thời gian hết hạn?
<IfModule mod_php5.c>
#Session timeout
php_value session.cookie_lifetime 1800
php_value session.gc_maxlifetime 1800
</IfModule>
if (isSet($_SESSION['started'])){
if((mktime() - $_SESSION['started'] - 60*30) > 0){
//Logout, destroy session, etc.
}
}
else {
$_SESSION['started'] = mktime();
}
Sử dụng session_set_cookie_params
funciton để thực hiện điều này.
Là cần thiết gọi chức năng này trước khi session_start()
gọi.
Thử cái này:
$lifetime = strtotime('+30 minutes', 0);
session_set_cookie_params($lifetime);
session_start();
Xem thêm trong: http://php.net/manual/feft.session-set-cookie-params.php
Nó thực sự dễ dàng với một chức năng như sau. Nó sử dụng tên bảng cơ sở dữ liệu 'phiên' với các trường 'id' và 'time'.
Mỗi khi người dùng truy cập lại trang web hoặc dịch vụ của bạn, bạn nên gọi hàm này để kiểm tra xem giá trị trả về của nó có ĐÚNG không. Nếu đó là FALSE, người dùng đã hết hạn và phiên sẽ bị hủy (Lưu ý: Hàm này sử dụng lớp cơ sở dữ liệu để kết nối và truy vấn cơ sở dữ liệu, tất nhiên bạn cũng có thể thực hiện bên trong chức năng của mình hoặc đại loại như thế):
function session_timeout_ok() {
global $db;
$timeout = SESSION_TIMEOUT; //const, e.g. 6 * 60 for 6 minutes
$ok = false;
$session_id = session_id();
$sql = "SELECT time FROM sessions WHERE session_id = '".$session_id."'";
$rows = $db->query($sql);
if ($rows === false) {
//Timestamp could not be read
$ok = FALSE;
}
else {
//Timestamp was read succesfully
if (count($rows) > 0) {
$zeile = $rows[0];
$time_past = $zeile['time'];
if ( $timeout + $time_past < time() ) {
//Time has expired
session_destroy();
$sql = "DELETE FROM sessions WHERE session_id = '" . $session_id . "'";
$affected = $db -> query($sql);
$ok = FALSE;
}
else {
//Time is okay
$ok = TRUE;
$sql = "UPDATE sessions SET time='" . time() . "' WHERE session_id = '" . $session_id . "'";
$erg = $db -> query($sql);
if ($erg == false) {
//DB error
}
}
}
else {
//Session is new, write it to database table sessions
$sql = "INSERT INTO sessions(session_id,time) VALUES ('".$session_id."','".time()."')";
$res = $db->query($sql);
if ($res === FALSE) {
//Database error
$ok = false;
}
$ok = true;
}
return $ok;
}
return $ok;
}
Lưu trữ dấu thời gian trong phiên
<?php
$user = $_POST['user_name'];
$pass = $_POST['user_pass'];
require ('db_connection.php');
// Hey, always escape input if necessary!
$result = mysql_query(sprintf("SELECT * FROM accounts WHERE user_Name='%s' AND user_Pass='%s'", mysql_real_escape_string($user), mysql_real_escape_string($pass));
if( mysql_num_rows( $result ) > 0)
{
$array = mysql_fetch_assoc($result);
session_start();
$_SESSION['user_id'] = $user;
$_SESSION['login_time'] = time();
header("Location:loggedin.php");
}
else
{
header("Location:login.php");
}
?>
Bây giờ, Kiểm tra xem dấu thời gian có trong cửa sổ thời gian cho phép không (1800 giây là 30 phút)
<?php
session_start();
if( !isset( $_SESSION['user_id'] ) || time() - $_SESSION['login_time'] > 1800)
{
header("Location:login.php");
}
else
{
// uncomment the next line to refresh the session, so it will expire after thirteen minutes of inactivity, and not thirteen minutes after login
//$_SESSION['login_time'] = time();
echo ( "this session is ". $_SESSION['user_id'] );
//show rest of the page and all other content
}
?>
Sử dụng lớp này trong 30 phút
class Session{
public static function init(){
ini_set('session.gc_maxlifetime', 1800) ;
session_start();
}
public static function set($key, $val){
$_SESSION[$key] =$val;
}
public static function get($key){
if(isset($_SESSION[$key])){
return $_SESSION[$key];
} else{
return false;
}
}
public static function checkSession(){
self::init();
if(self::get("adminlogin")==false){
self::destroy();
header("Location:login.php");
}
}
public static function checkLogin(){
self::init();
if(self::get("adminlogin")==true){
header("Location:index.php");
}
}
public static function destroy(){
session_destroy();
header("Location:login.php");
}
}
Sử dụng dấu thời gian ...
<?php
if (!isset($_SESSION)) {
$session = session_start();
}
if ($session && !isset($_SESSION['login_time'])) {
if ($session == 1) {
$_SESSION['login_time']=time();
echo "Login :".$_SESSION['login_time'];
echo "<br>";
$_SESSION['idle_time']=$_SESSION['login_time']+20;
echo "Session Idle :".$_SESSION['idle_time'];
echo "<br>";
} else{
$_SESSION['login_time']="";
}
} else {
if (time()>$_SESSION['idle_time']){
echo "Session Idle :".$_SESSION['idle_time'];
echo "<br>";
echo "Current :".time();
echo "<br>";
echo "Session Time Out";
session_destroy();
session_unset();
} else {
echo "Logged In<br>";
}
}
?>
Tôi đã sử dụng 20 giây để hết hạn sử dụng dấu thời gian .
Nếu bạn cần 30 phút, hãy thêm 1800 (30 phút sau vài giây) ...
Bạn có thể sử dụng DB trực tiếp để thay thế. Tôi sử dụng hàm DB để làm điều đó mà tôi gọi là chk_lgn.
Kiểm tra kiểm tra đăng nhập để xem liệu chúng có được đăng nhập hay không và khi thực hiện, nó đặt dấu thời gian ngày của kiểm tra là hoạt động cuối cùng trong hàng / cột db của người dùng.
Tôi cũng làm kiểm tra thời gian ở đó. Điều này làm việc cho tôi vào lúc này khi tôi sử dụng chức năng này cho mỗi trang.
PS Không ai tôi từng thấy đã đề xuất một giải pháp DB thuần túy.
Cách PHP xử lý các phiên khá khó hiểu cho người mới bắt đầu hiểu. Điều này có thể giúp họ bằng cách đưa ra một cái nhìn tổng quan về cách các phiên hoạt động: cách các phiên hoạt động (trình xử lý phiên tùy chỉnh)
Chỉ cần lưu trữ thời gian hiện tại và Nếu vượt quá 30 phút bằng cách so sánh thì hủy phiên hiện tại.