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();
Related
I need a return array in function. When i was use that returning this Array ( ):
function menuOlustur($ana_kategoriler){
global $db;
$alt_kategori_durum = '';
$alt_kategori;
foreach ($ana_kategoriler as $kategori) {
$alt_kategori = $db->rawQuery('select * from s_kategoriler where kategori = ' . $kategori['id'] . ' and durum=1 order by sira asc');
}
return $alt_kategori;
}
and i was use this returning one more index in array.
function menuOlustur($ana_kategoriler){
global $db;
$alt_kategori_durum = '';
$alt_kategori;
foreach ($ana_kategoriler as $kategori) {
$alt_kategori[] = $db->rawQuery('select * from s_kategoriler where kategori = ' . $kategori['id'] . ' and durum=1 order by sira asc');
}
return $alt_kategori;
}
My $ana_kategoriler is an array its a calling query like that
$ana_k_cek = $db->rawQuery('select id, kategori, adi_' . $dil . ' as adi,link_' . $dil . ' as link from s_kategoriler where m_id=5 and durum=1 order by sira asc ');
whats can i do ?
EDIT: fixed query, should not be kategori = 1,2,3,4, but kategory IN(1,2,3,4)
I suggest to change your code to:
function menuOlustur($ana_kategoriler){
global $db;
/* first - collect all ids */
$ids = array();
foreach ($ana_kategoriler as $kategori) {
$ids[] = $kategori['id'];
}
/* return empty array if there is no ids, or return result of single query matching all results with given ids */
return count($ids) > 0 ? $db->rawQuery('select * from s_kategoriler where kategori IN( ' . implode(",",$ids) . ') AND durum=1 order by sira asc') : array();
}
I have this HTML form which has so many fields that someone can use to query data from MySQL table using multiple conditions. The form has select boxes, text boxes and check boxes, and date inputs.
I have this function which is ineffective
public function search(Request $request)
{
// loop through the defined fields
foreach($this->fields as $field){
// if the field is set and not empty
if(is_array($request->get($field))){
foreach ($request->get($field) as $value) {
$this->conditions[] = "`$field` = '" . $value . "'";
}
} else {
if(isset($_POST[$field]) && $request->get($field) != '') {
$data = $request->get($field);
if($field == 'bf_ref_no'){
$data = is_numeric( substr($request->get($field), 0, 2) ) ? 'BF'.$request->get($field) : $request->get($field) ;
}
$this->conditions[] = "`$field` = '" . $data . "'";
}
}
}
// builds the query
$query = "SELECT invoices.id as inv_id, invoices.created_at as inv_date, invoices.amount_paid, invoices.amount, csv_data_final.* FROM csv_data_final
LEFT JOIN invoices ON invoices.parent_id = csv_data_final.id ";
// if there are conditions defined
if(count($this->conditions) > 0) {
// append the conditions
$query .= "WHERE " . implode (' AND ', $this->conditions); // you can change to 'OR', but I suggest to apply the filters cumulative
}
$results = DB::select( $query );
$borders = DB::table('borders')->orderBy('id', 'DESC')->get();
return view('track.track-withdata', compact('results', 'borders'));
}
This code doesn't work for dates using BETWEEN keyword.
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 );
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;
}
Problem:
I am trying to delete all sublevels of a category by using a class. Currently I can only make it delete two sublevels, not three.
The database table:
CREATE TABLE betyg_category (
CID int(11) NOT NULL AUTO_INCREMENT,
Item varchar(100) NOT NULL,
Parent int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (CID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The PHP class:
<?php
class ItemTree
{
var $itemlist = array();
function ItemTree($query)
{
$result = mysql_query($query) or die ('Database Error (' . mysql_errno() . ') ' . mysql_error());
while ($row = mysql_fetch_assoc($result))
{
$this->itemlist[$row['CID']] = array(
'name' => $row['Name'],
'parent' => $row['Parent']
);
}
}
function get_tree($parent, $with_parent=0)
{
$item_tree = array();
if ($with_parent == 1 && $parent != 0)
{
$item_tree[$parent]['name'] = $this->itemlist[$parent]['name'];
$item_tree[$parent]['parent'] = $this->itemlist[$parent]['parent'];
$item_tree[$parent]['child'] = $this->get_tree($parent);
return $item_tree;
}
foreach ($this->itemlist as $key => $val)
{
if ($val['parent'] == $parent)
{
$item_tree[$key]['name'] = $val['name'];
$item_tree[$key]['parent'] = $val['parent'];
$item_tree[$key]['child'] = $this->get_tree($key);
}
}
return $item_tree;
}
function make_optionlist ($id, $class='', $delimiter='/')
{
$option_list = '';
$item_tree = $this->get_tree(0);
$options = $this->make_options($item_tree, '', $delimiter);
if (!is_array($id))
{
$id = array($id);
}
foreach($options as $row)
{
list($index, $text) = $row;
$selected = in_array($index, $id) ? ' selected="selected"' : '';
$option_list .= "<option value=\"$index\" class=\"$class\"$selected>$text</option>\n";
}
return $option_list;
}
function make_options ($item_tree, $before, $delimiter='/')
{
$before .= empty($before) ? '' : $delimiter;
$options = array();
foreach ($item_tree as $key => $val)
{
$options[] = array($key, '- '.$before.$val['name']);
if (!empty($val['child'])) {
$options = array_merge($options, $this->make_options($val['child'], $before.$val['name'], $delimiter));
}
}
return $options;
}
function get_navlinks ($navid, $tpl, $startlink='', $delimiter=' ยป ')
{
// $tpl typ: {name}
$search = array('{id}', '{name}');
$navlink = array();
while (isset($this->itemlist[$navid]))
{
$replace = array($navid, $this->itemlist[$navid]['name']);
$navlink[] = str_replace($search, $replace, $tpl);
$navid = $this->itemlist[$navid]['parent'];
}
if (!empty($startlink))
{
$navlink[] = str_replace($search, array(0, $startlink), $tpl);
}
$navlink = array_reverse($navlink);
return implode($delimiter, $navlink);
}
function show_tree ($parent=0, $tpl='%s', $ul_class='', $li_class='')
{
$item_tree = $this->get_tree($parent);
return $this->get_node($item_tree, $parent, $tpl, $ul_class, $li_class);
}
function get_node ($item_tree, $parent, $tpl, $ul_class, $li_class)
{
// $tpl typ: {name}
$search = array('{id}', '{name}');
$output = "\n<ul class=\"$ul_class\">\n";
foreach ($item_tree as $id => $item)
{
$replace = array($id, $item['name']);
$output .= "<li class=\"$li_class\">".str_replace($search, $replace, $tpl);
$output .= !empty($item['child']) ? "<br />".$this->get_node ($item['child'], $id, $tpl, $ul_class, $li_class) : '';
$output .= "</li>\n";
}
return $output . "</ul>\n";
}
function get_id_in_node ($id)
{
$id_list = array($id);
if (isset($this->itemlist[$id]))
{
foreach ($this->itemlist as $key => $row)
{
if ($row['parent'] == $id)
{
if (!empty($row['child']))
{
$id_list = array_merge($id_list, get_id_in_node($key));
} else
{
$id_list[] = $key;
}
}
}
}
return $id_list;
}
function get_parent ($id)
{
return isset($this->itemlist[$id]) ? $this->itemlist[$id]['parent'] : false;
}
function get_item_name ($id)
{
return isset($this->itemlist[$id]) ? $this->itemlist[$id]['name'] : false;
}
}
?>
Scenario:
Say you have the following structure in a :
Literature
-- Integration of sources
---- Test 1
It will result in the following in the database table:
When I try to delete this sublevel, it will leave the last sublevel in the database while it should delete it. The result will be:
The PHP code:
//Check if delete button is set
if (isset($_POST['submit-deletecategory']))
{
//Get $_POST variables for category id
$CategoryParent = intval($_POST['CategoryList']);
//Check if category is selected
if ($CategoryParent != "#")
{
//Get parent category and subsequent child categories
$query = "SELECT CID, Item AS Name, Parent FROM " . TB_CATEGORY . " ORDER BY Name";
$items = new ItemTree($query);
if ($items->get_item_name($_POST['CategoryList']) !== false)
{
//Build up erase list
$CategoryErase = $items->get_id_in_node($CategoryParent);
$CategoryEraseList = implode(", ", $CategoryErase);
}
else
{
$CategoryEraseList = 0;
}
//Remove categories from database
$query = "DELETE FROM " . TB_CATEGORY . " WHERE CID IN ($CategoryEraseList)";
$result = mysql_query($query) or die ('Database Error (' . mysql_errno() . ') ' . mysql_error());
//Return a confirmation notice
header("Location: settings.php");
exit;
}
}
Thank you in advance for any guidance I can get to solve the issue.
Here is a way to do it : use a recursive function, which will first look for the leaf item (the deepest in your tree). You remove children first, then the parent. And for each child, you remove child's children first, etc...
deleteSub(1);
function deleteSub($cat_id) {
$request = "SELECT * FROM ". TB_CATEGORY ." WHERE Parent = ".$cat_id;
$results = mysql_query($request);
while($child = mysql_fetch_array($results))
{
deleteSub($child["CID"]);
}
$request = "DELETE FROM ". TB_CATEGORY ." WHERE CID = ".$cat_id;
return mysql_query($request);
}
A better way could be use this kind of recursive function to store CIDs in an array, then make a single DELETE request, but I think you'll be able to adapt this code.
I'm not going to read or try to understand the entire code, but it seems to me you need some sort of recursion function. What I basicly would do is create a function that goes up in the hierachy and one that goes down.
Note: It has been a while since i've written anything in procedural mysql, so please check if the mysql_num_rows(),mysql_fetch_array and so on is written in the correct manner
EDIT: I've just noticed you only wanted a downwards deletion and therefore zessx's answer is more valid
<?php
function recursiveParent($id) {
$sql = 'SELECT parent FROM betyg_category WHERE CID=' . $id;
$result = mysql_query($sql);
if(mysql_num_rows($result) > 0) {
while($r = mysql_fetch_array($result,MYSQLI_ASSOC)) {
recursiveParent($r['parent']);
}
}
$sql = 'DELETE FROM betyg_category WHERE CID=' . $id;
mysql_query($sql);
}
function recursiveChild($parent) {
$sql = 'SELECT CID FROM betyg_category WHERE parent=' . $parent;
$result = mysql_query($sql);
if(mysql_num_rows($result) > 0) {
while($r = mysql_fetch_array($result,MYSQLI_ASSOC)) {
recursiveChild($r['CID']);
}
}
$sql = 'DELETE FROM betyg_category WHERE parent=' . $parent;
mysql_query($sql);
}
function delete($id) {
recursiveParent($id);
recursiveChild($id);
}
?>
This is my way to do. instead of recursive the query to run, i get all the child's id first then only run query. here the code refer:-
First, defined a variable called $delete_node_list as array. (to store all node id that need to be delete)
function delete_child_nodes($node_id)
{
$childs_node = $this->edirectory_model->get_child_nodes($node_id);
if(!empty($childs_node))
{
foreach($childs_node as $node)
{
$this->delete_child_nodes($node['id']);
}
}
$this->delete_node_list[] = $node_id;
}
in mysql..
$sql = 'DELETE FROM betyg_category WHERE CID IN '.$this->delete_node_list;
mysql_query($sql);