2013-03-21 62 views
7

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_encodesession_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; 
    } 
} 
+0

Cũng bằng văn bản câu hỏi :) –

+0

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 ~ –

Trả lời

1

Igbinary (https://github.com/igbinary/igbinary/) là một thả thay thế cho các serializer php chuẩn. Thay vì thời gian và không gian tiêu thụ văn bản đại diện, igbinary lưu trữ cấu trúc dữ liệu php dưới dạng nhị phân nhỏ gọn. Tiết kiệm là đáng kể khi sử dụng kho lưu trữ dựa trên bộ nhớ hoặc bộ nhớ tương tự cho dữ liệu được tuần tự hóa. Giảm 50% nhu cầu lưu trữ có thể được mong đợi. Số cụ thể tùy thuộc vào dữ liệu của bạn.

Hiệu suất không được thực hiện ít nhất là ngang bằng bộ nối tiếp chuẩn PHP. Hiệu suất tuần tự phụ thuộc vào tùy chọn "compact_strings" cho phép theo dõi chuỗi trùng lặp. Chuỗi được chèn vào một bảng băm có thêm một số chi phí. Trong các kịch bản thông thường, điều này không có nhiều ý nghĩa kể từ khi mẫu sử dụng được "tuần tự hóa hiếm khi, không thường xuyên". Với tùy chọn "compact_strings", igbinary thường chậm hơn một chút so với serializer chuẩn. Không có nó, nhanh hơn một chút.

Tính năng

  • Hỗ trợ các kiểu dữ liệu tương tự như các tiêu chuẩn PHP serializer: null, bool, int, float, string, mảng và đối tượng.
  • __autoload & unserialize_callback_func
  • __sleep & __wakeup
  • -interface Serializable
  • di động dữ liệu giữa các nền tảng (32/64bit, endianess)
  • Tested trên Linux amd64, Linux ARM, Mac OSX x86, HP-UX PA-RISC và NetBSD sparc64
  • Móc lên tới bộ đệm mã hóa APC như một bộ xử lý tuần tự hóa (APC 3.1.7+)
  • Compati ble với PHP 5.2 và 5,3

Hy vọng nó giúp

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