PHP在简单ORM中转换对象

ih99xse1  于 2022-12-21  发布在  PHP
关注(0)|答案(1)|浏览(146)

我想在PHP中做一个简单的ORM,用于与我的数据库进行标准的CRUD交互,我还想让它在php5中工作,以实现遗留兼容性。
我已经写了一些类来做这个,它工作,但不完全像我会。
我有一个抽象类叫做ModelBase,它有一个属性(tableName)和一些方法,比如select,insert,update和delete,还有一个抽象方法getData,它将由实现ModelBase的类实现,并且应该返回正确类型的对象。
例如,我可以有一个实现ModelBase的类Users和另一个类UserData,UserData是具有属性的模型。
下面是代码:

abstract class ModelBase{
   private $tableName;

   public function __construct($tableName) { 
        $this->tableName = $tableName;
   }

   public function select{
       // make select query to db and retreive data
       // ...

       $resData = [];
       while($dataRow = mysqli_fetch_array($res, MYSQLI_ASSOC)) {
           $resData[] = $this->getObjectData($dataRow); // implemented in child class
       }
       return $resData;
   }

   public function insert(){ /* ... */}
   public function update(){ /* ... */}
   public function delete(){ /* ... */}
   abstract function getObjectData($data); // maps the results
}

class UserData {
   public $id;
   public $name;
   public $surname;
   public $email;
   // other fields

   public function __construct() {}
}

class User implements ModelBase {
    private $tableName = 'users';

    public function __construct() { 
        parent::__construct($this->tableName);
    }

    public function getObjectData($dataRow) {
        $o = new UserData ();

        // mapping dataRow to object fields
        $o->id = $dataRow['ID'];
        // ....

        return $o;
   }
}

所以我以这种方式使用我的类:

$users = new Users();
$u = users->select();
$firstUser = $u[0]; // I get my user if exists

在$firstUser中,我会得到一个带有属性和正确数据的对象,但我希望我的IDE(在本例中为vsCode)也能识别对象类型,以便建议正确的属性。因此,如果我写$firstUser-〉,我希望看到来自UserData和其他xyzData类的字段建议(id,name,surname,...)。
我应该做些什么来改进我的类,以便在我使用对象时看到属性建议,同样在php5中?

2vuwiymt

2vuwiymt1#

PHP 8的解决方案,已在PHPSorm上测试。

<?php

class Base {
    /**
     * @return static[]
     */
    public function select() : array {
        return [new self];
    }
    public function selectFirst() : static {
        return $this->select()[0];
    }
}

class User extends Base {
    public ?string $userName = null;
}

#detects the current class via () : static
(new User)->selectFirst()->userName;

#detects the current class via @return static[]
(new User)->select()[0]->userName;

PHP 5的行解决方案中,使用此注解直接定义变量

/** @var $a User */
$a->userName;

支持旧的php5没有任何好处。当支持旧的php版本时,你会失去如此多干净的代码和现代的方法。
但如果您必须这样做,那么就选择内联解决方案

PHP 5未经测试且不太干净:

class User extends Base {
    public ?string $userName = null;
    /**
     * @return User[]
     */
    public function select() : array {
        return parent::select();
    }
}

相关问题