query with php array in mysql - php

I want to fetch contents with multiple filters, right now there's only one.
For Example:
SELECT * FROM Table1 WHERE status=true AND category = 'Camera' AND
model = 'Samsung' AND type = 'New'
I want to create an array for it. But as I'm a newbie in this one not getting a lead.
function getAllRequests($filter){
if(empty($filter)){
$addfilter = '';
}else{
$addfilter = 'AND cat_id=' . $filter;
}
}
$sql = 'SELECT * FROM Table1 WHERE status=true' . $filter;
Any help will be appreciated.

This will get you closer to the solution, though it will not replace the cat_id in the query, which will certainly be wrong - though impossible to do too much more without the array structure:
function getAllRequests($filter)
{
$addfilter="";
if(!empty($filter))
{
foreach($filter as $val)
{
$addfilter. = ' AND cat_id=' . $val .'\'';
}
}
return $addFilter;
}
$myFilters=getAllRequests($filter);
$sql = 'SELECT * FROM Table1 WHERE status=true' . $myFilters;
On the other hand, if your array is strucutred in a way like this:
array{ category => camera, model => samsung); // etc
you could use the following:
function getAllRequests($filter)
{
$addfilter="";
if(!empty($filter))
{
foreach($filter as $key => $val)
{
$addfilter. = " AND `$key` = '$val'";
}
}
return $addFilter;
}
$myFilters=getAllRequests($filter);
$sql = 'SELECT * FROM Table1 WHERE status=true' . $myFilters;
Edit: You can loop through all the filters in the following manner:
function getAllRequests()
{
$addfilter="";
if(!empty($_REQUEST))
{
foreach($_REQUEST as $key => $val)
{
$addfilter. = " AND `$key` = '$val'";
}
}
return $addFilter;
}
$myFilters=getAllRequests();
$sql = 'SELECT * FROM Table1 WHERE status=true' . $myFilters;
You don't need to pass the $_REQUEST (which will work for both GET and POST) as it already a superglobal.

function getAllRequests($filter){
if(empty($filter)){
$addfilter = '';
}else{
$addfilter = 'AND cat_id=' . $filter;
}
}
$sql = 'SELECT * FROM Table1 WHERE status=true' . $addfilter;

You can use another approach, which is using optional parameters and it will make your WHERE clause dynamic as you want. In this approach you pass all parameters' values directly to the sql query which should look like so:
SELECT *
FROM Table1
WHERE 1 = 1
AND (#status IS NULL OR status = #statusParam)
AND (#category IS NULL OR category = #categoryParam)
AND (#model IS NULL OR model = #modelParam)
AND (#type IS NULL OR type = #typeParam)
Then If any of the parameters #statusParam, #categoryParam, #modelParam or #typeParam passed to the query with NULL values, then the comparison with the column holding that value will be ignored. I used the predicate 1 = 1, in case all the values passed to the query with all NULL values in the case all the WHERE clause will be ignored as it won't presented, since WHERE 1 = 1 always true and it will be like SELECT * FROM Table1.

use this
function getAllRequests($filter){
if(empty($filter)){
$addfilter = '';
}else{
$addfilter .= 'AND cat_id=' . $filter;
}
return $addfilter;
}
$sql = 'SELECT * FROM Table1 WHERE status=true' . getAllRequests($filter);

When you are sending array make sure it has indexes
$conditions = array('category' => 'Camera', 'model' => 'Samsung' , 'type' => 'New')
Now loop through it. in your else condition
foreach($conditions as $key =>$value){
$addfilter .= 'AND ' . $key . ' = ' . $value;
}

Related

Php in_array with session

My PHP statement looks like this
$select_product= "SELECT * FROM `products` WHERE pro_name = '$page_name' and status = 'Active'";
$sql101=$dbconn->prepare($select_product);
$sql101->execute();
$wlvd101=$sql101->fetchAll(PDO::FETCH_OBJ);
foreach($wlvd101 as $rows101);
$product_id = $rows101->id;
// Gives me result of a sample id 101
Again I am another statement where I have fetched the ids of products from my cart. The statement looks like this:
$pidArr = array();
if(!empty($_SESSION['cart'])){
foreach($_SESSION['cart'] as $id=>$val)
{
$rate=$val['product_mrp'] * $val['qty'];
$total=$total+$rate;
$pidArr[] = $val['uid'];
$qtyArr[] = $val['qty'];
$webArr[] = $val['ppid'];
}
$all_cart_products = "'" . implode("','", $pidArr) . "'";
//echo $all_cart_products;
//It gives me a list of ids like this '100', '101', '102' etc
}
Now while using in_array, my statement is not working. The code looks like this:
$my_ids = $all_cart_products;
if (in_array("$product_id", $my_ids))
{
echo "Match Found";
}
else
{
echo "Match not found";
}
How to solve this problem?
This line $all_cart_products = "'" . implode("','", $pidArr) . "'" creates a string.
Which you then assign $my_ids = $all_cart_products; so $my_ids is also now a string.
Pass it $pidArr instead.

Remove row from array result from codeigniter query

I am executing below query in codeigniter which returns 4 rows:
$available_rooms = $this->db->query("SELECT id_room as id, ea_rooms.name as name FROM ea_rooms_services WHERE id_service =" . $service_id)->result_array();
Output e.g.:
{
{id:1, name:a}
{id:2, name:b}
{id:3, name:c}
{id:4, name:d}
}
I have an array with room ids $occupiedRooms (e.g. {0=>1, 1=>2}) which is being populated as follows:
$occupiedRooms = array();
foreach ($listing as $element){
... SOMECODE
if ($id_room != null)
$occupiedRooms[] = $id_room;
}
I want to unset all rows in $available_rooms that have the same ids in $occupiedRooms.
Expected output:
{
{id:3, name:c}
{id:4, name:d}
}
I am using below code but it is not working
foreach ($available_rooms as $elementKey => $element){
if(in_array($element['id'], $occupiedRooms)){
unset($available_rooms[$elementKey]);
}
}
I also tried array_filter with below code but it also didn't work:
foreach ($occupiedRooms as $id){
$available_rooms = array_filter($available_rooms, function($room) use($id)
{
return $room['id'] != $id;
});
}
this would be shorter:
$occupied_rooms = array(1,5,6);
$available_rooms = $this->db->query("SELECT id_room as id, ea_rooms.name as name FROM ea_rooms_services WHERE id_service =" . $service_id . " AND id_room NOT IN ( " . implode(",", $occupied_rooms) . " ) ")->result_array();

Multiple variables in prepared statement PHP

I'm having an issue preparing a SQL statement:
$statement = $conexion->prepare(
'SELECT * FROM celulares
WHERE (MARCA = :marca )
AND
(CATEGORIA = :categoria1 OR CATEGORIA = :categoria2 OR CATEGORIA = :categoria3)
AND
(CATEGORIA2 = :categoria1 OR CATEGORIA2 = :categoria2 OR CATEGORIA2= :categoria3)
AND
(CATEGORIA3 = :categoria1 OR CATEGORIA3 = :categoria2 OR CATEGORIA3 = :categoria3)');
Giving placeholders values with this:
$statement->execute(array(':categoria1' => $categoria1,
':categoria2' => $categoria2,
':categoria3' => $categoria3,
':marca' => $query
));
$query value may variate when my application begins depending on some results:
if ($entrada == "LG") {
if ($query == "") {
$query = "LG";
} else {
$query = $query . ' OR MARCA = "LG" ';
}
}
if ($entrada == "APPLE") {
if ($query == "") {
$query = "APPLE";
} else {
$query = $query . ' OR MARCA = "APPLE" ';
}
}
if ($entrada == "HUAWEI") {
if ($query == "") {
$query = "HUAWEI";
} else {
$query = $query . ' OR MARCA = "HUAWEI" ';
}
}
I tried a lot of things, but none of those worked out it returns an empty array, the only one who works was changing this line of my prepared statement:
WHERE (MARCA = :marca OR MARCA = :marca2 OR MARCA = :marca3 )
And as many "MARCA" as results, i think it's not the best way to do it
UPDATED:
Now trying with IN Statement in my Query (Thanks you all for helping me)
Now it looks like:
$marcas = array("LG", "HUAWEI"); (Static values for test)
$inQuery = implode(',', array_fill(0, count($marcas), '?'));
$statement = $conexion->prepare(
'SELECT * FROM celulares
WHERE (MARCA = IN (' . $inQuery . '))
AND
(CATEGORIA = :categoria1 OR CATEGORIA = :categoria2 OR CATEGORIA = :categoria3)
AND
(CATEGORIA2 = :categoria1 OR CATEGORIA2 = :categoria2 OR CATEGORIA2= :categoria3)
AND
(CATEGORIA3 = :categoria1 OR CATEGORIA3 = :categoria2 OR CATEGORIA3 = :categoria3)');
foreach ($marcas as $k => $marca) {
$statement->bindValue(($k+1), $marca);
}
$statement->bindValue(':categoria1', $categoria1);
$statement->bindValue(':categoria2', $categoria2);
$statement->bindValue(':categoria3', $categoria3);
$statement->execute();
Getting: Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters
Trying to fix it
You can simplify your query:
SELECT * FROM celulares
WHERE (MARCA = :marca )
AND (:categoria1,:categoria2,:categoria3)
IN (
(CATEGORIA,CATEGORIA2,CATEGORIA3),
(CATEGORIA,CATEGORIA3,CATEGORIA2),
(CATEGORIA2,CATEGORIA,CATEGORIA3),
(CATEGORIA2,CATEGORIA3,CATEGORIA),
(CATEGORIA3,CATEGORIA,CATEGORIA2),
(CATEGORIA3,CATEGORIA2,CATEGORIA)
)
This way you only pass in the categories once, and compare it against the six possible permutations of three categories.
That being said, this is a sign that your database is in very poor shape. Generally speaking having any kind of "column2", "column3" system is a sign that you need to restructure your database - the kind of queries you end up with, like the above, are only going to get worse.
Specifically, in this case, just adding CATEGORIEA4 would increase the amount of permutations you need to define from 6 to 24!!
EDIT: I completely missed the part about :marca and IN - I was too focussed on the bad state of the database with regard to categories, sorry!
Well, i fix it, probably it's not the best way to solve it but i have this now:
I fill array with entries from POST
$query = array();
$index = 0;
foreach ($_POST as $entrada) {
switch($entrada) {
case "SAMSUNG":
$query[] = "SAMSUNG";
break;
case "LG":
$query[] = "LG";
break;
case "APPLE":
$query[] = "APPLE";
break;
case "HUAWEI":
$query[] = "HUAWEI";
break;
}
}
$inQuery = str_repeat('?,', count($query) - 1) . '?';
Here's my new query: Problem was that i was mixing "?" with placeholders (:) which not is recommended
$statement = $conexion->prepare(
"SELECT * FROM celulares
WHERE ( MARCA IN($inQuery))
AND
(CATEGORIA = ? OR CATEGORIA = ? OR CATEGORIA = ?)
AND
(CATEGORIA2 = ? OR CATEGORIA2 = ? OR CATEGORIA2= ?)
AND
(CATEGORIA3 = ? OR CATEGORIA3 = ? OR CATEGORIA3 = ?)");
Then i bindValues like that
$c = 0;
foreach ($query as $q => $queries) {
$c++;
$statement->bindValue(($q+1), $queries);
}
$statement->bindValue($c+1, $categoria1);
$statement->bindValue($c+2, $categoria2);
$statement->bindValue($c+3, $categoria3);
$statement->bindValue($c+4, $categoria1);
$statement->bindValue($c+5, $categoria2);
$statement->bindValue($c+6, $categoria3);
$statement->bindValue($c+7, $categoria1);
$statement->bindValue($c+8, $categoria2);
$statement->bindValue($c+9, $categoria3);
$statement->execute();
$resultados = $statement->fetchAll();
I did many test with a lot of querys and it's working fine, probably it's a "dirty" solution but i'll continue learning
Thanks u all for helping me!

PHP failed to load string from other function as parameter

public function test_passing_string() {
$this - > load - > model(array('registration/Registration_model', 'Jawaban_lab_model'));
$registration = new Registration_model();
$jawaban_lab = new Jawaban_lab_model();
$id = "kuda4";
$jawaban_lab - > load($id); //load jawaban_lab from id
$manualy_written_registration_number = "REG/FM/130102-0001";
echo "registration number from jawaban_lab->registration_number : ".$jawaban_lab - > registration_number
.
"<br> registration number from manualy_written_registration_number : ".$manualy_written_registration_number;
//$registration->load($jawaban_lab->registration_number);
$registration - > load($manualy_written_registration_number);
echo "<br> patient id : ".json_encode($registration - > PatientID);
}
Before go to the question, I will explain my code.
On test_passing_string() function, I call 2 model, and create object for each model there are $registration and $jawaban_lab.
To load data from model I create a load() function. load() has two parameters: column_value and column_name. The default value for column_name is that model's Primary Key.
BUT
The problem comes from
$registration->load($jawaban_lab->registration_number);
I can't retrieve any $registration object data, then I test it by passing the value manually by write this:
$manualy_written_registration_number = "REG/FM/130102-0001";
$registration - > load($manualy_written_registration_number);
And the result appear, doesn't that mean my load() function is fine?
Then I check value inside $jawaban_lab->registration_number by echoing it, surprisingly it display same value as my $manualy_written_registration_number variable.
This is screenshoot in my browser when I run test_passing_string() function:
Using $manualy_written_registration_number value
Using $jawaban_lab->registration_number value
Why can't I use the value from
$jawaban_lab->registration_number even though it has the same value as
my manually writen registraiton number?
public function load($column_value, $column_name = NULL) {
$query = NULL;
if ($column_name != NULL) {
// using custom column.
$query = $this->dbs->get_where($this::DB_TABLE, array(
$column_name => $column_value
));
} else {
// using column primary key .
$query = $this->dbs->get_where($this::DB_TABLE, array(
$this::DB_TABLE_PK => $column_value
));
}
if ($query->row()) {
$this->populate($query->row());
}
}
I use multiple database using CodeIgniter 3, registration_model from SQL server and jawaban_lab from MySQL, jawaban lab have column registration_number to store registration_model primary key
var_dump
First of all thanks to rlanvin and Nirajan N Raju
from rlanvin's comment, i find out the problem is come from codeigniter's query helper, because when i enable codeigniter profiling sql server query return "SELECT CASE WHEN (##OPTIONS | 256) = ##OPTIONS THEN 1 ELSE 0 END AS qi"
so i think codeigniter might be cannot generate query so i create the query manually
i change
public function load($column_value, $column_name = NULL) {
$query = NULL;
if ($column_name != NULL) {
// using custom column.
$query = $this->dbs->get_where($this::DB_TABLE, array(
$column_name => $column_value
));
} else {
// using column primary key .
$query = $this->dbs->get_where($this::DB_TABLE, array(
$this::DB_TABLE_PK => $column_value
));
}
if ($query->row()) {
$this->populate($query->row());
}
}
to this
public function load($column_value, $column_name = NULL) {
$query = NULL;
if ($column_name != NULL) {
$query = $this->dbs->query("SELECT * FROM " . $this::DB_TABLE . " WHERE " . $column_name . " LIKE '" . trim($column_value) . "'");
} else {
$query = $this->dbs->query("SELECT * FROM " . $this::DB_TABLE . " WHERE " . $this::DB_TABLE_PK . " LIKE '" . trim($column_value) . "'");
}
if ($query->row()) {
$this->populate($query->row());
}
}

MYSQL: where column IN(Any_value)

I am trying to make a dynamic where clause. I am getting some array of check boxes in PHP as following code
$brand = array();
if(isset($_GET['brand']) && !empty($_GET['brand']))
$brand=$_GET['brand'];
$brand_str = implode("' , '",$brand);
}
MY SQL Query is
$sql="SELECT DISTINCT * FROM products WHERE brand IN('$brand_str')";
if brand is not defined it gives error or no row is fetched but its a simple problem can be solved using following approach.
MY approach:
I use a variable like 'flag_for_filter_brand' inside if statement that is if flag_for_filter_brand=1 the QUERY is
$brand = array();
$flag_for_filter_brand=false;
if(isset($_GET['brand']) && !empty($_GET['brand']))
$brand=$_GET['brand'];
$brand_str = implode("' , '",$brand);
$flag_for_filter_brand=true;
}
if(flag_for_filter_brand);
$sql="SELECT DISTINCT * FROM products WHERE brand IN('$brand_str')";
else
$sql="SELECT DISTINCT * FROM products;
MY PROBLEM:
But this is also a big problem because my code become so large because there are two three where clauses as below
$sql="SELECT DISTINCT * FROM products WHERE brand IN('$brand_str') and Quantity IN ($var2) and type IN($var3)";
how to solve this in a optimal way?
Any suggestion or help is appreciated
Put each of your WHERE conditions in an array. Then test whether the array contains anything.
$wheres = array();
if(isset($_GET['brand']) && !empty($_GET['brand']))
$brand=$_GET['brand'];
$brand_str = implode("' , '",$brand);
$wheres[] = "brand IN ('$brand_str')";
}
if(isset($_GET['quantity']) && !empty($_GET['quantity']))
$quant=$_GET['quantity'];
$quant_str = implode("' , '",$quant);
$wheres[] = "Quantity IN ('$quant_str')";
}
// Repeat this for other conditions
if (!empty($wheres)) {
$where_str = "WHERE " . implode(' AND ', $wheres);
} else {
$where_str = "";
}
$sql = "SELECT DISTINCT * FROM Products $where_str";
If you have lots of conditions, you can put the names of the fields in an array, and then make the first part of this answer into a loop:
$fields = array('brand', 'quantity', 'type', ...);
foreach ($fields as $field) {
if (!empty($_GET[$field])) {
$field_str = implode("' , '", $_GET[$field]);
$wheres[] = "$field IN ('$field_str')";
}
}
Put all parts of your WHERE condition in an array.
$where = array();
if(isset($_GET['brand']) && !empty($_GET['brand']))
$brand_str = implode("' , '", $_GET['brand']);
$where[] = "brand IN('$brand_str')";
}
...
then test if array is not empty
if (!empty($where)) {
$sql="SELECT DISTINCT * FROM products WHERE " . implode (' AND ', $where);
} else {
$sql="SELECT DISTINCT * FROM products";
}
Just use 1 as WHERE value:
$brandArray = $_GET['brand']; // with empty(), isset(), and other validation...
$quantityArray = $_GET['quantity']; // with empty(), isset(), and other validation...
$typeArray = $_GET['type']; // with empty(), isset(), and other validation...
$whereArray = array();
$whereArray['brand'] = !empty($brandArray) ? 'brand IN (' . implode(',', $brandArray) . ')' : 1;
$whereArray['quantity'] = !empty($quantityArray) ? 'quantity IN (' . implode(',', $quantityArray) . ')' : 1;
$whereArray['type'] = !empty($typeArray) ? 'type IN (' . implode(',', $typeArray) . ')' : 1;
$where = implode(' AND ', $whereArray);
if(flag_for_filter_brand);
$sql="SELECT DISTINCT * FROM products WHERE brand IN('$brand_str')";
else
$sql="SELECT DISTINCT * FROM products;
$sql = <<<SQL
SELECT
DISTINCT *
FROM
products
WHERE
$where
;
SQL>>>;
That's just one possibility to handle this. Actually this code should be separated infor classes and methods or at least to some functions.
One way would be to put the queries in a function and call that function inside your if
if(isset($_GET['brand']) && !empty($_GET['brand'])) {
$brand=$_GET['brand'];
$brand_str = implode("' , '",$brand);
if !empty($brand_str)
myQueries( $brand_str );
}
function myQueries( $brand_str ) {
// execute your queries
}
Another option is if your script is doing only that to exit if your string is empty.
if(isset($_GET['brand']) && !empty($_GET['brand'])) {
$brand=$_GET['brand'];
$brand_str = implode("' , '",$brand);
if empty( $brand_str )
exit;
}
myQueries( $brand_str );

Categories