数据库表类中实体类的使用与优化
立即解锁
发布时间: 2025-08-19 01:32:01 阅读量: 1 订阅数: 4 


PHP与MySQL:从入门到精通
### 数据库表类中实体类的使用与优化
在开发过程中,数据库返回的数据通常是以数组形式呈现的。以获取作者信息为例,原本代码会将`getUser()`方法返回的`$author`数组数据复制到新创建的`Author`类实例中。像下面这样:
```php
$author = $this->authentication->getUser();
$authorObject = new \Ijdb\Entity\Author($this->jokesTable);
$authorObject->id = $author['id'];
$authorObject->name = $author['name'];
$authorObject->email = $author['email'];
$authorObject->password = $author['password'];
```
这种方式显然效率低下,因为大部分代码只是简单地将数组数据复制到对象中。为了避免这个问题,我们可以在`saveEdit`方法之外构建`Author`对象,并让`getUser`方法返回这个构建好的对象。
#### 1. 用`fetchObject`方法返回对象
当前,`Authentication`类中的`getUser`方法调用了`DatabaseTable`类中的`findById`方法,该方法返回的是一个数组:
```php
public function findById($pdo, $table, $primaryKey, $value) {
$query = 'SELECT * FROM ' . $table . ' WHERE ' . $primaryKey . ' = :primaryKey';
$parameters = [
'primaryKey' => $value
];
$query = $this->query($query, $parameters);
return $query->fetch();
}
```
不过,PDO提供了`fetchObject`方法,它可以返回指定类的实例。例如,要让`fetchObject()`返回一个`Author`对象,可以这样使用:
```php
return $query->fetchObject('Author', [$jokesTable]);
```
这里有两个参数:
- 要实例化的类名。
- 创建对象时提供给构造函数的参数数组。
#### 2. 改进`DatabaseTable`类
由于`DatabaseTable`类需要与不同的数据库表交互,并且可能没有访问`$jokesTable`变量的权限,所以不能直接硬编码类名和构造函数参数。我们可以修改`DatabaseTable`类的构造函数,使其接受两个可选参数:要创建的类名和提供给它的任何参数。
```php
class DatabaseTable {
private $pdo;
private $table;
private $primaryKey;
private $className;
private $constructorArgs;
public function __construct(\PDO $pdo, string $table, string $primaryKey, string $className = '\stdClass', array $constructorArgs = []) {
$this->pdo = $pdo;
$this->table = $table;
$this->primaryKey = $primaryKey;
$this->className = $className;
$this->constructorArgs = $constructorArgs;
}
}
```
同时,修改`findById`方法,使用新的类变量:
```php
public function findById($value) {
$query = 'SELECT * FROM `' . $this->table . '` WHERE `' . $this->primaryKey . '` = :value';
$parameters = [
'value' => $value
];
$query = $this->query($query, $parameters);
return $query->fetchObject($this->className, $this->constructorArgs);
}
```
对于`PDO`的`fetchAll`方法,也可以通过提供`\PDO::FETCH_CLASS`作为第一个参数,类名作为第二个参数,构造函数参数作为第三个参数来返回对象:
```php
return $result->fetchAll(\PDO::FETCH_CLASS, $this->className, $this->constructorArgs);
```
#### 3. 更新`IjdbRoutes`类
修改`IjdbRoutes`类,为`$authorsTable`实例提供类名和参数:
```php
$this->jokesTable = new \Ninja\DatabaseTable($pdo, 'joke', 'id');
$this->authorsTable = new \Ninja\DatabaseTable($pdo, 'author', 'id', '\Ijdb\Entity\Author', [$this->jokesTable]);
```
现在,当使用`$authorsTable`实例检索记录时,`$author`变量将是`Author`类的一个实例,我们可以调用该类中的任何方法(如`addJoke`)。
#### 4. 修复`saveEdit`方法
修改`saveEdit`方法,避免值的复制:
```php
public function saveEdit() {
$aut
```
0
0
复制全文
相关推荐








