What I am trying to do is write a “search” class that can search for a list of products and store them in an array.
I already have a “product” class that can be used to get the details of a specific product.
Here is my code:
class Product {
public $name;
public $price;
public $description;
public function getProductById ($id) {
$sql = 'SELECT name, price, description FROM product WHERE id = ' . $id;
$row = /* MySQL functions here to execute SQL statement and get a matching row */
$this->name = $row['name'];
$this->price = $row['price'];
$this->description = $row['description'];
return TRUE;
}
}
class Search {
public $results;
public $totalResults;
function __construct() {
$this->results = array ();
$this->totalResults = 0;
}
public function doSearch ($name) {
$sql = 'SELECT id FROM product WHERE name LIKE "%' . $name . '%"';
$rows = /* MySQL functions here to execute SQL statement and get a list of matching product ID's */
foreach ($rows as $row) {
$product = new Product;
$product->getProductById ($row['productid']);
$this->results[] = $product;
}
return TRUE;
}
}
$search = new Search;
$search->doSearch ('Fresh Flowers');
The problem with the above is that every matching record in the doSearch method will execute a query in the getProductById method. If there are 100 matching products, there will be 100 individual queries carried out in the Product class.
However, if I get the products directly in the doSearch method using a single query, this will then bypass the Product class altogether.
When a “product” is an object, what’s the most appropriate way to write a search class that can return a list of “product” objects without the overhead of what I’m doing above?
Add a constructor to the
Productclass which takes name, price and description as parameters (or an assoziative array), to populate the object with the necessary values, decoupled of the database query.Within
doSearch, you can then create aSELECTwhich not only gets the ID but all relevant fields from the products table, and create the populated product objects immediately withnew Product($name, $price, $description)ornew Product($row), without callinggetProductByIdfor each product.