2

I have a design question for working with databases in object-oriented PHP.

I have a table in my database called products. Then I have 2 classes for this table in my PHP project. ProductsRepository.php and Product.php.

ProductsRepository.php currently looks like this

class ProductsRepository
{

    private $db;

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

    public function getById($id)
    {
        $data = $this->db->GetProductByID($id);

        $product = new Product(
            $data['id'],
            $data['category'],
            $data['title'],
            $data['description'],
        );

        return $product;
    }

    public function getAll()
    {
        $products = array();
        $data = $this->db->GetAllProducts();
        foreach ($data as $productData){
            $product = new Product(
                $productData['id'],
                $productData['category'],
                $productData['title'],
                $productData['description'],
            );
            $products[] = $product;
        }

        return $products;
    }
}

My question is how I should build a "createProduct" method. First and foremost, which class should it be in? I want the method to return an instance of the new product. The main problem I have with this is how I should handle the id of the new product since it will be given the next id available by the database.

A few options I've thought of:

Have createProduct in ProductsRepositoryand let it take a product with id set to -1 as argument

public function createProduct(Product $product)
{
    $product['id'] = $this->db->insertANewProduct($product); //returns the id
}

Have createProduct in Product

Should this be the constructor for the Product class?

public function createProduct($db, $data)
{
    $this->$data = $data; //includes all info of the new product except the id
    $this->$data['id'] = $db->insertANewProduct($data); //returns the id
}

1 Answer 1

2
$this->$data['id'] = $db->insertANewProduct($data);

I think is a bad practice, because breaks de Single Responsibility Principle, the product class knows it's been persisted. You are loosing what you win with the repository pattern. If you want to do that another option (less OO) is Active Record.

I would choose the option 1

    public function createProduct(Product $product){
       $product['id'] = $this->db->insertANewProduct($product);
       return $product;
    }

I really work in Java and use JPA for persistence my entities, in this case that you have auto generated id the JPA implementation (i.e. Hibernate) will populate the object id for you. Have you considered use a ORM?

4
  • Yes, I'm using an SQL database with AUTO_INCREMENT on the IDs Jul 16, 2015 at 23:21
  • And I imagine that you want to return the created product at success with the id? Jul 16, 2015 at 23:29
  • That is correct Jul 17, 2015 at 0:27
  • 1
    An ORM can solve many issues very well. But sometimes using an ORM is shooting birds with canons :)
    – AnotherGuy
    Jul 17, 2015 at 11:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.