phpsessionserializationdeserializationwakeup

Saving object to a session - How do I fetch my object from the session as it was before?


I am saving a customer class with some variables and methods to a session.

How do I manage to get all it's methods to work when fetching it back from a session? (Like an exact original if possible)

Is is what I have done so far:

<?php
namespace MyApp\Models;
use MyApp\Core\Database;
use MyApp\Helpers\Session;
use MyApp\Core\Config;

class Customer {

    private $db;

    public $host;

    public $dbName; 

    public $type;


    public function __construct($customerName = NULL)
    {
        # Get database instance
        $this->db = Database::getInstance();

        # If customer name passed as a variable 
        if ( $customerName ) {

            # Get Customer data from db
            $data = $this->customerDataByName($customerName);

            if ($data) {
                # Set data to $this Obj
                $this->setCustomerData($data['db_host'], $data['db_name'], $data['system_type']);
                # Set $this Obj to Session
                $this->setCustomerToSession();
            } else {
                return false; 
            }
        } 
    }


    public function setCustomerData($host, $dbName, $type)
    {
        # Set customer host in object
        $this->host     = $host;
        # Set customer name in object
        $this->dbName   = $dbName;
        # Set customer type in object
        $this->type     = $type;
    }


    public function setCustomerToSession()
    {
        Session::put(Config::$customer, $this); 
    }


    public function customerDataByName($customer_name) 
    {
        return $this->db->row("SELECT `db_name`, `db_host`, `system_type` FROM customers WHERE customer_name = :customer_name", array('customer_name' => $customer_name));
    }



    public function __sleep()
    {
        return array('host', 'dbName', 'type', 'customerDataByName()', 'setCustomerData()' );
    }

    public function __wakeup()
    {
        $this->db = Database::getInstance();
    }

}

The "host", "dbName", and "type" are restored properly using the __sleep() method, I tried to add the functions in a few different ways and no luck.. I would want it to be able to connect to the database too.

And also tried using an other method:

public function setCustomerToSession()
{
    $serialized = serialize($this);
    Session::put(Config::$customer, $serialized); 
}

Without the __wakup and __sleep, Then tried:

$a = unserialize($_SESSION['customer']);
var_dump($a);

and got this error:

PHP Fatal error: Uncaught PDOException: You cannot serialize or unserialize PDO instances in...

Pointing to the line of $serialized = serialize($this);


Solution

  • You should use the function serialize() to returns a string containing a byte-stream representation of value, In reverse you can use unserialize(). Because you can not store object in PHP SESSION.

    The code should be,

    session_start();
    
    $a = your_object;
    $b = serialize($a);
    
    $_SESSION["serialized_data"] = $b; 
    # To store in Session
    
    $unserialized_data = unserialize($_SESSION["serialized_data"]); 
    # To get from Session as Object