PHP function for looping variable - php

I have this coding :
foreach ($users_id_array[REGION_NORTH_REFID][813] as $key) {
$query_course = "SELECT ut_lp_marks.obj_id, object_data.title, read_event.spent_seconds, " .
"read_event.read_count, ut_lp_marks.status, ut_lp_marks.percentage, ut_lp_marks.u_comment FROM ut_lp_marks ".
"LEFT JOIN object_data ON (object_data.obj_id = ut_lp_marks.obj_id) ".
"LEFT JOIN read_event ON (read_event.obj_id = object_data.obj_id AND read_event.usr_id = ut_lp_marks.usr_id) ".
"WHERE ut_lp_marks.usr_id=$key AND object_data.type = 'crs'";
$set_course = mysql_query($query_course);
while($rec_course = mysql_fetch_assoc($set_course))
{
if ($rec_course['status'] == 0) {
$total_regna++;
}
if ($rec_course['status'] == 1) {
$total_reginprogress++;
}
if ($rec_course['status'] == 2) {
$total_regpassed++;
}
if ($rec_course['status'] == 3) {
$total_regfailed++;
}
// $total_attempt = $total_attempt + $rec_course['read_count'];
// $total_spent = $total_spent + $rec_course['spent_seconds'];
}
$no_test++;
}
the variable that i used is for each :
813, 945, 835, 777
My problems is my coding right now is only for 1 variable.
How can i used this same code for different variable,do i need to make array or a function? How can i access .. different $total_regna++; $total_reginprogress++; $total_regpassed++; $total_regfailed++; if i am using 1 code for 4 variable?..

You can make an array of these values such as
$values = array('813','945','835','777');
and instead of using for each, you can implode this array values in query.
$query_course = "SELECT ut_lp_marks.obj_id, object_data.title, read_event.spent_seconds, " .
"read_event.read_count, ut_lp_marks.status, ut_lp_marks.percentage, ut_lp_marks.u_comment FROM ut_lp_marks ".
"LEFT JOIN object_data ON (object_data.obj_id = ut_lp_marks.obj_id) ".
"LEFT JOIN read_event ON (read_event.obj_id = object_data.obj_id AND read_event.usr_id = ut_lp_marks.usr_id) ".
"WHERE ut_lp_marks.usr_id in (".implode(',',$values).") AND object_data.type = 'crs'";
Now while loop will be same.
I think it will be good in your case.

$ids=array(813, 945, 835, 777);
for ($i=0;$i<4;$i++){
foreach ($users_id_array[REGION_NORTH_REFID][$ids[$i]] as $key) {
...

Related

Multiple nested array from MySQL query in PHP

I'm using foreach loops to access records in a nested array.
I need to nest 3 arrays (so the first array contains an array, which also contains an array). I'm having success with 2 arrays but I can't get 3 to work.
I had my code working with 2 arrays (which worked just fine) but I can't get 3 arrays to be nested.
This is the result that I want:
[
{
"site_id": "1",
"user_plants": [
{
"user_plant_id": "1",
"site_id": "1",
"plant_id": "1",
"plant_images": [
{
"plant_image_id": "1"
},
{
"plant_image_id": "2"
},
{
"plant_image_id": "3"
},
]
}
]
}
]
My current code:
$query = "SELECT A.site_id FROM sites A WHERE A.user_id='".$user_id."' GROUP BY A.site_id";
$result = $this->conn->query($query);
$json_response = array();
$sites = array();
if ($result-> num_rows > 0) {
while ($item = $result->fetch_object())
$sites[] = $item;
foreach($sites as $item) {
$row_array = (array)$item;
$site_id = $item->site_id;
$user_plants = "SELECT A.user_plant_id, A.site_id, A.plant_id FROM user_plants A RIGHT JOIN sites B ON A.site_id ='".$site_id."'
JOIN plants C ON A.plant_id = C.plant_id GROUP BY A.user_plant_id";
$resultSet = $this->conn->query($user_plants);
$user_plants = array();
if ($resultSet-> num_rows > 0) {
while ($item = $resultSet->fetch_object())
$user_plants[] = $item;
foreach ($user_plants as $item) {
$row_array['user_plants'][] = (array)$item;
$plant_id = $item->plant_id;
$user_plant_id = $item->user_plant_id;
$plant_images = "SELECT A.plant_image_id FROM plants_images A WHERE A.plant_id ='".$plant_id."' UNION SELECT B.plant_image_id FROM user_plant_image B JOIN user_plants C ON B.user_plant_id ='".$user_plant_id."' WHERE C.user_id ='".$user_id."' GROUP BY B.plant_image_id ORDER BY plant_image_id";
$resultSet = $this->conn->query($plant_images);
$plant_images = array();
if ($resultSet->num_rows > 0) {
while ($item = $resultSet->fetch_object())
$plant_images[] = $item;
foreach ($plant_images as $item) {
$row_array['user_plants'][]['plant_images'][] = $item;
}
} else if ($resultSet->num_rows == 0) {
$row_array['plant_images'] = [];
}
}
$json_response[] = $row_array;
}
}
}
return $json_response;
The result of above code:
[
{
"site_id": "1",
"user_plants": [
{
"user_plant_id": "1",
"site_id": "1",
"plant_id": "1"
},
{
"plant_images": [
{
"plant_image_id": "1"
},
{
"plant_image_id": "2"
},
{
"plant_image_id": "3"
},
]
}
]
}
]
How should I adjust the foreach loops above to cater for this?
There's plenty of room for improvement in this code but I've ignored that and tried to keep the code matching yours in this example.
The main changes are:
Create a temporary variable $user_plant_array which we store "plant_images" against
Push that temporary variable to the $site_array at the end of the loop
Rename some loop variables to making it easier to identify what you're referencing
$json_response = array();
$sites = array();
if ($result->num_rows > 0) {
while ($site = $result->fetch_object()) {
$sites[] = $site;
}
foreach ($sites as $site) {
$site_array = (array)$site;
$site_id = $site->site_id;
$user_plants = "SELECT A.user_plant_id, A.site_id, A.plant_id FROM user_plants A RIGHT JOIN sites B ON A.site_id ='" . $site_id . "'
JOIN plants C ON A.plant_id = C.plant_id GROUP BY A.user_plant_id";
$resultSet = $this->conn->query($user_plants);
$user_plants = array();
if ($resultSet->num_rows > 0) {
while ($user_plant = $resultSet->fetch_object())
$user_plants[] = $user_plant;
foreach ($user_plants as $user_plant) {
// create a temporary variable here that we will map
// all "plant_images" to
$user_plant_array = (array)$user_plant;
$plant_id = $user_plant->plant_id;
$user_plant_id = $user_plant->user_plant_id;
$plant_images = "SELECT A.plant_image_id FROM plants_images A WHERE A.plant_id ='" . $plant_id . "' UNION SELECT B.plant_image_id FROM user_plant_image B JOIN user_plants C ON B.user_plant_id ='" . $user_plant_id . "' WHERE C.user_id ='" . $user_id . "' GROUP BY B.plant_image_id ORDER BY plant_image_id";
$resultSet = $this->conn->query($plant_images);
$plant_images = array();
if ($resultSet->num_rows > 0) {
while ($plant_image = $resultSet->fetch_object())
$plant_images[] = $plant_image;
foreach ($plant_images as $plant_image) {
$user_plant_array['plant_images'][] = $plant_image;
}
} else if ($resultSet->num_rows == 0) {
$user_plant_array['plant_images'] = [];
}
// the temporary variable now contains all "plant_images"
// now we can push that to the site array
$site_array['user_plants'][] = $user_plant_array;
}
$json_response[] = $site_array;
}
}
}
return $json_response;
Creating a separate answer as an alternate solution with some code improvements.
"Improvements" being more readability and/or more performant.
A few of the main changes I would suggest as "improvements" have been implemented in this example. The main ones being:
Using prepared SQL statements (not always required but good practice to use, especially in anything accepting user input, also can make for cleaner code)
Reducing the amount of loops (in a few places you were looping just to create an array and then looping again)
Returning/continuing early where possible (helps to prevent unnecessary nesting)
Removing unnecessary if statements (e.g. most of the while loops will be skipped if the results are empty - checking beforehand isn't entirely necessary)
More readable variable names (it's common for new coders to try and abbreviate a lot of variables and often take it too far - making them readable will save you a lot of time when debugging)
The code using mysqli might not be the best as I generally work with PDO.
function getSitesData() {
// assumes that $user_id is set somewhere before this
// assumes that $this->conn references a valid database connection
$sql = "SELECT A.site_id FROM sites A WHERE A.user_id = ? GROUP BY A.site_id";
$query = $this->conn->prepare($sql);
$query->bind_param("i", $user_id);
$query->execute();
$site_result = $query->get_result();
$sites = [];
while ($site = $site_result->fetch_assoc()) {
// using fetch_assoc gives us an associative array
// initialise empty array
$site["user_plants"] = [];
// get user_plants
$sql = "SELECT A.user_plant_id, A.site_id, A.plant_id FROM user_plants A RIGHT JOIN sites B ON A.site_id = ?
JOIN plants C ON A.plant_id = C.plant_id GROUP BY A.user_plant_id";
$query = $this->conn->prepare($sql);
$query->bind_param("i", $site["site_id"]);
$query->execute();
$user_plant_result = $query->get_result();
while ($user_plant = $user_plant_result->fetch_assoc()) {
// intialise empty array
$user_plant["plant_images"] = [];
// get plant images
$sql = "SELECT A.plant_image_id FROM plants_images A WHERE A.plant_id = ? UNION SELECT B.plant_image_id FROM user_plant_image B JOIN user_plants C ON B.user_plant_id = ? WHERE C.user_id = ? GROUP BY B.plant_image_id ORDER BY plant_image_id";
$query = $this->conn->prepare($sql);
$query->bind_param("iii", $user_plant["plant_id"], $user_plant["user_plant_id"], $user_id);
$query->execute();
$plant_image_result = $query->get_result();
while ($plant_image = $plant_image_result->fetch_assoc()) {
$user_plant["plant_images"][] = $plant_image;
}
$sites["user_plants"][] = $user_plant;
}
$sites[] = $site;
}
return $sites;
}

ext js store/model example .net -converting php/mysql to .netwebservier/sql

Afternoon all,
I am working through a tutorial from MASTERING EXT JS and am stuck on retrieving data from db.
The book has been using examples using PHP and MYSQL... which I do not know. I use a .net web server and SQL, so I'm trying to convert this example from the tutorial, to how I would do it on my .net webserver.
the result in JSON format should be something like this
{
"data"[
{
"id":1",
"text" : "menu1",
"items": [
{"id": 2",
"text: "submenu2
},
{
"id":"3",
"text":"submenu3"
}
the php code they give me is this
php file 1
$permissions = retrievePermissions($userName); $modules =
retrieveModules($permissions); $result = retrieveMenuOptions($modules,
$permissions);
php file 2
function retrievePermissions($userName){
require('../db/db.php');
$sqlQuery = "SELECT p.menu_id menuId FROM User u ";
$sqlQuery .= "INNER JOIN permissions p ON u.groups_id = p.groups_id ";
$sqlQuery .= "INNER JOIN menu m ON p.menu_id = m.id ";
$sqlQuery .= "WHERE u.username = '$userName' ";
$permissions = [];
if ($resultDb = $mysqli->query($sqlQuery)) {
while($user = $resultDb->fetch_assoc()) {
$permissions[] = $user['menuId'];
}
}
$resultDb->free();
$mysqli->close();
return $permissions; }
function retrieveModules($permissions){
require('../db/db.php');
$inClause = '(' . join(',',$permissions) . ')';
$sqlQuery = "SELECT id, text, iconCls FROM menu WHERE menu_id IS NULL AND id in $inClause";
$modules = [];
if ($resultDb = $mysqli->query($sqlQuery)) {
while($module = $resultDb->fetch_assoc()) {
$modules[] = $module;
}
}
$resultDb->free();
$mysqli->close();
return $modules; }
function retrieveMenuOptions($modules, $permissions){
require('../db/db.php');
$inClause = '(' . join(',',$permissions) . ')';
$result = [];
foreach ($modules as $module) {
$sqlQuery = "SELECT * FROM menu WHERE menu_id = '";
$sqlQuery .= $module['id'] ."' AND id in $inClause";
// check if have a child node
if ($resultDb = $mysqli->query($sqlQuery)) {
// determine number of rows result set
$count = $resultDb->num_rows;
if ($count > 0){
$module['items'] = array();
while ($item = $resultDb->fetch_assoc()) {
$module['items'][] = $item;
}
}
$result[] = $module;
}
}
$resultDb->close();
$mysqli->close();
return $result;
I'm trying to figure out how to return the same json format using my .net webservice/SQL instead of php/MySQL.
It seems like it does 3 separate functions. And the result array is used as a parameter for the next query.
The basics seem easy... like for retreivePermissions... it is a simple SELECT WHERE statement.
retrieveModules seems to be an INNER JOIN with the first results.
But the last one... retrieveMenuOptions, it pulls in both results as parameters, and It returns results.
That is what I don't understand... how can I pull the results from SQL in the same JSON result format.
Am I making sense?
I have an example that uses a .NET Web API controller. Not exactly a web service, but you'll get the idea. Check it out here: http://jorgeramon.me/2015/ext-js-grid-search-with-net-and-mysql-backend/

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 );

PHP while loop within a while loop works once

I have two queries sent to a database bring back posts (op_ideas 16 cols) followed by another which holds the votes per post (op_idea_vote cols 4) with matching idea_id's
Example of Data:
Query: op_ideas:
[{"idea_id":"2211","author_id":"100000", "date":"2012-09-06
10:02:28","idea_title":"Another test","4" etc etc
Query: op_idea_votes:
idea_id = 2211, agree=3, disagree=1, abstain=0
The code below ought to look at op_ideas, and then cycle over op_ideas_vote until it finds a match under 'idea_id'. Then it goes to the next record under op_ideas, and again using that idea_id search for it within the op_idea_vote list, find a match, and add it to the array.
This works for only the first record, not for the other three. I am testing, so I have 3 rows in each that match idea_id with different results in the op_idea_vote.
$votes = mysql_query($commentVotes);
$result = mysql_query($gl_query);
while ($gce_result = mysql_fetch_array($result)) {
$voteid = $gce_result['idea_id'];
while($allvotes= mysql_fetch_array($votes)) {
if($voteid = $allvotes['idea_id'])
{
//echo $voteid . " main idea and the votes: " . $allvotes;
$gce_result["agree"] = $allvotes['agree'];
$gce_result["disagree"] = $allvotes['disagree'];
$gce_result["abstain"] = $allvotes['obstain'];
}
else
{
$gce_result["agree"] = 0;
$gce_result["disagree"] = 0;
$gce_result["abstain"] = 0;
}
//print_r($gce_result);
}
$data_result[] = $gce_result;
}
echo json_encode($data_result);
If I use print_f(&gce_result) it works fine in phpfiddle. But when i use the code above, it works for the first record, but it's complete missing the second two. It seems to be missing the second while, as it does not even give me the 0 0 0 results.
Query for op_ideas:
$gl_query = "SELECT DISTINCT * FROM heroku_056eb661631f253.op_ideas INNER JOIN op_organs ORDER BY date ASC;";
if (!mysql_query($gl_query)) {
die('Error: ' . $gl_query . " " . mysql_error());
}
$result = mysql_query($gl_query);
Query For op_idea_vote :
$commentVotes = "SELECT v.idea_id, COUNT(v.agree = 1 or null) as agree, COUNT(v.disagree = 1 or null) as disagree, COUNT(v.obstain = 1 or null) as obstain FROM op_idea_vote v GROUP BY v.idea_id";
if (!mysql_query($commentVotes)) {
die('Error: ' . $commentVotes . " " . mysql_error());
}
$votes = mysql_query($commentVotes);
You can scan a resource only once.
So the inner while will be run only one time.
use == instead of = for checking condition of if & while
in the while loop ,you have to assign the value of $allvotes ,but you never assigned,
while ($gce_result == mysql_fetch_array($result)) {
$voteid = $gce_result['idea_id'];
while($allvotes== mysql_fetch_array($votes)) {
if($voteid == $allvotes['idea_id'])
{
//echo $voteid . " main idea and the votes: " . $allvotes;
$gce_result["agree"] = $allvotes['agree'];
$gce_result["disagree"] = $allvotes['disagree'];
$gce_result["abstain"] = $allvotes['obstain'];
}
else
{
$gce_result["agree"] = 0;
$gce_result["disagree"] = 0;
$gce_result["abstain"] = 0;
}
$data_result[] = $gce_result;
}
}
Your problem is trying to scan over the $votes result more than once.
You should store the result of that query first.
Eg.
while ($vote = mysql_fetch_array($votes)) {
$allvotes['idea_id'] = $vote;
}
while ($gce_result = mysql_fetch_array($result)) {
$voteid = $gce_result['idea_id'];
if (array_key_exists[$voteid, $allvotes]) {
//assign results
} else {
//default
}
}
Another option would be to do the query with a join, so you can do everything in one query. Then just loop over that result.

Handling a bunch of various requests into the database

I currently have a php page that grabs information from a database and produces HTML with data attributes that are filled in by from the MySQL query. The database is going to be used to search, with many different options for searches.
What I need help with is knowing a way so to organize how the many variables are handled. It's a really big mess of code, and even with all the comments I put it gives me a headache trying to figure out how to add another variable to the search.
All the variables, except for the LIMIT to which row and how many results, are optional. So if someone leaves everything except that blank, I still want it to function as well as if they meticulously filled in all the fields.
Here's what I have, with 6 variables.
<?php
$product_size = "(".$_GET['size']." BETWEEN productsizeDOWN AND productsizeUP)"; // This code sets the variable to input into the MySQL string based on the URL
$product_size_check = $_GET['size']; // the _checks check are used to see if the value is or isn't empty using if statements below
$manufacturer = $_GET['manufacturer'];
$product_manufacterer_check = $_GET['manufacturer']; // _check
$product_invisible = "(hideproduct = '".$_GET['invisible']."')"; // Checks if product is hidden
$product_invisible_check = $_GET['invisible']; // _check
$product_instock_check = $_GET['instock']; // _check
$product_limit0 = $_GET['startat']; // This is the first number after LIMIT; the row to start in.
$product_limit1 = $_GET['results']; // This is how many results to load.
$manufacturer_array = explode(",", $manufacturer); // The manufacturer comes in as "Nike,Addidas,Rebok" and is turned into an array
$manufacturer_imploded = implode("' OR productmanufacturer = '", $manufacturer_array); // Puts it back together with "OR productmanufacturer =" between each name.
$product_manufacterer = ("(productmanufacturer = '".$manufacturer_imploded."')"); // formats it so it can be directly inserted into MySQL string with a WHERE in front.
if($product_invisible_check == ""){
$product_invisible = "";
}else{$where = "WHERE ";}; //Useless code that I havn't deleted that I tried to use when I searched the entire database
if($product_size_check == ""){
$product_size = "";
}else{$where = "WHERE ";};
if($product_manufacterer_check == ""){
$product_manufacterer = "";
}else{$where = "WHERE ";};
if($product_instock_check == "N"){
$product_instock = "(stockstatus <= '0' AND donotallowbackorders = 'Y') AND "; // Checks if product is in stock (Allowing backordering OR stock >1)
$where = "WHERE ";
}
elseif($product_instock_check == "Y") {
$product_instock = "(stockstatus > '0' OR donotallowbackorders = 'N') AND ";
$where = "WHERE ";
}
else {
$product_instock = "";
};
$sql="Select * FROM ioa7pd_Products WHERE ".$product_instock.$product_size."AND".$product_manufacterer_and.$product_manufacterer."".$product_invisible." LIMIT ".$product_limit0.", ".$product_limit1; // The end result of it all.
echo $sql;
?>
When the URL is
test.php?size=5&manufacturer=Nike,Addidas,Rebok&invisible=N&instock=Y&startat=0&results=30
the resulting SQL query is
Select * FROM ioa7pd_Products WHERE (stockstatus > '0' OR donotallowbackorders = 'N') AND (5 BETWEEN productsizeDOWN AND productsizeUP)AND(productmanufacturer = 'Nike' OR productmanufacturer = 'Addidas' OR productmanufacturer = 'Rebok')(hideproduct = 'N') LIMIT 0, 30
But I plan to add more options to the search.
My main question is simply: What way can I organize this to make it simple to add more variables? Tiered if statements?
Travesty has been helping me with my code and has really been great in organizing it.
Here is the current code. It needs to be secure to prevent injection.
// Database connection
$con = mysql_connect("[CENSORED]","[CENSORED]","[CENSORED]")
or die("Could not connect: " . mysql_error());
mysql_select_db("[CENSORED]") or die('Could not select database');
// Begin organization of URL variables into MYSQL Query
$get_size = $_GET['size'];
$get_manufacturer = $_GET['manufacturer'];
$get_invisible = $_GET['invisible'];
$get_instock = $_GET['instock'];
$get_sex = $_GET['sex'];
$get_startat = $_GET['startat'];
$get_results = $_GET['results'];
if ($get_size != ""){
$all_selectors[] = "(".$get_size." BETWEEN productsizeDOWN AND productsizeUP)"; // Add to array if size is not blank.
};
if ($get_manufacturer != ""){
$manufacturer_exploded = explode(",", $get_manufacturer);
$manufacturer_imploded = implode("' OR productmanufacturer = '", $manufacturer_exploded);
$all_selectors[] = ("(productmanufacturer = '".$manufacturer_imploded."')");
};
if ($get_invisible != ""){
$all_selectors[] = "(hideproduct = '".$get_invisible."')";
};
if($get_instock == "N" or $get_instock == "n"){
$all_selectors[] = "(stockstatus <= '0' AND donotallowbackorders = 'Y')";
}elseif($get_instock == "Y" or $get_instock == "y") {
$all_selectors[] = "(stockstatus > '0' OR donotallowbackorders = 'N')";
};
if ($get_startat != "" or $get_results != ""){
$number_results = "LIMIT ".$get_startat.", ".$get_results;
} else {
$number_results = "LIMIT 0, 15";
};
// All variables are now in an array, except "startat" and "results"
$all_selectors0 = "WHERE ".implode(" AND ", $all_selectors);
// Create SQL query
$sql="Select * FROM sadsads_Products ".$all_selectors0." ".$number_results;
I would do something more like this. It's not tested and probably not 100% complete...you may need to do some further customization, particularly with adding more special cases to the switch statement, but this will make adding more variables much easier:
REMOVED OLD EXAMPLE, SEE UPDATED EXAMPLE BELOW
One key thing to note is that you aren't sanitizing your database inputs. Your code is vulnerable to SQL injection. My example above helps to solve that, but this code isn't fully tested, so you should ensure that all user input is sanitized before using it in any query.
If your field names don't match up with your MySQL columns (which it looks like they don't), then you can fix them with an associative array:
$columns = array(
// [form field] => [mysql column]
'size' => 'product_size',
'manufacturer' => 'product_manufacturer',
'invisible' => 'hideproduct'
// ...
);
And then in your switch statement, do something more like this:
$whereClause[] = "{$columns[$key]} = '{$value}'";
FINAL UPDATE:
DOCUMENTED SAMPLE - has plenty of comments and extra stuff to make it work on Codepad
EXACT WORKING CODE - you should be able to copy and paste this (and add your DB credentials) and it should work:
$con = mysqli_connect("[CENSORED]", "[CENSORED]", "[CENSORED]") or die("Could not connect: ". mysqli_error());
mysqli_select_db("[CENSORED]") or die("Could not select database");
$columns = array(
'size' => 'product_size',
'manufacturer' => 'product_manufacturer',
'invisible' => 'hideproduct'
);
$whereClause = array();
$limit = array("startat" => 0, "results" => 15);
foreach ($_GET as $key=>$value) {
$key = mysqli_real_escape_string($key);
if (is_array($value)) {
for ($i = 0; $i < count($value); $i++) {
$value[$i] = mysqli_real_escape_string($value[$i]);
}
} else {
$value = mysqli_real_escape_string($value);
}
switch ($key) {
case 'size':
$whereClause[] = "({$value} BETWEEN productsizeDOWN AND productsizeUP)";
break;
case 'startat':
case 'results':
$limit[$key] = $value;
break;
case 'instock':
$whereClause[] = "(stockstatus ". ($value == 'N' ? "<=" : ">") ." '0' ". ($value == 'N' ? "AND" : "OR") ." donotallowbackorders = '". ($value == 'N' ? "Y" : "N") ."')";
break;
default: {
if (is_array($value)) {
$whereClause[] = "{$columns[$key]} IN ('". implode("', '", $value) ."')";
} else {
$whereClause[] = "{$columns[$key]} = '{$value}'";
}
}
}
}
$sql = "SELECT * FROM ioa7pd_Products". (empty($whereClause) ? "" : " WHERE ". implode(" AND ", $whereClause)) ." LIMIT {$limit['startat']}, {$limit['results']}";
echo $sql;
after
else {
$product_instock = "";
};
do:
$limit = '';
if( !empty($product_limit0) && !empty($product_limit1) )
$limit = " LIMIT $product_limit0, $product_limit1";
$sql="Select * FROM ioa7pd_Products WHERE ".$product_instock.$product_size."AND".$product_manufacterer_and.$product_manufacterer."".$product_invisible." $limit"; // The end result of it all.
echo $sql;
If you have separate params in $_GET, you would have to traverse with multiple if statements. you can pass the params as an array into $_GET, with numeric keys, that would help a bunch.

Categories