0

我有一个快速的:我是 PHP 对象的初学者,我有一个包含我所有产品的产品表。

我的产品也有一个类(有一个构造函数,用我的产品的所有参数填充我的实例)。

假设我想要一个我所有产品的列表,我应该为我的产品列表创建一个单独的类,还是创建一个创建我的产品类的新实例的函数?

我现在并没有真正得到它的好处,因为如果我必须执行与我的类查询完全相同的查询,那没用?

谢谢你的提示!

更新

谢谢各位!这对我来说仍然很复杂,但这就是我所做的(谈论书籍)试图遵循你的建议。

我创建了一个 DAO。在这个 DAO 中,我有两个静态函数返回书籍列表或一本书,以及一个创建书籍对象的静态函数。

使用这种方法,我仍然有 2 个查询(一个用于列表,一个用于单本书)。我有一种感觉这是错误的,但任何帮助表示赞赏:)

class bookDAO {

    public static function getBooks() {
        $books = array();
        $db = databaseConnection::getInstance();
        $query = $db->query("SELECT * FROM books");
        while($row = $query->fetchObject()) {
            $book = self::createBookFromRow($row);
            $books[] = $book;
        }
        return $books;
    }

    public static function getBook($id){
        $db = databaseConnection::getInstance();
        $query = $db->prepare("SELECT * FROM books WHERE id=:id");
        $query->execute(array(":id"=>$id));
        $row = $query->fetchObject();
        $book = self::createBookFromRow($row);
        return $book;
    }

    private static function createBookFromRow($row) {
        $book = new book($row);
        return $book;
    }

}
4

4 回答 4

3

在这种情况下,创建对象数组很常见。

例如:

$products = array();
foreach($results as $result) {
  $products[] = new Product($result);
}
print_r($products);
于 2012-10-02T19:05:22.887 回答
2

您可以简单地添加一个数组。或者,如果您想向产品列表中添加一些方法,您可以实现如下内容:

class Products
{
    private $productFactory;

    private $products = array();

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

    public function addProduct($product)
    {
        $this->products[] = $this->productFactory->build($product);
    }

    public function addProducts($products)
    {
        foreach ($products as $product) {
            $this->addProduct($product);
        }
    }

    // do soemthing with all products
    public function changeProducts()
    {
        foreach($this->products as $product) {
            $product->changeSpec('new spec value');
        }
    }
}

class Product
{
    private $someSpec;

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

    public function changeSpec($spec) {
        $this->someSpec = $spec;
    }
}

class ProductFactory
{
    public function build($spec) {
        return new Product($spec);
    }
}

// build the productslist object
$productFactory = new ProductFactory();
$products = new Products($productFactory);
$products->addProducts(array(
    'some spec of product1',
    'some spec of product2',
));

请注意,我手动添加产品,但这也可能是来自某些持久存储机制(例如数据库)的记录集。或者也许更好地注入一些访问数据库以检索产品的类。不要在Product/Products类中进行任何查询。如果你这样做,你会紧密耦合某些东西(数据库),这使得测试变得非常困难。除此之外,您还违反了SRP

请注意,我创建了一个工厂来创建Product该类的新实例。这样,您就没有将Product类与Products类紧密耦合。如果您想进行单元测试,这使得模拟 Product 类变得更加容易。

更新

你可以对这个类做的另一件事Products是让它实现Iterator接口,这样你也可以根据需要循环遍历产品。

于 2012-10-02T19:15:01.213 回答
2

您的 Product 类不应该执行任何查询,将其分成 DAO 例如ProductDAO

class ProductDAO
{
  function static getProducts()
  {
     //Your query here: PDO, MySQLi, MySQL etc
    $products = array(); //to store array of products

    while($row = mysql_fetch_assoc($result))
    {
       $product = createProductFromRow($row);

       $products[] = $product;
    }

    return $products;
}

   private static function createProductFromRow($row)
   {
   $product = new Product();
   $product->setId($row["id"]);
   $product->setName($row["Name"]);
   //etc

   return $product; 
   }
}

从您的页面

  $products = ProductDAO::getProducts();

  foreach($products as $p)
  {
     echo ($p->getName() + '<br />');
  }
于 2012-10-02T19:08:26.893 回答
1

将保存所有产品引用的产品类

class Products {

    static private $store = array();

    static public function save(Product $object)
    {
        self::$store[] = $object;
    }

    static public function getAll()
    {
        return self::$store;
    }

}

将每个 Product 引用保存到 Products 类

最简单的方法是在您的 Product 构造函数中执行此操作。

# your Product class
class Product {

    public function __construct()
    {
        # your stuff here..

        # save reference of current Product to the Products
        Products::save($this);
    }

}

您对产品的初始化

这仅用于测试,请在此处使用您的逻辑来初始化 Product 对象。

new Product;
new Product;
new Product;

循环遍历所有产品

foreach (Products::getAll() as $product) {
    var_dump($product);
}
于 2012-10-02T19:17:24.317 回答