barophobia
barophobia

Reputation: 31

How do I work with collections of objects? Or rather, does an object retrieve a collection of similar objects?

I think I get the OOP paradigm at its basic level but I'm having a hard time conceptualizing the proper way to lookup records in a database. I suspect this is because I don't really get OOP as much as I think I do...

The application I'm trying to write is a shopping cart because it has a lot of good candidates for objects. The object I'll be working with is a product (yes, this is very primitive).

<?php
    class Product
    {
        public $id = 0;
        public $name = '';
        public $price = 0;

        function __construct($id)
        {
            // if $id exists try to retrieve
            // a product with $id
            // else create a new product
            // and set $this->id
        }
    }

    $product = new Product();
    echo $product->name;
?>

Easy enough. But now I want to look up multiple products (for a search results page) and I'm not sure how to handle it.

My inclination is to write another class that takes some input and performs a SQL query that just returns a list of product ids. I would then loop through those results and create a product object for each one. I could then loop through the array of objects and build my search results page.

I'm not sure why but this just doesn't feel like the right way. Seems like too much work because first I'm doing a query to just get a list of product ids and then I do more queries to get each product's data. It'd be a lot faster if just did one query that returned all the data I need.

What's the right thing to do? Something else perhaps?

Upvotes: 3

Views: 267

Answers (4)

Justin
Justin

Reputation: 5069

Dont be averse to using already-existing frameworks for dealing with databases in OOP. Zend_Db has different usage methods, most notably the Table Gateway/Row Gateway method as is sort of described above. TableGateway is intended to do queries and return Rows. Rows represent a single row and can be manipulated independently.

If you're doing a query for many rows, a separate class that represents the table (or even 'virtual' table in the case of some complex join) is the cleanest way to keep the concerns of that table and the individual rows separate.

Upvotes: 0

troelskn
troelskn

Reputation: 117547

Mapping from a database to an object oriented application isn't trivial. There are different ways to approach this, but a simple strategy is to have an entity class (Product) and a gateway class (could be called different things, but typically ProductGateway or ProductFinder). The gateway class has access to the database and it knows how to fetch and initialize entities. The same class would also know how to map the object back to the database.

For example:

class ProductGateway {
  function getProductById($id) {
    $result = $this->db->query("select * from products where id = ?", $id);
    return new Product($result->next());
  }
  function save($product) {
    if ($product->getId()) {
      return $this->update($product);
    } else {
      return $this->insert($product);
    }
  }
  ...
}

The point is that you application level code doesn't need to know if the product came from a database or not. It just changes the entity object and leaves it for the gateway to deal with persistence.

Upvotes: 2

djna
djna

Reputation: 55907

I think you're thinking on the right lines - one thing though, why return only ids, return the array (or list) of matching products.

How about a ProductFinder which has query methods, parameters being definitions of products the return type being a collection of Products.

You then may see that the ProductFinder could also take responsibility for creating products (inserting to the DB), deleting products etc. Hence the Product itself knows little or nothing about the db. The ProductFinder might then get a slightly different name such as ProductKeeper or ProductHome.

If you have quite a few entities in addition to products you then may find that their "keepers" have an awful lot of code in common, before long you end up with a persistence framework. There seems to be at least one already for php, I suggest you have a look at it.

Upvotes: 0

VolkerK
VolkerK

Reputation: 96149

Write a product class that isn't aware of the database (hard to believe but products can exist without a database ;)) and a class that can create product objects from a database result.

Upvotes: 2

Related Questions