Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP OOP:如何构造需要其他映射器功能的映射器_Php_Oop_Datamapper - Fatal编程技术网

PHP OOP:如何构造需要其他映射器功能的映射器

PHP OOP:如何构造需要其他映射器功能的映射器,php,oop,datamapper,Php,Oop,Datamapper,假设我有两个对象,类别和产品: 类别 <?php class Category { private $name; public function __construct(string $name) { $this->name = $name; } } ?> 选项2-让ProductMapper在需要类别映射的方法中创建一个类别映射 如果ProductMapper需要很多其他映射器,我可能会在这里忽略ProductMapper实际使用的

假设我有两个对象,类别和产品:

类别

<?php class Category {
    private $name;

    public function __construct(string $name) {
        $this->name = $name;
    }
}
?>
选项2-让ProductMapper在需要类别映射的方法中创建一个类别映射

如果ProductMapper需要很多其他映射器,我可能会在这里忽略ProductMapper实际使用的映射器,因为它们不是在一个地方列出的,而是分散在整个代码中

<?php
class ProductMapper {
    private $pdo;

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

    public function ofId($id) {

        $query = 'SELECT name, categoryId FROM product WHERE id = ?';
        $stmt = $pdo->prepare($query);
        $stmt->execute([$id]);

        if ($row = $stmt->fetch()) {
            $categoryMapper = new CategoryMapper($this->pdo);
            $category = $categoryMapper->ofId($row['categoryId']);
            return new Product($row['name'], $category);
        }

        return null;

    }
}
?>

选项3-不要使用CategoryMapper并在ProductMapper中复制构建类别代码

<?php
class CategoryMapper {
    private $pdo;

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

    public function ofId($id) : ?Category {

        $query = 'SELECT name FROM category WHERE id = ?';
        $stmt = $pdo->prepare($query);
        $stmt->execute([$id]);

        if ($row = $stmt->fetch()) {
            return new Category($row['name']);
        }

        return null;

    }

    // Other methods
}
?>
这只会导致大量重复代码(特别是当嵌入的对象变得更大或在其中嵌入了对象时)


那么这通常是如何做到的呢?
还有其他我没有想到的选项吗?

我认为应该在CategoryMapper类中添加一个singleton方法,如下所示

public static $instance = null;    
public static function getInstance() {
     if (self::$instance == null) {
        self::$instance = new self();
     }

     return self::$instance;
}
对ProductMapper的调用如下所示

public function __construct(PDO $pdo) {
    $this->pdo = $pdo;
    $this->categoryMapper = CategoryMapper::getInstance();
}

简单回答:第一种方法是正确的。您应该将所有依赖项作为参数传递到构造函数中

详细回答:第一种方法是正确的,但是使用依赖项注入容器是一个很好的实践。它将负责初始化对象并将它们作为参数传递给另一个对象。它还将确保每个类只初始化一个对象。如果你想要一些轻量级的东西,你可以选择,或者,如果你喜欢一些更具可配置性的东西,有很多特性

<?php
class ProductMapper {
    private $pdo;

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

    public function ofId($id) {

        $query = 'SELECT p.name as productName, c.name as categoryName FROM product p join category c on p.categoryId = c.id WHERE p.id = ?';
        $stmt = $pdo->prepare($query);
        $stmt->execute([$id]);

        if ($row = $stmt->fetch()) {
            $category = new Category($row['categoryName']);
            return new Product($row['productName'], $category);
        }

        return null;

    }
}
?>
public static $instance = null;    
public static function getInstance() {
     if (self::$instance == null) {
        self::$instance = new self();
     }

     return self::$instance;
}
public function __construct(PDO $pdo) {
    $this->pdo = $pdo;
    $this->categoryMapper = CategoryMapper::getInstance();
}