Theo cách này, câu hỏi này có thể được xem như là phần mở rộng của this one.An toàn của các phương pháp này để mã hóa và giải mã các phiên PHP
Chúng tôi đang xem xét phát hành một lớp xử lý việc deserializing và tuần tự hóa dữ liệu phiên được lưu trữ trong một bảng trên một trang web sản xuất quy mô lớn để chúng tôi có thể chỉnh sửa dữ liệu phiên tùy ý.
Vấn đề là, session_decode()
populates hiện $_SESSION
mà không trả lại một mảng được giải mã, và session_encode()
không mã hóa một mảng nhất định (nó chỉ trả về một chuỗi tuần tự của phiên hiện tại.)
Các PHP mặc định phiên serialize handler không chỉ đơn giản sử dụng serialize()
để mã hóa các phiên và do đó cách duy nhất để có cùng chức năng mã hóa và giải mã phiên là bằng cách di chuyển biến toàn cầu $_SESSION
xung quanh (tức là lưu trữ vào phiên, truy xuất dữ liệu và khôi phục) hoặc bằng cách thử để tái tạo một triển khai thực hiện những gì mà session.serialize_handler
thực hiện.
Chúng tôi đã chọn phương pháp tiếp cận sinh sản thứ hai vì dường như có vẻ ít thuyết phục hơn. Đã có một số nỗ lực trong bản sao chép này trong phần nhận xét của session_encode và session_decode trong tài liệu. Tôi đã chọn ra hai điều mà tôi nghĩ dường như đáng tin cậy nhất và áp dụng chúng. Các phương pháp giải mã có vẻ khá mạnh mẽ nhưng phương pháp mã hóa mặc dù nó hoạt động, đã được đăng hơn 5 năm trước
Chúng tôi vẫn miễn cưỡng đơn giản vì có thể có trường hợp cạnh vô hình sẽ khiến các phương pháp này bị hỏng.
Cuối cùng, tôi đang tìm:
- ví dụ mà sẽ phá vỡ phương thức dưới đây, hoặc
- bảo đảm rằng các phương pháp đã được sử dụng trong sản xuất và sẽ không phá vỡ
- có lẽ lựa chọn thay thế đã được thử và thử nghiệm trong sản xuất?
Cảm ơn mọi người đã nâng cao!
Mã:
class Session extends BaseSession
{
/**
* Taken from http://www.php.net/manual/en/function.session-decode.php#108037
*/
public function unserialized() {
$session_data = $this->content;
$method = ini_get("session.serialize_handler");
switch ($method) {
case "php":
return self::unserialize_php($session_data);
break;
case "php_binary":
return self::unserialize_phpbinary($session_data);
break;
default:
throw new Exception("Unsupported session.serialize_handler: " . $method . ". Supported: php, php_binary");
}
}
/**
* Taken from http://www.php.net/manual/en/function.session-encode.php#76425
*/
public function serialize($array, $safe = true) {
// the session is passed as refernece, even if you dont want it to
if($safe) $array = unserialize(serialize($array)) ;
$raw = '' ;
$line = 0 ;
$keys = array_keys($array) ;
foreach($keys as $key) {
$value = $array[ $key ] ;
$line ++ ;
$raw .= $key .'|' ;
if(is_array($value) && isset($value['huge_recursion_blocker_we_hope'])) {
$raw .= 'R:'. $value['huge_recursion_blocker_we_hope'] . ';' ;
} else {
$raw .= serialize($value) ;
}
$array[$key] = Array('huge_recursion_blocker_we_hope' => $line) ;
}
$this->content = $raw;
$this->save();
}
private static function unserialize_php($session_data) {
$return_data = array();
$offset = 0;
while ($offset < strlen($session_data)) {
if (!strstr(substr($session_data, $offset), "|")) {
throw new Exception("invalid data, remaining: " . substr($session_data, $offset));
}
$pos = strpos($session_data, "|", $offset);
$num = $pos - $offset;
$varname = substr($session_data, $offset, $num);
$offset += $num + 1;
$data = unserialize(substr($session_data, $offset));
$return_data[$varname] = $data;
$offset += strlen(serialize($data));
}
return $return_data;
}
private static function unserialize_phpbinary($session_data) {
$return_data = array();
$offset = 0;
while ($offset < strlen($session_data)) {
$num = ord($session_data[$offset]);
$offset += 1;
$varname = substr($session_data, $offset, $num);
$offset += $num;
$data = unserialize(substr($session_data, $offset));
$return_data[$varname] = $data;
$offset += strlen(serialize($data));
}
return $return_data;
}
}
Cũng bằng văn bản câu hỏi :) –
Cảm ơn :) btw trên [câu hỏi này] (http://stackoverflow.com/questions/9948182/custom-serialize- handler-for-custom-php-sessionhandler-db-storage? rq = 1) ai đó đã đề cập bằng cách sử dụng trình xử lý tuần tự hóa tùy chỉnh, tuy nhiên điều đó sẽ quá lớn đối với việc di chuyển của chúng tôi - vì vậy chúng tôi bị kẹt trên trình xử lý mặc định ~ –