使用FETCH_CLASS将数据加载到类本身

I want to load data from the database (with PDO) and push it into a class. But it shall be generic, so I am using an abstract class which shall do all the basic stuff. And each sub-class (1 for each database table) shall be as reduced as possible.

At the same time, I want to keep control of the public properties and functions.

abstract class myTable {
    protected static $table
    protected static $classname

    public function __construct($id) {
        $pdo = new MyMagicPdoClass();

        $sql  = "SELCT * FROM ".self::$table." WHERE id = {$id}";
        $stmt = pdo->prepare($sql);
        $stmt->execute();
        $result = $stmt->fetchAll(PDO::FETCH_CLASS, self::$classname);

        // Here is my OBJECT in the CLASS-TYPE i want (POINT 1)
        // Show evidence for testing: 
        echo "<pre>",print_r($result),"</pre>";
    }

}


class User extends myTable {

    // for each accessable field: property-name = column-name --> as PRIVATE
    private $id;
    private $FirstName;
    private $LastName;
    private $Email;

    // avoid automated property creation (by PDO::FETCH_CLASS), the
    // use of "__set()"-method helps to filter all properties out.
    // Only properties (declared in this class) that match with the name of the column
    // will be initiated. If not doing this, ALL columns would be
    // automatically created as an PUBLIC property of the class. 
    // So no control via Gettes and Setters.
    public function __set($name, $value) {}

    public function __construct($id = null) {
        self::$classname = __CLASS__; // will be used in abstract class
        self::$table = "tblUser";     // will be used in abstract class

        // call onstructer of parent-class
        parent::__construct($id);

        /**
         * I GUESS, HERE SHOULD BE THE MAGIC (POINT 2)
         */
    }

    // SETTERS
    public function setFirstName($value) {
        $this->FirstName = $value;
    }
    [...]

    // GETTERS
    public function getFirstName() {
       return $this->FirstName;
    }
    [...]

    // SOME METHODS
    public function doWhatOnlyThisClassShallDo() {...}
}

Example of usage

$id = 234;
$user = new User($id);

echo $user->FirstName;                    // shall be forbidden
echo $user->getFirstName();               // shall be used instead
echo $user->doWhatOnlyThisClassShallDo(); // shall be possible

In the parent constructor, I have the OBJECT that I am looking for in $result. Now I want to have this as the result of my constructor (see Point 2) from the sub-class.

For sure I can now load manually each property in the constructor by the result of the abstract class, but as written above, I want to keep each sub-class as simple as possible. On top is that all the effort with FETCH_CLASS is useless as I simply allocate values to properties in the sub-class' constructor.

Any suggestions? Or am I using the wrong approach?

So you want to fetch the row from the database and populate each column value into the matching property? Also, I'm sure you want to perform safe and secure database queries. I think this is what you're looking for:

abstract class myTable {
    protected static $table
    protected static $classname

    public function __construct($id) {
        $pdo = new MyMagicPdoClass();

        $sql  = "SELECT * FROM " . self::$table . " WHERE id = ?";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$id]);
        $result = $stmt->fetch(\PDO::FETCH_ASSOC);
        foreach ($result as $k=>$v) {
            if (property_exists($this, $k)) {
                $this->$k = $v;
            }
        }
    }

}