if ($stmt - > execute()) {
if ($stmt - > rowCount() > 0) {
$menu_id = array();
while ($selected_row = $stmt - > fetch(PDO::FETCH_ASSOC)) {
$menu_id[] = array('menuid' => $selected_row['menulist_id'], );
}
$stmt = $dbh - > prepare("SELECT * FROM menulist_tbl WHERE menulist_id = :menuid AND menu_displayorder <= :value");
$menu_name = array();
$input = array_map("unserialize", array_unique(array_map("serialize", $menu_id)));
//print_r($menu_id);
//print_r($input);
foreach($input as $row) {
$stmt - > execute(array(':menuid' => $row['menuid'], ':value' => '10000'));
//while ($selected_row =$stmt->fetch(PDO::FETCH_COLUMN, 0)){
while ($selected_row = $stmt - > fetch(PDO::FETCH_ASSOC)) {
$menu_name[] = array('displayorder' => $selected_row['menu_displayorder'], 'menuname' => $selected_row['menu_name'], 'menuurl' => $selected_row['menu_url'], 'menuflag' => $selected_row['menu_flag'], 'menuid' => $selected_row['menulist_id']);
}
}
array_multisort($menu_name);
//print_r($menu_name);
return $menu_name;
}
}
This is how i get menu from database this code will do the following:
From result of another query it will store in an array the menulist_id then I will use this menulist_id to query the menu table for menu name that has a display order of less 10000 , I have this parameter of less than 10000 because i can hide menu from the list of menu without deleting them so I want to show them again I just reduce their display order and they can be seen again. But why is my display order parameter not working even if i have a display order of 10011 the menu is still showing. Any idea is appreciated
FYI
the column menu_displayorder is varchar.
For a varchar you will want to CAST as a numerical data type that can controlled better with >= try this:
AND CAST(menu_displayorder AS UNSIGNED) <= :value
Related
I'm trying to create a filter in DataTables, but what I found is only filtering the data in "front end" (in the datatables script). I have 10K rows in the SQL table so I think, the "front end filtering/searching" is not my best option. I need to create a filter to my SQL Query in server-side, and get back only the filtered rows (datas).
Also the search option is not good option for me because I have in tables values like 1 or 2 (boolean).
My DataTables using this method (way) of fetching datas from SQL in backend:
include 'config.php';
## Read value
$draw = $_POST['draw'];
$row = $_POST['start'];
$rowperpage = $_POST['length']; // Rows display per page
$columnIndex = $_POST['order'][0]['column']; // Column index
$columnName = $_POST['columns'][$columnIndex]['data']; // Column name
$columnSortOrder = $_POST['order'][0]['dir']; // asc or desc
$searchValue = $_POST['search']['value']; // Search value
$searchArray = array();
## Search
$searchQuery = " ";
if($searchValue != ''){
$searchQuery = " AND (emp_name LIKE :emp_name or
email LIKE :email OR
city LIKE :city ) ";
$searchArray = array(
'emp_name'=>"%$searchValue%",
'email'=>"%$searchValue%",
'city'=>"%$searchValue%"
);
}
## Total number of records without filtering
$stmt = $conn->prepare("SELECT COUNT(*) AS allcount FROM employee ");
$stmt->execute();
$records = $stmt->fetch();
$totalRecords = $records['allcount'];
## Total number of records with filtering
$stmt = $conn->prepare("SELECT COUNT(*) AS allcount FROM employee WHERE 1 ".$searchQuery);
$stmt->execute($searchArray);
$records = $stmt->fetch();
$totalRecordwithFilter = $records['allcount'];
## Fetch records
$stmt = $conn->prepare("SELECT * FROM employee WHERE 1 ".$searchQuery." ORDER BY ".$columnName." ".$columnSortOrder." LIMIT :limit,:offset");
// Bind values
foreach($searchArray as $key=>$search){
$stmt->bindValue(':'.$key, $search,PDO::PARAM_STR);
}
$stmt->bindValue(':limit', (int)$row, PDO::PARAM_INT);
$stmt->bindValue(':offset', (int)$rowperpage, PDO::PARAM_INT);
$stmt->execute();
$empRecords = $stmt->fetchAll();
$data = array();
foreach($empRecords as $row){
$data[] = array(
"emp_name"=>$row['emp_name'],
"email"=>$row['email'],
"gender"=>$row['gender'],
"salary"=>$row['salary'],
"city"=>$row['city']
);
}
## Response
$response = array(
"draw" => intval($draw),
"iTotalRecords" => $totalRecords,
"iTotalDisplayRecords" => $totalRecordwithFilter,
"aaData" => $data
);
echo json_encode($response);
In this code as you can see I have Search option, but as I said I can't use it for filtering columns with boolean values for example.
Another example what I want to do:
I have a column named by "edited" with boolean values.
How can I get those rows where the column "edited" have values 0?
I'm using MariaDB.
Thank you for your help!
You can easy write ...WHERE edited = :edited ... the value of edited should be 0 for false and 1 for true.
So in your example:
## Search
$searchQuery = " ";
if($searchValue != ''){
$searchQuery = " AND (emp_name LIKE :emp_name or
email LIKE :email OR
city LIKE :city ) AND
edited = :edited";
$searchArray = array(
'emp_name'=>"%$searchValue%",
'email'=>"%$searchValue%",
'city'=>"%$searchValue%",
'edited'=>$edited
);
}
The code below returns nothing, but if I remove this line:
'desc' => $row['DESC'],
from the function it works fine.
DESC Is a valid column in the database and when I run the full query in phpmyadmin, it returns the desired result.
I am not sure why this line
'desc' => $row['DESC'],
breaks the return of the result.
=======
After more investigating I can see the JSON output has the same issue.
Altering the column name (since DESC is a keyword) and reflecting the changes in the query has no effect.
========
function get_all_subjects($db1) {
$stmt = $db1->query("SELECT DISTINCT NAME, DESC, CLASSCODE FROM tbl_subjects WHERE VISIBLE = 1 ORDER BY NAME ASC");
$stmt->execute();
$count = $stmt->rowCount();
$column = array();
if ($count >0)
{
while($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
$column[] = array(
'name' => $row['NAME'],
'desc' => $row['DESC'],
'cc' => $row['CLASSCODE']
);
}
return json_encode(array('subjects' =>$column));
}
else
{
return $count;
}
}
DESC is a reserved word in SQL. If you want to use it as a column, you should protect it with forward quotes:
function get_all_subjects($db1) {
$stmt = $db1->query("SELECT DISTINCT NAME, `DESC` AS D, CLASSCODE FROM tbl_subjects WHERE VISIBLE = 1 ORDER BY NAME ASC");
$stmt->execute();
$count = $stmt->rowCount();
$column = array();
if ($count >0)
{
while($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
$column[] = array(
'name' => $row['NAME'],
'desc' => $row['D'], // Using the alias, just in case
'cc' => $row['CLASSCODE']
);
}
return json_encode(array('subjects' =>$column));
}
else
{
return $count;
}
}
DESC is a reserved Keyword do something like
SELECT DISTINCT NAME, DESC as yourVar, CLASSCODE FROM tbl_subjects WHERE VISIBLE = 1 ORDER BY NAME ASC
and then like that
'desc' => $row['yourVar'],
$stmt = $db1->query("SELECT DISTINCT `NAME`, `DESC`, `CLASSCODE` FROM `tbl_subjects` WHERE `VISIBLE` = 1 ORDER BY `NAME` ASC");
there was syntax error because desc is reserved keyword, you have to use quotes, the best habbit is quote each column and each table name
Thank you all for your answers - I found the problem and what broke the script was that my strings in my JSON values had several - in them.
It took me a while to find it :-)
I want to retrieve the data from db using PHP
$device_owner_resultset=mysqli_query($con, "SELECT * FROM `device_owner_details` WHERE `deviceId` =$device_details_data_id");
$device_owner_resultset_data = mysqli_fetch_array($device_owner_resultset);
$owner_deviceid = $device_owner_resultset_data['deviceId'];
$owner_name = $device_owner_resultset_data['name'];
$name_fetch_rows = mysqli_fetch_row($device_owner_resultset);
$device_realtime_resultset=mysqli_query($con, "SELECT * FROM `device_realtime_stats` WHERE `deviceId` = $owner_deviceid LIMIT $start_from , $limit");
$rows_fetch = mysqli_fetch_row($device_realtime_resultset);
if(($total_pages<=$page) &&( $total_pages>0))
{
$device_details=array('devices'=> array());
for($i=1;$i<=20;$i++)
{
$details =array('name' => $name_fetch_rows[$i]-> name, 'latitude' => $rows_fetch[$i] -> currentLatitude, 'longitude' => $rows_fetch[$i] -> currentLongitude);
array_push($device_details['devices'],$details);
}
$response = json_encode($device_details);
echo $response;
}
Here i have an parse error, what is the mistake from my coding , i think error is in mysqli_fetch_rows and its calling array
You are not using mysqli_fetch_row($result) correctly. The function mysqli_fetch_row($result) does not return all the row data. It returns an array of a single row as an enumerated array. Try this code using this code instead:
// Now only selects name column and added LIMIT 1 to MySQL query for efficiency
$device_owner_resultset = mysqli_query($con, "SELECT name FROM `device_owner_details` WHERE `deviceId` = $device_details_data_id LIMIT 1");
// Now using mysqli_fetch_assoc($result)
// instead of mysqli_fetch_array($result) for clarity
$device_owner_resultset_data = mysqli_fetch_assoc($device_owner_resultset);
// Got rid of $owner_deviceid because it should be the same as $device_details_data_id
$owner_name = $device_owner_resultset_data['name'];
// Got rid of $name_fetch_rows because it is redundant with $device_owner_resultset_data
// Query now specifies which columns it selects for clarity and efficiency
$device_realtime_resultset = mysqli_query($con, "SELECT currentLatitude, currentLongitude FROM `device_realtime_stats` WHERE `deviceId` = $device_details_data_id LIMIT $start_from, $limit");
if ($total_pages <= $page && $total_pages > 0) {
$device_details=array('devices'=> array());
// This loops through all the rows from the query
while ($row = mysqli_fetch_assoc($device_realtime_resultset)) {
// $row is an associative array where the column name is
// mapped to the column value.
// The owner name should remain the same because there is
// only one owner.
$details = array('name' => $owner_name,
'latitude' => $row["currentLatitude"],
'longitude' => $row["currentLongitude"]
);
array_push($device_details['devices'], $details);
}
$response = json_encode($device_details);
echo $response;
}
If the columns of the device_realtime_stats table are not named currentLatitude and currentLongitude make sure they are renamed.
$mysql_all_resultset = mysqli_query($con, " SELECT dot.name, drs.currentLatitude, drs.currentLongitude FROM device_details dt, device_owner_details dot, device_realtime_stats drs WHERE dt.vendorId=$vendor_id AND dot.deviceId=dt.id AND drs.deviceId= dot.deviceId LIMIT $start_from, $limit ");
if(($total_pages<=$page) &&( $total_pages>0))
{
$device_details=array('devices'=> array());
while ($rows_fetch = mysqli_fetch_assoc($mysql_all_resultset))
{
$details =array('name' => $rows_fetch['name'], 'latitude' => $rows_fetch['currentLatitude'], 'longitude' => $rows_fetch['currentLongitude']);
array_push($device_details['devices'],$details);
}
$response = json_encode($device_details);
echo $response;
}
I'm making a blog based on PHP and MySQL (using PDO to connect). I have written a function (below) that will retrieve blog posts and return them, but order by isn't working when I pass it by reference:
<?php
/**
* Get blog posts, filtered and sorted to taste.
* #return array Array of rows - each row is an array indexed by column name.
* #param string $inFunction What to select posts by - id, date or tag(s).
* #param string $inFilter Filter data to select posts by - id no., date(s) or tag(s). If you are filtering by date and only specify one, it will be taken to be the 'newer than' date.
* #param string $inOrder How to sort posts. This parameter is fed directly into the query and therefore should be raw SQL.
* #param object $inDatabase Database handle to pass to the SQL query.
*/
function getBlogPosts($inFunction, $inDatabase, $inFilter, $inOrder) {
switch ($inFunction) {
case "permalink": {
$query = $inDatabase->prepare("select * from blog_posts where permalink = :permalink");
$query->bindValue(":permalink", $inFilter);
$query->execute();
$result = $query->fetch();
return new BlogPost($result["id"], $result["title"], $result["permalink"], $result["post_full"], $result["post_sample"], $result["tags"], $result["timestamp"]);
break;
}
case "number": {
$query = $inDatabase->prepare("select * from blog_posts
order by :order
limit :limit_start , :limit_end");
$query->bindParam(":order", $inOrder);
$splitLimits = explode(", ", $inFilter);
if (sizeOf($splitLimits) === 1)
$splitLimits[] = 1; // First post
$limitEnd = $splitLimits[0] + $limitStart;
$limitStart = $splitLimits[1] - 1;
$query->bindValue(":limit_start", (int) $limitStart, PDO::PARAM_INT);
$query->bindValue(":limit_end", (int) $limitEnd, PDO::PARAM_INT);
$query->debugDumpParams();
$query->execute();
$results = $query->fetchAll(PDO::FETCH_ASSOC);
$return = array();
foreach ($results as $result) {
$return[] = new BlogPost($result["id"], $result["title"], $result["permalink"], $result["post_full"], $result["post_sample"], $result["tags"], $result["timestamp"]);
}
return $return;
break;
}
case "id": {
$query = $inDatabase->prepare("select * from blog_posts where id = :id order by :order");
$query->bindParam(":id", $inFilter);
$query->bindParam(":order", $inOrder);
$query->execute();
return $query->fetchAll(PDO::FETCH_ASSOC); // Prevents duplicate results when using loops (foreach, while etc.)
break;
}
case "date": {
$splitdate = explode(", ", $inFilter);
$query = $inDatabase->prepare("select * from blog_posts
where (date_posted > :newerthan_date)
and (date_posted <= :olderthan_date)
order by :order");
if (sizeof($splitdate) === 1) {
$splitdate[] = date("Y-m-d");
}
$query->bindParam(":newerthan_date", $splitdate[0]);
$query->bindParam(":olderthan_date", $splitdate[1]);
$query->bindParam(":order", $inOrder);
$query->execute();
return $query->fetchAll(PDO::FETCH_ASSOC);
break;
}
case "tag": {
$tags = explode(", ", $inFilter);
$insert = "";
foreach ($tags as $key => $tag) {
if ($key === 0) {
$insert .= "where tags like :tag_{$key}";
}
else {
$insert .= " or tags like :tag_{$key}";
}
}
$query = $inDatabase->prepare("select * from blog_posts
{$insert}
order by :order");
foreach ($tags as $key => $tag) {
$query->bindValue(":tag_{$key}", '%^' . $tag . '^%');
}
$query->bindParam(":order", $inOrder);
$query->execute();
return $query->fetchAll(PDO::FETCH_ASSOC);
break;
}
}
}
On the main page, $results = getBlogPosts("number", $sql_conn, "10", "timestamp desc"); is called and a foreach loop iterates through the posts. The problem is that PDO does not seem to be applying the :order parameter; whatever I put for $inOrder it always has the same order. If I go and directly change the statement within the getBlogPosts function to have order by timestamp desc instead of order by :order, it works fine.
I'm stumped - any ideas?
"This parameter is fed directly into the query and therefore should be raw SQL." => the comment is correct, the code is not, fix this. The reason is you can specify strings/numbers/etc. with parameters, but not identifiers (column names etc.).
What your query does it this:
SELECT ... FROM ... ORDER BY 'columnname';
Rather then:
SELECT ... FROM ... ORDER BY columnname;
So. it sorts by the string 'columnname', not the value in the field with the same name, with is the same for every row, so no sorting takes place (you might as well ORDER BY 1. The solution here is to add that order by clause as raw MySQL as the docblock comment states. If you want more control over it / prevent nastiness there, you could provide a whitelist of allowable order by clauses and refuse others.
I have something like that in my mySQL database:
(User 734 have many informations : biography, name, phone, mail ...)
I want to get an array (in PHP) with grouped datas :
array(
[734]=>
object {
[155] => string "Dominique",
[4] => int(047682037),
[1] => string "Dominique B"
},
[735]=>
object {
[155] => string "Other",
[4] => int(0123456789),
[1] => string "Other B"
}
)
not only for 734 user but for each user. With a simple query I get everything but not in the good order. Can I make it in SQL or I maybe need to rearrange datas in PHP next ?
What is the sql query to get, for each user_id, all the related datas ?
I can't change the database structure (WP and buddypress)
I can't use native WP functions (because getting datas from another site)
SELECT * FROM (whatever your table name is)
WHERE user_id = (whatever user id you're interested in getting data for)
Solution using ORDER BY :
$users = array();
$current_user = null;
$result = $mysqli->query("SELECT user_id, field_id, value FROM `TABLE_NAME` ORDER BY user_id, field_id");
while ($result && $row = $mysqli->fetch_assoc($result)) {
if ($current_user != $row['user_id']) {
$current_user = $row['user_id'];
$users[$row['user_id']] = array();
}
$users[$row['user_id']][$row['field_id']] = $row['value'];
}
EDIT :
There is another solution using GROUP BY and GROUP_CONCAT :
$users = array();
$result = $mysqli->query("SELECT user_id, GROUP_CONCAT(field_id SEPARATOR '|') as fields, GROUP_CONCAT(value SEPARATOR '|') as values FROM `TABLE_NAME` GROUP BY user_id");
while ($result && $row = $mysqli->fetch_assoc($result)) {
$fields = explode('|', $row['fields']);
$values = explode('|', $row['values']);
$users[$row['user_id']] = array();
// Problem id you have your field ids and your values in separate arrays, not sure what you want to do with them
}
$result = mysqli_query($con, "SELECT * FROM table_name WHERE user_id = 734");
Or if you arent using mysqli:
$result = mysql_query("SELECT * FROM table_name WHERE user_id = 734");
If you are using the PDO library you could check the PDO::FETCH_GROUP attribute.
http://php.net/manual/en/pdostatement.fetchall.php
fetch_style:
To return an associative array grouped by the values of a specified column, bitwise-OR PDO::FETCH_COLUMN with PDO::FETCH_GROUP.
$stmt = $this->_mysqli->prepare('SELECT user_id,field_id,value FROM WHERE user_id = ?');
$stmt->bind_param('i', $user_id );
$stmt->execute();
$stmt->bind_result($user_id, $field_id, $value);
while($stmt->fetch())
{
$data[$user_id][$field_id] = $value;
}