Log in

View Full Version : Help with PDO query



fastsol1
02-02-2013, 12:28 AM
So I am just starting to convert my site to PDO but have come to a snag in my knowledge of this. I have this function for a search of products in the db and I don't know how to build this in a way that I can bind the values for security because of how the query is built with the $construct var. Since using PDO doesn't allow for a normal mysql_real_escape_string() escaping I am confused as to how to proceed.

Here is the function

function searchResults($start)
{
global $db;

$search_term = sanitize($_GET['search-term']);
if(empty($search_term))
{return FALSE;}
else
{
$search_xplode = preg_split('/[\s]+/', $search_term);
$m=1;
$construct='';
foreach ($search_xplode as $ste)
{
if ($m==1)
{
$construct .= "`".PRODUCTS."`.`prod_number` LIKE '%$ste%' AND `".PRODUCTS."`.`active`=TRUE
OR `".PRODUCTS."`.`prod_desc` LIKE '%$ste%' AND `".PRODUCTS."`.`active`=TRUE
OR `".PRODUCTS."`.`prod_name` LIKE '%$ste%' AND `".PRODUCTS."`.`active`=TRUE";
}
else
{
$construct .= " OR `".PRODUCTS."`.`prod_number` LIKE '%$ste%' AND `".PRODUCTS."`.`active`=TRUE
OR `".PRODUCTS."`.`prod_desc` LIKE '%$ste%' AND `".PRODUCTS."`.`active`=TRUE
OR `".PRODUCTS."`.`prod_name` LIKE '%$ste%' AND `".PRODUCTS."`.`active`=TRUE";
}
$m++;
}//End foreach loop.

$get = $db->query("SELECT
`".BRANDS."`.*,
`".PRODUCTS."`.*
FROM `".PRODUCTS."`
INNER JOIN `".BRANDS."` ON `".BRANDS."`.`id` = `".PRODUCTS."`.`brand_id`
WHERE $construct
ORDER BY `".BRANDS."`.`brand_name` ASC, `".PRODUCTS."`.`price` ASC
LIMIT $start, {$GLOBALS['settings']['prod_per_page']}");

if($get->rowCount() <=0)
{return FALSE;}
else
{
$the_prod_info = array();
while ($prod = $get->fetch(PDO::FETCH_ASSOC) !== FALSE)
{ $the_prod_info[] = $prod; }
$the_prod_info[] = recordCount(PRODUCTS, "WHERE ".$construct);
return $the_prod_info;
}
}
}

Don't be concerned about the sanitize() I use cause that is something I have built but doesn't have any bearing on the issue. Typically I have been doing the binding the easy way like this


$get = $db->prepare("BLAH BLAH");
$get->execute(array($var, $var));

Any help would be greatly appreciated.

fastsol1
02-02-2013, 02:08 AM
Nevermind, figured it out pretty fast once I thought about it. I also learned of a new SELECT feature to get the total number of rows in the first query without the LIMIT being factored and then you use the SELECT FOUND_ROWS() in the next query right after and gives the result from the first query but is much faster and if you have a complicated query for the first query string you don't have to duplicate it again for the second, VERY nice feature for pagination purposes.

Here is the result


function searchResults($start)
{
global $db;

$search_term = sanitize($_GET['search-term']);
if(empty($search_term))
{return FALSE;}
else
{
$search_xplode = preg_split('/[\s]+/', $search_term);
$m=1;
$params = array();
$construct='';
foreach ($search_xplode as $ste)
{
$params[$m] = '%'.$ste.'%';

if ($m==1)
{
$construct .= "`".PRODUCTS."`.`prod_number` LIKE :$m AND `".PRODUCTS."`.`active`=TRUE
OR `".PRODUCTS."`.`prod_desc` LIKE :$m AND `".PRODUCTS."`.`active`=TRUE
OR `".PRODUCTS."`.`prod_name` LIKE :$m AND `".PRODUCTS."`.`active`=TRUE";
}
else
{
$construct .= " OR `".PRODUCTS."`.`prod_number` LIKE :$m AND `".PRODUCTS."`.`active`=TRUE
OR `".PRODUCTS."`.`prod_desc` LIKE :$m AND `".PRODUCTS."`.`active`=TRUE
OR `".PRODUCTS."`.`prod_name` LIKE :$m AND `".PRODUCTS."`.`active`=TRUE";
}
$m++;
}//End foreach loop.

$sql = "SELECT SQL_CALC_FOUND_ROWS
`".BRANDS."`.*,
`".PRODUCTS."`.*
FROM `".PRODUCTS."`
INNER JOIN `".BRANDS."` ON `".BRANDS."`.`id` = `".PRODUCTS."`.`brand_id`
WHERE $construct
ORDER BY `".BRANDS."`.`brand_name` ASC, `".PRODUCTS."`.`price` ASC
LIMIT $start, {$GLOBALS['settings']['prod_per_page']}";
$get = $db->prepare($sql);

foreach($params as $key => $val)
{ $get->bindValue(':'.$key, $val, PDO::PARAM_STR); }
$get->execute();

$total_rows = $db->query('SELECT FOUND_ROWS();')->fetch(PDO::FETCH_COLUMN);

if($get->rowCount() <=0)
{return FALSE;}
else
{
$the_prod_info = array();
while ($prod = $get->fetch(PDO::FETCH_ASSOC))
{ $the_prod_info[] = $prod; }
$the_prod_info[] = $total_rows;
return $the_prod_info;
}
}
}