I am going to select a list of items from a table, and pass it using json-framework.
Example, I want to select friends from my "shirts" table, from "players_shirts" table
pid | sid
================
1 | 2
2 | 3
1 | 5
Lets say, I get 30++ result (rows).
I assume (not yet tested this code), in php, I assign it by:
$array;
$count = 0;
while($r = mysql_fetch_assoc($exe){
$array[$count] = $r['sid'];
// EDIT START: I forgot to add counter
$count++;
// EDIT END
}
echo json_encode($array)
Is this method efficient/good enough?
I am new to php/database/manipulating data from database.
There is no need to specify an array keys in your case, so your code could be rewritten as:
$array = array();
while($r = mysql_fetch_assoc($exe){
$array[] = $r['sid'];
// or you may use array_push($array, $r['sid']); instead of the line above.
}
Related
so I've been scratching my head about this one for a while and almost there but still getting unexpected results.
So I have a database containing the following data
username | level1 | level2 | level3
user1 | 39.76072 | 79.41869 | 151.2955
user2 | 39.80072 | 80.73846 | 270.6498
user3 | 39.84072 | 80.81845 | 83.41801
user4 | 39.85321 | 80.90525 | 88.31719
user5 | Zero | Zero | Zero
I've been trying to put these into a multi-dimensional array in order from the lowest to the highest but have really been struggling. These are basically level times and I'm trying to create a leaderboard.
I assume the problem is that the level columns are not INT but rather CHAR
I am currently trying the following
function order_by_time($a, $b) {
return $b["Level".$_POST["level"]] < $a["Level".$_POST["level"]] ? 1 : -1;
}
$query = mysqli_query($con, "SELECT userName, Level".$_POST["level"]." FROM table");
$results = array();
$unranked = array();
while($line = mysqli_fetch_array($query, MYSQLI_ASSOC)){
if($line["Level".$_POST["level"]] == "Zero"){
$unranked[] = $line;
} else{
$results[] = $line;
}
}
usort($results, "order_by_time");
$results = array_merge($results, $unranked);
This works for level1 and for level2 but not for level3.
Level1 displays as it does in the aboce database example and so does level2 but the problem is so does level3 and that isn't the correct order.
it looks like its something to do with the number of characters before the decimal.
Any advice on how i can resolve this without touching the database? that isn't really an option as its already being used.
I'd really appreciate some help with this :-)
First off, don't inject something from $_POST directly into an SQL query. That's how sites get hacked. In this particular case, I'd recommend setting a variable with that parameter cast to integer, and check its value as well:
$level = (int)$_POST["level"];
if ($level > 0 && $level < 4) {
$query = $con->query("SELECT userName, Level$level FROM table");
} else {
die();
}
As to your question, the simple solution here is to sort in the database. ORDER BY Level$level and you're done.
$level = (int)$_POST["level"];
if ($level > 0 && $level < 4) {
$query = $con->query("SELECT userName, Level$level FROM table ORDER BY Level$level");
} else {
die();
}
$results = $query->fetch_all(MYSQLI_ASSOC);
If that's not possible for some reason, what you've got there should be working just fine according to my testing. But it's rather hacky, especially pulling information from $_POST to a custom function. Instead just use PHP's built-in abilities to work with multidimensional arrays.
$level = (int)$_POST["level"];
if ($level > 0 && $level < 4) {
$query = $con->query("SELECT userName, Level$level FROM table");
} else {
die();
}
$results = $query->fetch_all(MYSQLI_ASSOC);
$usernames = array_column($results, "username");
$times = array_column($results, "Level$level");
array_multisort($times, SORT_ASC, $results);
The only reason I can think of that this wouldn't work would be that there are some leading or trailing spaces in the values that are preventing them from being converted to numbers for the comparison.
If you're just echoing them out in HTML, you probably wouldn't see the spaces, but you'll see them if you var_dump the variable. The normal behavior of PHP is to compare numeric strings as numbers, but it won't work that way if there are extra spaces.
$test = '151.2955' > '83.41801';
var_dump($test); // true
$test = '151.2955 ' > '83.41801 ';
var_dump($test); // false
Try trimming the values.
$query = mysqli_query($con, "SELECT userName, TRIM(Level3) AS userValue FROM table");
The expression is aliased, so refer to it in your PHP code as $row['userValue'] rather than using the value from $_POST. If this does work, it may also let you use ORDER BY in MySQL. I'm not really sure if whitespace has the same result there as it does in PHP. I think you'll need to cast the column to a numeric type for it to sort properly regardless of spaces. It's unfortunate that you can't alter the table to store the number as a number.
I currently have the following:
$query='select concat("[",key,"=>",value,"]")
from table';
if(isset($query))$r=$mysql->query($query);
if(isset($r)){
for($i=1;$i<=$r->num_rows;$i++){
$r->data_seek($i-1);
$a[$i-1]=$r->fetch_array(MYSQLI_ASSOC);
$a[$i-1]=parse_array($a[$i-1]);
}
}
$mysql->close;
function parse_array($parent){
foreach($parent as$k=>$val){
if(strpos($val,']')){
$array=explode(',',substr($val,1,-1));
foreach($array as$val){
$keypair=explode("=>",$val);
$newarray[$keypair[0]]=$keypair[1];
}
$parent[$k]=parse_array($newarray);
}
}
}
There has to be a more elegant way of doing this - perhaps built into MySQL? I'm trying to minimize the time this spends running PHP - I would like it to arrive to PHP already in array form, but MySQL kicks Subquery returns more than one result if I attempt a subquery.
Edit: Here's table:
+----------+----------+
| value | key |
+----------+----------+
| img.jpg | src |
+----------+----------+
Output should be:
[
'src'=>'img.jpg'
]
Just move all of the manipulation over to php. Fetch the query with numeric indexes. Make the assumption that the every even index is a key and every odd index is a value (or vice versa).
$query = 'select key1, value1, key2, value2
from table';
if(isset($query))
$result = $mysql->query($query);
if(isset($result)) {
$newResult = []; // if your version of php doesn't support this syntax to create a new array use `$newResult = array();`
while($row=$result->fetch_array(MYSQLI_NUMERIC)) {
$newResult[] = build_assoc_array($row);
}
}
$mysql->close;
function build_assoc_array($flat_arr) {
$newArr = [];
$numCol = count($flat_arr);
for($colIndex = 0; $colIndex < $numCol; $colIndex+=2) {
$newArr[$flat_arr[$colIndex]] = $flat_arr [$colIndex+1];
}
return $newArr;
}
I've looked for about an hour. I may even be looking for the wrong thing, because I'm sure this is a common practice. In the past, I would have just ran mutliple querys or had something hard coded, but I'm trying to do things the most efficient way.
I have a query that brings back this data:
factoryId | serviceID | serviceName
1 1001 repair
1 1002 recycle
1 1003 transfer
2 1001 repair
2 1002 recycle
2 1003 transfer
3 1001 repair
3 1002 recycle
3 1003 transfer
I need to put it into sections with headers...
// switch statement determines factory name from id ?>
Factory One
Repair
Recycle
Transfer
Factory Two
Repair
Recycle
Transfer
Factory Three
Repair
Recycle
Transfer
I think the solution is with multi-dimensional arrays, but not sure how to write the array, and then (2 foreach loops?) to echo the formatted result.
Here this is what you can do, I am not using the query but generated an array which is similar to mysql_fetch_assoc();
<?php
$array[] = array("factory"=>"Factory One","serviceName"=>"repair");
$array[] = array("factory"=>"Factory One","serviceName"=>"recycle");
$array[] = array("factory"=>"Factory One","serviceName"=>"transfer");
$array[] = array("factory"=>"Factory Two","serviceName"=>"repair");
$array[] = array("factory"=>"Factory Two","serviceName"=>"recycle");
$array[] = array("factory"=>"Factory Two","serviceName"=>"transfer");
$array[] = array("factory"=>"Factory three","serviceName"=>"repair");
$array[] = array("factory"=>"Factory three","serviceName"=>"recycle");
$array[] = array("factory"=>"Factory three","serviceName"=>"transfer");
$group_array = array();
foreach($array as $key=>$val){
$group_array[$val["factory"]][] = $val["serviceName"];
}
foreach($group_array as $key=>$val){
echo '<b>'.$key.'</b><br />';
foreach($val as $k=>$v){
echo '-'.$v.'<br />';
}
}
?>
The first loop is similar to looping the query result and creating a group array and then finally loop the group array to display the data.
Try the below code. Make sure to write your query appending ASC or DESC to factoryID
<?php
//Place a counter for factoryId
$countid_fid = 1;
$reset = 0; //this decides if the title should be printed or not. 1 means dont print.
//loop
while($row = mysql_fetch_object($q)) {
$fid = $row->factoryID;
if($countid_fid == $fid) {
if($reset = 0) {
echo $row->serviceName; //title
$reset = 1;
}
}else{
$reset = 0;
}
//rest of your code to show data
}
?>
Hope this help
SELECT * FROM factory GROUP BY factoryId;
First, thanks for any help.
I've spent countless hours on here and other forums trying to find my exact solution but either 1) I'm not understanding the one's I've read or 2)I haven't found the right answer.
In PHP, I've run a somewhat complex query which returns a set of records similar to:
id | name | direction|
1 aaa east
2 bbb west
3 ccc east
I've created an associative array such as:
$query=("select * from foo");
$result=mysql_query($query);
$array=mysql_fetch_assoc($result);
Now, what I need to do seems simple but I'm not grasping the concept for some reason.
I need to loop through the entire $array and return a count of any value that I want to specify and store that count in a variable.
i.e. Show me how many times east shows up in the "direction" column and put that in a variable called $eastcount.
I've tried various combinations of using foreach loops with incremental counts and have tried using array_count_values but have not been able to put the pieces together :/
// build query
$query=("select * from foo");
// execute query
$result=mysql_query($query);
// declare vars
$east_count = 0;
// iterate through results
while ($data = mysql_fetch_array($result)) {
// grab DIRECTION column value
$direction = $data['direction'];
// detect 'east'
if ($direction == 'east') {
// increment 'east' count
$east_count++;
}
}
// print # of times we had 'east'
echo("direction said 'east' $east_count times");
This should work (sorry for the lack of code block I'm on my iPhone).
http://www.php.net/manual/en/function.array-count-values.php
$array = array(1, "hello", 1, "world", "hello");
print_r(array_count_values($array));
Array
(
[1] => 2
[hello] => 2
[world] => 1
)
How about this:
query=("select * from foo");
$result=mysql_query($query);
$directions = array();
while($direction = mysql_fetch_assoc($result) {
$directions[] = $direction['direction'];
}
$directionCounts = array_count_values($directions);
//now you can access your counts like this:
echo $directionCounts['east'];
First, of all you should be using mysqli instead. But, anyhow I hope this makes some sense.
if ($result) {
$count = 0;
while ( $row = mysql_fetch_assoc($result)) {
if ($row["route"] === "east") {
$count += 1;
}
}
return $count;
}
Say I have a query the following query run:
Edit
Added order clause because the real sql statement has one.
SELECT description, amount, id FROM table ORDER BY id
In this instance, the ID is not unique to the dataset. It would return something like this.
Description Amount ID
----------- ------ --
1 Hats 45 1
2 Pants 16 1
3 Shoes 3 1
4 Dogs 5 2
5 Cats 6 2
6 Waffles 99 3
What I need to do is enclose each section of IDs in it's own div (So rows 1,2,3 in one div, 4,5 in another div and 6 in it's own div).
There are tons of solutions to this but I just can't think of one that isn't overly complicated.
I want to be able to keep the SQL how it is and somehow sort the data set in PHP so that I can loop through each section of the dataset while looping through the dataset as a whole.
Some kind of array would work but the structure of it is stumping me.
How can I get this to work? PHP solutions would be idea but theoretical will help too.
See if something like this works for you.
// execute query: Select description, amount, id from table
$results = array();
while ($row = $query_result->fetch_array()) {
if (!isset($results[$row['id']])) $results[$row['id']] = array();
$results[$row['id']][] = $row; // push $row to results for this id
}
// later on
foreach($results as $id => $data) {
// output div based on $id
foreach($data as $datum) {
// output individual data item that belongs to $id
}
}
A simple serial solution might look something like this:
$curId = ''; // track working id
$firstDiv = true; // track if inside first div
// open first div
echo '<div>';
// foreach $row
{
// when id changes, transition to new div, except when in first div
if ($row->$id != $curId) {
if ($firstDiv) {
$firstDiv = false;
} else {
// start new div
echo '</div>';
echo '<div>';
}
$curId = $row->$id; // track new current id
}
// display contents of current row
}
// close last div
echo '</div>';
Just store the id in temp variable, if the next one is different close the div and open new div
Assuming associative arrays for the db results:
$final = array();
foreach($results as $result)
{
$final[$result['id']][] = $result;
}
This leaves you with an associative array $final that groups the entries by ID