2013-03-21 10 views
7

एन्कोड और डीकोड करने के लिए इन विधियों की सुरक्षा इस तरह से इस प्रश्न को this one के विस्तार के रूप में देखा जा सकता है।PHP सत्र

हम एक ऐसी कक्षा को जारी करने पर विचार कर रहे हैं जो एक बड़े पैमाने पर उत्पादन वेबसाइट पर तालिका में संग्रहीत सत्र डेटा को deserializing और serializing संभालती है ताकि हम मनमाना सत्र डेटा संपादित कर सकें।

समस्या session_decode() भरता वर्तमान $_SESSION एक डीकोड सरणी लौटने के बिना है, और session_encode() एक दिया सरणी एन्कोड नहीं करता (यह केवल वर्तमान सत्र के एक धारावाहिक स्ट्रिंग देता है।)

डिफ़ॉल्ट पीएचपी सत्र serialize हैंडलर सत्रों को एन्कोड करने के लिए बस serialize() का उपयोग नहीं करते हैं, और इसलिए एक सत्र को एन्कोडिंग और डिकोडिंग की एक ही कार्यक्षमता प्राप्त करने का एकमात्र तरीका या तो वैश्विक $_SESSION वैरिएबल को स्थानांतरित करना है (यानी सत्र में स्टोर, डेटा पुनर्प्राप्त करना और पुनर्स्थापित करना) या कोशिश करके session.serialize_handler क्या करता है इसके कार्यान्वयन को पुन: उत्पन्न करने के लिए।

हमने बाद के प्रजनन दृष्टिकोण का चयन किया क्योंकि यह कम अवरोधक लगता है। दस्तावेज़ों में session_encode और session_decode के टिप्पणियों अनुभाग में इस प्रजनन पर कई प्रयास हुए हैं। मैंने दो को चुना है जो मुझे लगता है कि सबसे विश्वसनीय लगता है और उन्हें लागू किया। डीकोड विधि काफी मजबूत लगता है लेकिन यह काम करता है, लेकिन एन्कोड विधि 5 साल पहले

हम अभी भी इसे बाहर रोल करने के लिए अनिच्छुक हैं क्योंकि अदृश्य किनारे के मामले हो सकते हैं जो इन विधियों को तोड़ने का कारण बनेंगे।

अंत में, मैं के लिए देख रहा हूँ:

  • उदाहरण है कि विधियों के नीचे टूट जाएगा, या
  • आश्वासन है कि इन तरीकों उत्पादन में इस्तेमाल किया गया है और
  • शायद विकल्प को तोड़ने नहीं होगा कि उत्पादन में कोशिश की और परीक्षण किया गया है?

सभी को उन्नत में धन्यवाद!

कोड:

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

खैर लिखा सवाल :) –

+0

धन्यवाद btw पर :) [इस सवाल] (http://stackoverflow.com/questions/9948182/custom-serialize- हैंडलर-फॉर-कस्टम-php-sessionhandler-db-storage? rq = 1) किसी ने कस्टम सीरियलाइजेशन हैंडलर का उपयोग करके उल्लेख किया है, हालांकि यह हमारे लिए एक चाल का बहुत बड़ा होगा - इसलिए हम डिफ़ॉल्ट हैंडलर पर फंस गए हैं ~ –

उत्तर

1

Igbinary (https://github.com/igbinary/igbinary/) मानक php serializer के लिए प्रतिस्थापन में एक बूंद है। कॉम्पैक्ट बाइनरी फॉर्म में समय और स्थान उपभोग करने वाले पाठपरक प्रस्तुति के बजाय, igbinary स्टोर php डेटा संरचनाओं को कॉम्पैक्ट बाइनरी रूप में। धारावाहिक डेटा के लिए memcached या समान स्मृति आधारित स्टोरेज का उपयोग करते समय बचत महत्वपूर्ण हैं। भंडारण आवश्यकता में लगभग 50% की कमी की उम्मीद की जा सकती है। विशिष्ट संख्या आपके डेटा पर निर्भर करती है।

असामान्यता प्रदर्शन कम से कम मानक PHP धारावाहिक के बराबर है। सीरियलाइजेशन प्रदर्शन "compact_strings" विकल्प पर निर्भर करता है जो डुप्लिकेट स्ट्रिंग ट्रैकिंग को सक्षम बनाता है। स्ट्रिंग को हैश टेबल में डाला जाता है जो कुछ ओवरहेड जोड़ता है। सामान्य परिदृश्यों में इसका अधिक महत्व नहीं होता है क्योंकि उपयोग पैटर्न "शायद ही कभी क्रमबद्ध होता है, अक्सर अनियमित होता है"। "Compact_strings" विकल्प के साथ आमतौर पर मानक serializer की तुलना में igbinary थोड़ा धीमा है। इसके बिना, थोड़ा तेज़।अशक्त, bool, int, नाव, स्ट्रिंग, सरणी और वस्तुओं:

  • मानक PHP serializer रूप में एक ही डेटा प्रकार का समर्थन करता है सुविधाएँ।
  • __autoload & unserialize_callback_func
  • __sleep & __wakeup
  • Serializable -interface
  • प्लेटफार्मों (32/64 बिट, endianess)
  • लिनक्स amd64, लिनक्स एआरएम, मैक OSX 86, HP-UX पर परीक्षण किया गया के बीच
  • डाटा पोर्टेबिलिटी पीए-आरआईएससी और नेटबीएसडी sparc64
  • एक सीरियलाइजेशन हैंडलर (एपीसी 3.1.7+)
  • Compati के रूप में एपीसी ओपोड कैश तक हुक पीएचपी 5.2 के साथ ble और 5,3

आशा है कि यह मदद करता है

संबंधित मुद्दे