V
V
vadi_kot2018-04-23 03:14:41
PHP
vadi_kot, 2018-04-23 03:14:41

PHP PDO DB connection error: SQLSTATE[HY000]: General error: could not call class constructor?

There are two classes, one with a connection to the database and a child with the output of users, an error occurs when outputting data: SQLSTATE[HY000]: General error: could not call class constructor
class db

class db
{
    private static $dbh;

    public static function getDbh()
    {
        try {
            self::$dbh = new PDO('mysql:host=localhost;dbname=pdo_dev;charset=utf8', 'root', 'root');
            self::$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }
    catch (PDOException $e) {
            echo "Ошибка соединения с БД: ".$e->getMessage();
        }
    }

    public static function querySelect($query,$class)
    {
        self::getDbh();
        $sth = self::$dbh->prepare($query);
        $sth->execute();
        $result = $sth->fetchAll(PDO::FETCH_CLASS, $class);
        return $result;
    }
}

user class
class user extends db
{
    protected $id;
    protected $name;

   function __construct($id,$name)
    {
        $this->id=$id;
        $this->name=$name;
    }

    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param mixed $name
     */
    public function setName($name)
    {
        $this->name = $name;
    }


    public static function getUsers()
    {
        $query="SELECT * FROM user";
        $result = self::querySelect($query,__CLASS__);
        return $result;
    }
}

The error falls in the line $result = self::querySelect($query,__CLASS__);
If the constructor is removed from the user class, then everything works correctly, objects are created and displays all the data, but as soon as the constructor is added, such an error starts to fly out, can someone tell me what the problem is and how to fix this error?
Code in the executable:
$result = user::getUsers();
    foreach ($result as $item) {
        echo $item->getName()."<br />";
    }

Answer the question

In order to leave comments, you need to log in

3 answer(s)
R
Rsa97, 2018-04-23
@Rsa97

You have defined an explicit constructor in the child user class, so the constructor of the parent db class is not automatically called. Add an explicit call to the user class constructorparent::__construct();

F
FanatPHP, 2018-04-23
@FanatPHP

It should be noted that this class has a lot of other problems.
1. The static function for the connection is a card pinocchio, which does not perform any useful function, but performs only a harmful one, each time reconnecting to the melon database. You should at least check if there is already a connection and return it.
2. prepare with an empty execute is a cardinal pinocchio that does not perform any useful function, but only performs a harmful one, skipping all the injections in the world. In prepare, you need to pass a request with placeholders, and execute an array with variables to replace.
3. echo "Error connecting to the database:" - this is a card pinocchio that does not perform any useful function, but only performs a harmful one. The user will not understand anything from the error message, and the programmer will not know anything about it. To output try errors, there must be one, global, and output them depending on the environment - on a home computer, you can dump them directly on the screen, and on a production server, only log them.
4. The user is not a database. Therefore, it should not inherit from the DB class. and even more so there is not the slightest sense to inherit a class with static methods. The object for working with the database must be passed to the constructor and assigned to a class variable. Or if it is a stupid singleton, then don't transfer anything at all, but simply call its methods where necessary, although this is wrong.
Read more here (you can use Google translate)
https://phpdelusions.net/pdo/common_mistakes
https://phpdelusions.net/articles/error_reporting

S
Sergey Gerasimov, 2018-04-24
@mrTeo

When using PDO::FETCH_CLASS, a new object of the specified class is created as a result of fetching. The properties of the object will be assigned the values ​​of the columns whose names match the names of the properties. In this case, the values ​​are assigned to the properties of the object BEFORE the constructor is called. If properties with names corresponding to column names do not exist, they will be created automatically (with public scope).
If your data needs to be processed immediately after it is received from the database, it can be implemented in the class constructor.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question