2010-08-06 29 views
16

Các PHP kịch bản là như sau:PHP - ini_set ('session.gc_maxlifetime', 5) - Tại sao nó không kết thúc phiên?

<?php // continue.php 
ini_set('session.gc_maxlifetime', 5); 
session_start(); 
echo ini_get('session.gc_maxlifetime'); 
// wait for 7 seconds 
usleep(7000000); 
if (isset($_SESSION['username'])) 
{ 
    $username = $_SESSION['username']; 
    $password = $_SESSION['password']; 
    $forename = $_SESSION['forename']; 
    $surname = $_SESSION['surname']; 

    echo "Welcome back $forename.<br /> 
      Your full name is $forename $surname.<br /> 
      Your username is '$username' 
      and your password is '$password'."; 
} 
else echo "Please <a href=authenticate2.php>click here</a> to log in."; 

?> 

Dựa trên thời gian chờ (tức là từ 5 giây), kịch bản không nên in ra bất cứ điều gì. Tuy nhiên, tôi vẫn nhận được thông báo sau

5Welcome back Bill. Your full name is Bill Smith. Your username is 'bsmith' and your password is 'mysecret'. 

Dường như dòng ini_set ('session.gc_maxlifetime', 5) không hoạt động như nó phải được. Tôi đang sử dụng windowsXP + XAMMP.

Bạn có thể cho tôi biết cách làm cho nó hoạt động không?

Cảm ơn bạn

Trả lời

4

Đọc (tôi nhấn mạnh) manual:

session.gc_maxlifetime định số giây sau đó dữ liệu sẽ được xem như 'rác' và khả năng dọn dẹp. Thu gom rác có thể xảy ra trong khi bắt đầu phiên (tùy thuộc vào session.gc_probabilitysession.gc_divisor).

Trong cùng một trang:

session.gc_divisor cùng với session.gc_probability định nghĩa xác suất mà gc (garbage collection) quá trình được bắt đầu trên tất cả các khởi tạo phiên. Xác suất được tính bằng cách sử dụng gc_probability/gc_divisor, ví dụ: 1/100 có nghĩa là có 1% cơ hội là quy trình GC bắt đầu trên mỗi yêu cầu. session.gc_divisor mặc định là 100.

Bây giờ, hãy thực hiện phép toán và thấy rằng GC sẽ không được gọi trên mỗi yêu cầu.

Bạn nên lưu trữ trong phiên một biến giúp tiết kiệm thời gian của hoạt động cuối cùng của người dùng và sử dụng thay vì phiên là "hoạt động" hợp lý. Đừng dựa vào việc thu gom rác thải.

+0

Tôi nghĩ điểm ở đây là phiên vẫn hoạt động, và do đó có lẽ không phải chịu thu gom rác trong mọi trường hợp. Tôi không biết chắc chắn. –

+0

@Pekka Vấn đề là thu gom rác là vô dụng ở đây vì 1) nó sẽ chỉ được gọi với xác suất nhỏ và 2) nó chỉ được gọi là 'session_start'. – Artefacto

+0

đã đồng ý. Ngoài ra, bộ sưu tập rác thậm chí còn vô dụng hơn vì phiên mà chúng tôi đang ở vẫn hoạt động (và một số trình xử lý nội bộ có thể bị khóa). Chính xác? –

1

Tôi không nghĩ đây là cách gc_maxlifetime được cho là hoạt động. Hướng dẫn nói

session.gc_maxlifetime định số giây sau đó dữ liệu sẽ được xem như 'rác' và khả năng dọn dẹp.

(tôi nhấn mạnh)

trong trường hợp của bạn, phiên vẫn hoạt động. Vì vậy, tôi không nghĩ rằng nó sẽ bị thu gom rác.

Bạn có thể thử thực hiện session_write_close() trước khi sleep(). Điều đó có thể làm tăng khả năng thu gom rác thải.

+0

Ông ta có cùng một ý tưởng về sự nhấn mạnh: p – Artefacto

+0

@Artefacto vâng, thật vui! :) –

+0

Xin chào tất cả, Tôi đã thêm các dòng sau, nhưng nó vẫn không hoạt động. ini_set ('session.gc_maxlifetime', 5); ini_set ('gc_probability', 100); ini_set ('gc_divisor', 100); điều tôi muốn làm là thực thi phiên tự động hết hạn sau 5 giây. Nếu phương pháp này không hiệu quả, làm thế nào để nó hoạt động? cảm ơn bạn – q0987

9

phiên.gc_maxlifetime là số giây mà sau đó phiên sẽ là được xem là để thu thập rác.

phiên.gc_probability và session.gc_divisor sau đó xác định xác suất thu gom rác sẽ được thực thi trên bất kỳ phiên khởi tạo nào

34

Ngay cả khi bộ thu gom rác đã khởi động và xóa tệp phiên bạn đã mở/đọc với session_start(), nó sẽ KHÔNG đi vào ruột của quy trình PHP cụ thể đó và xóa mảng đối tượng $_SESSION.

Giả sử bạn đang sử dụng trình xử lý phiên dựa trên tệp chuẩn (có chứa bản sao serialize() 'd của $_SESSION), đây là những gì sẽ xảy ra.

  1. Các tập tin phiên ngồi trong thư mục tạm của nó
  2. Bạn session_start(), gây PHP để mở/khóa các tập tin, đọc nội dung của nó, deserialize các dữ liệu, và tình cờ, có thể cập nhật các tập tin phiên của "cuối cùng đã qua sử dụng" dấu thời gian (atime trên hộp Unix).
  3. Nếu các ngôi sao và mặt trăng được căn chỉnh chính xác với Neptune tăng dần trong ngôi nhà thứ năm, bộ thu gom phiên làm việc MAY kích hoạt và xóa các tệp phiên cũ.
  4. Bộ thu gom rác sẽ vui vẻ lặp lại qua thư mục phiên và xóa bất kỳ tệp nào cũ hơn max_liftime, NHƯNG S DEL KHÔNG XÓA BẤT K FIL MỌI LỌC HIỆN TẠI/SỬ DỤNG. Vì bạn chưa đóng() phiên của bạn, tệp của phiên của bạn vẫn đang được sử dụng nên sẽ không bị xóa.

Bây giờ, nếu bạn đã làm một cái gì đó như thế này:

ini_set(...); // set GC probability to max, short session lifetime, etc... 

session_start(); // populate $_SESSION 
session_write_close(); // dump $_SESSION out to file, close file, release lock. 

sleep(7); // Sleep for 7 seconds; 

session_start(); // re-populate $_SESSION; 

Bây giờ bạn có thể chỉ kết thúc với một tươi trống $ _SESSION, NẾU thu rác quyết định kick in Tuy nhiên, trừ khi bạn. làm điều đó thứ hai session_start(), dữ liệu $ _SESSION cũ từ lần bắt đầu trước đó() gọi S ST S ST ĐƯỢC HIỆN TẠI. Tệp phiên có thể đã được chuyển vào thùng rác, nhưng trình thu thập rác sẽ không chạm vào những gì có trong bộ nhớ của tập lệnh khi nó chạy.

+2

Bạn có chắc chắn bộ thu gom rác không chạy * before * 'session_start()' điền vào mảng '$ _SESSION'? Bạn có URL xác nhận điều này không? –

+3

+1 cho # 3 và cho 'session_write_close()' ý tưởng hay! –

Các vấn đề liên quan