Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

मैं फ़ाइल सिस्टम के बजाय PHP सत्र डेटा को डेटाबेस में कैसे सहेजूँ?

मैंने कई घंटों के डिबगिंग के दौरान पाया है कि संदर्भित लेख कई Google खोजों के साथ-साथ स्टैक ओवरफ़्लो उत्तरों के एक महत्वपूर्ण उपसमुच्चय जैसे यहां , यहां और यहां सभी अमान्य या पुरानी जानकारी प्रदान करते हैं।

डेटाबेस में सत्र डेटा सहेजने में [महत्वपूर्ण] समस्याएँ उत्पन्न करने वाली चीज़ें:

  • जबकि ऑनलाइन सभी उदाहरण बताते हैं कि आप session_set_save_handler को "भर" सकते हैं , उनमें से कोई भी यह नहीं बताता है कि आपको register_shutdown_function('session_write_close') भी सेट करना होगा भी (संदर्भ )

  • कई (पुरानी) मार्गदर्शिकाएं पुरानी SQL डेटाबेस संरचना को संदर्भित करती हैं, और उन्हें नहीं होना चाहिए इस्तेमाल किया गया। डेटाबेस में सत्र डेटा सहेजने के लिए आपको जो डेटाबेस संरचना चाहिए वह है:id /access /data . यही बात है। विभिन्न अतिरिक्त टाइमस्टैम्प कॉलम की कोई आवश्यकता नहीं है जैसा कि मैंने कुछ "गाइड" और उदाहरणों पर देखा है।

    • कई पुराने गाइड में पुराने MySQL सिंटैक्स भी हैं जैसे DELETE * FROM ...
  • [मेरे प्रश्न में निर्मित] वर्ग को कार्यान्वयन करना होगा SessionHandlerInterface . मैंने गाइड (उपरोक्त संदर्भित) देखे हैं जो sessionHandler . के कार्यान्वयन को देते हैं जो एक उपयुक्त इंटरफ़ेस नहीं है। शायद PHP के पिछले संस्करणों में थोड़ा अलग तरीका था (शायद <5.4)।

  • सत्र वर्ग के तरीके जरूरी PHP मैनुअल द्वारा निर्धारित मान लौटाएं। फिर से, शायद पूर्व-5.4 PHP से विरासत में मिला है, लेकिन मैंने जो दो गाइड पढ़े हैं, उन्होंने कहा कि class->open पढ़ने के लिए पंक्ति लौटाता है, जबकि PHP मैनुअल बताता है कि उसे true लौटाने की आवश्यकता है या false केवल।

  • यह मेरे मूल अंक का कारण है :मैं कस्टम सत्र नामों का उपयोग कर रहा था (वास्तव में सत्र के नाम के रूप में आईडी और सत्र आईडी के एक ही बात हैं! ) यह बहुत अच्छी StackOverflow पोस्ट के अनुसार और यह एक सत्र नाम उत्पन्न कर रहा था जो 128 वर्ण लंबा था। चूंकि सत्र का नाम एकमात्र कुंजी है जिसे किसी सत्र से समझौता करने और सत्र अपहरण तो एक लंबा नाम/आईडी एक बहुत अच्छी बात है।

    • लेकिन, इससे एक समस्या हुई क्योंकि MySQL चुपचाप सत्र आईडी को काट रहा था 128 के बजाय केवल 32 वर्णों तक, इसलिए यह डेटाबेस में सत्र डेटा को खोजने में सक्षम नहीं था। यह पूरी तरह से मूक मुद्दा था (शायद मेरे डेटाबेस कनेक्शन वर्ग के कारण ऐसी चीजों की चेतावनियां नहीं फेंकना)। लेकिन यह वह है जिस पर ध्यान दिया जाना चाहिए। यदि आपको डेटाबेस से सत्र पुनर्प्राप्त करने में कोई समस्या है, तो पहले जांच लें कि पूर्ण सत्र आईडी प्रदान की गई फ़ील्ड में संग्रहीत किया जा सकता है।

तो इन सबके साथ ही कुछ अतिरिक्त विवरण भी जोड़े जाने हैं:

PHP मैनुअल पेज (ऊपर लिंक किया गया) एक क्लास ऑब्जेक्ट के लिए अनुपयुक्त लाइनों का ढेर दिखाता है:

जबकि अगर आप इसे क्लास कंस्ट्रक्टर में डालते हैं तो यह ठीक वैसे ही काम करता है:

class MySessionHandler implements SessionHandlerInterface {

    private $database = null;

public function __construct(){

    $this->database = new Database(whatever);

    // Set handler to overide SESSION
    session_set_save_handler(
        array($this, "open"),
        array($this, "close"),
        array($this, "read"),
        array($this, "write"),
        array($this, "destroy"),
        array($this, "gc")
        );
    register_shutdown_function('session_write_close');
    session_start();
    }
...
}

यह इसका मतलब है कि फिर अपने आउटपुट पेज पर एक सत्र शुरू करने के लिए आपको बस इतना ही चाहिए:

<?php
require "path/to/sessionhandler.class.php"; 
new MySessionHandler();

//Bang session has been setup and started and works

संदर्भ के लिए संपूर्ण सत्र संचार वर्ग इस प्रकार है, यह PHP 5.6 के साथ काम करता है (और शायद 7 लेकिन अभी तक 7 पर परीक्षण नहीं किया गया है)

<?php
/***
 * Created by PhpStorm.
 ***/
class MySessionHandler implements SessionHandlerInterface {
    private $database = null;

    public function __construct($sessionDBconnectionUrl){
        /***
         * Just setting up my own database connection. Use yours as you need.
         ***/ 

            require_once "class.database.include.php";
            $this->database = new DatabaseObject($sessionDBconnectionUrl);

        // Set handler to overide SESSION
        session_set_save_handler(
            array($this, "open"),
            array($this, "close"),
            array($this, "read"),
            array($this, "write"),
            array($this, "destroy"),
            array($this, "gc")
        );
        register_shutdown_function('session_write_close');
        session_start();
    }

    /**
     * Open
     */
    public function open($savepath, $id){
        // If successful
        $this->database->getSelect("SELECT `data` FROM sessions WHERE id = ? LIMIT 1",$id,TRUE);
        if($this->database->selectRowsFoundCounter() == 1){
            // Return True
            return true;
        }
        // Return False
        return false;
    }
    /**
     * Read
     */
    public function read($id)
    {
        // Set query
        $readRow = $this->database->getSelect('SELECT `data` FROM sessions WHERE id = ? LIMIT 1', $id,TRUE);
        if ($this->database->selectRowsFoundCounter() > 0) {
            return $readRow['data'];
        } else {
            return '';
        }
    }

    /**
     * Write
     */
    public function write($id, $data)
    {
        // Create time stamp
        $access = time();

        // Set query
        $dataReplace[0] = $id;
        $dataReplace[1] = $access;
        $dataReplace[2] = $data;
        if ($this->database->noReturnQuery('REPLACE INTO sessions(id,access,`data`) VALUES (?, ?, ?)', $dataReplace)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Destroy
     */
    public function destroy($id)
    {
        // Set query
        if ($this->database->noReturnQuery('DELETE FROM sessions WHERE id = ? LIMIT 1', $id)) {
            return true;
        } else {

            return false;
        }
    }
    /**
     * Close
     */
    public function close(){
        // Close the database connection
        if($this->database->dbiLink->close){
            // Return True
            return true;
        }
        // Return False
        return false;
    }

    /**
     * Garbage Collection
     */
    public function gc($max)
    {
        // Calculate what is to be deemed old
        $old = time() - $max;

        if ($this->database->noReturnQuery('DELETE FROM sessions WHERE access < ?', $old)) {
            return true;
        } else {
            return false;
        }
    }

    public function __destruct()
    {
        $this->close();
    }

}

उपयोग:जैसा कि क्लास कोड टेक्स्ट के ठीक ऊपर दिखाया गया है।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. आईफोन ऐप (आईओएस एसडीके) को php/MySQL बैकएंड से कनेक्ट करने का सबसे अच्छा तरीका क्या है?

  2. कमांड प्रॉम्प्ट से mysqldump का उपयोग करके बैकअप फ़ाइल नाम के साथ दिनांक और समय कैसे जोड़ें और बैकअप फ़ाइल के पथ को परिभाषित करें

  3. django auth उपयोगकर्ता ईमेल फ़ील्ड को छोटा कर रहा है

  4. कैसे जांचें कि कोई तालिका MySQL में बनाने से पहले पहले से मौजूद है या नहीं?

  5. मुझे कर्मचारी तालिका से दूसरा सबसे बड़ा वेतन कैसे मिलेगा?