Error instantiating two or more PDOs in different classes

0

I'll start with the displayed error:

  

Fatal error: Uncaught PDOException: You can not serialize or   unserialize PDO instances in [no active file] on line 0

In the project I have the Carts class and the Tags class, both are subclasses of a class called Database , in which I make the connection to the database and I run CRUD, etc.

The error occurred when I tried to call two controllers at the same time, one to list the records of the Carrinhos class and another to list the records of the Marcas class. Here are the methods used:

To connect to the database: (runs when the Carts class and the Tags class are instantiated)

private function connect($line)
{
    if(is_null($this->connection))
    {
        try {
            if ($conn = $this->tryConnect($line, $this->database))
                return $conn;
            else
                return $this->tryConnect($line);
        } catch (Exception $e) {
            Log::register($e->getMessage() . "In l:" . __LINE__);
            return false;
        }
    }
    else
        return $this->connection;

}
private function tryConnect($line, $dbname = null)
{
    try
    {
        if(!is_null($dbname))
            $dbname =  ';dbname=' . $dbname;
        Session::set("teste", $dbname);
        $conn = new PDO
        (
            'mysql:host=' . Settings::get('dbhost') . $dbname,
            Settings::get('dbuser'),
            Settings::get('dbpassword'),
            array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")
        );
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $conn->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_EMPTY_STRING);
        Log::register("Is connect \nIn l:".$line, "mysql_success");
        return $conn;
    }
    catch (Exception $e)
    {
        Log::register($e->getMessage()."In l:" .__LINE__);
        return false;
    }
}

To list the records of each class use:

public function listAll($pager = null, $criteria = null)
{
    $data = $this->clear();
    $sql = "";

    if($pager instanceof Pager and $criteria instanceof Criteria)
        $sql =  "SELECT *" . " FROM {$this->addCriteria($criteria)} LIMIT {$pager->range()['min']}, {$pager->range()['max']};";
    else if($pager instanceof Pager)
        $sql =  "SELECT *" . " FROM {$data['table']} LIMIT {$pager->range()['min']}, {$pager->range()['max']};";

    else if($criteria instanceof Criteria)
        $sql = "SELECT {$criteria->getSelect()}" . " FROM {$this->addCriteria($criteria)};";
    else if(!$pager instanceof Pager)
        $sql = "SELECT *" . " FROM {$data['table']};";

    if($this->debug)
        var_dump($sql);

    if($this->connection = $this->connect(__LINE__))
    {
        try
        {
            $prepare = $this->connection->prepare($sql);
            if($criteria instanceof Criteria)
                foreach ($criteria->getValues() as $key => $value)
                    $prepare->bindValue(":$key", $value);

            $prepare->execute();
            $list = $prepare->fetchAll(PDO::FETCH_ASSOC);
            $return = array();

            foreach ($list as $row)
                array_push($return, $this->fills($row));

            Log::register("List All execute of: " . $sql. "\nIn l:" . __LINE__, "mysql_success");
            return $return;
        }
        catch (Exception $e)
        {
            Log::register($e->getMessage()."In l:" .__LINE__);
        }
    }
    return false;
}

Where Pager and Criteria are not relevant.

And finally the method to terminate the connection:

private function close($prepare, $action, $line)
{
    if($prepare instanceof PDOStatement)
    {
        if($prepare->execute())
        {
            Log::register($action . " execute of: " . $prepare->queryString . "\nIn l:$line", "mysql_success");
            foreach ($_POST as $key => $value)
                unset($_POST[$key]);
            $this->connection = null;
            Saved::destroy();
            return true;
        }
    }
    return false;
}

From what I see the error would be that you are trying to use two concurrent connections in the same database, the solution I researched looks like it would use the #

    
asked by anonymous 15.08.2016 / 18:31

2 answers

0

The error was not in the instantiation of the PDO as I found (since all the results in the searches spoke the same problem), but because I was storing a array of objects in a session variable, even doing serialize was not working.

The solution was to pass the objects to array , so I took advantage of a method that had in my Database that transforms my model into array :

private function clear()
{
    $attr = get_class_vars(get_class($this->object));
    $attr2 = get_class_vars('Database');

    foreach ($attr as $key => $value)
        if($key != 'table' and key_exists($key, $attr2))
            unset($attr[$key]);

    $data = array();
    foreach ($attr as $key => $value)
        $data[$key] = $this->object->$key;
    return $data;
}

Then I made a public method to get the object already as an array:

public function vars()
{
    return $this->clear();
}

In controller , I created a method that takes the list of objects and transforms it into a list of arrays :

public function toArray($object)
{
    if(is_array($object))
    {

        $variables = array();
        foreach ($object as $o)
        {
            array_push($variables, $this->scan($o));
        }
        return $variables;
    }
    else if(is_object($object))
    {
        return $this->scan($object);
    }
}

private function scan($o)
{
    if(is_object($o))
    {
        $vars = $o->vars();
        foreach ($vars as $k => $v)
        {
            if(is_object($v))
            {
                $vars[$k] = $this->toArray($v);
            }
        }
        return $vars;
    }
}

For others the code may seem strange, but it fits the framework of the framework: link

    
15.08.2016 / 20:58
0

I understand from your code that you are trying to make a connection class using the Singleton . I think the way is this. A connection class in the singleton pattern would look like this:

<?php
class SingletonDB
{
    public $db;
    private static $instance;

    private function __construct()
    {
        $this -> dbhc= new PDO('mysql:host=localhost;dbname=example', "root", "");
    }

    //singleton pattern
    public static function getInstance()
    {
        if (!isset(self::$instance))
        {
            $object = __CLASS__;
            self::$instance = new $object;
        }
        return self::$instance;
    }
}

?>

Taking an instance of the class

$db = database::getInstance();

Source: link

    
15.08.2016 / 20:19