I have loop that is saving data into multidimensional array.
$array = array();
for($i=0;$i<100;$i++) {
for($j=0;$j<100;$j++) {
if ($value1 != 0) {
$array[$i][$j]['key1'] = $value1;
$array[$i][$j]['key2'] = $value2;
$array[$i][$j]['key3'] = $value3;
}
}
}
Sometimes there may be no values to save for specific $j key, so before listing I would like to count the number of $j keys of each $i key.
I was trying do that in loop like that but it's not working:
for($i=0;$i<100;$i++) {
if (count($array[$i]) > 0) {
for($j=0;$j<count($array[$i]);$j++) {
echo $array[$i][$j]['key1'];
echo $array[$i][$j]['key2'];
echo $array[$i][$j]['key3'];;
}
}
}
}
I've seen many topics about counting arrays, but nothing similar to my problem.
Thanks in advance for any help.
EDIT:
As I looked into the comments I realized myself that indeed I've made mistake in the question, this is because I was writing the post very late, after many hours of work. Sorry.
The proper array reading code (that is representing my need) is:
for($i=0;$i<100;$i++) {
if (count($array[$i]) > 0) {
echo "table header";
}
for($j=0;$j<count($array[$i]);$j++) {
echo $array[$i][$j]['key1'];
echo $array[$i][$j]['key2'];
echo $array[$i][$j]['key3'];
}
}
As you see now I need to know if there are any data for each $i because table header is to be generated (or not) according to that.
Related
I need sum up quantity items. I have a database query, I print values:
while ($row = mysqli_fetch_array($lista)) {
echo $row['przedmiot'].":".$row['ilosc'].'<br>';
}
then I get this result:
item1:1
item1:3
item2:1
item1:3
item2:5
I need to add these values, I would like to get this result:
item1:7
item2:6
#Sascha's answer will work, but I'd suggest a different approach - instead of querying all these rows, transferring them from the database to your application and then having to loop over them in the code, let the database do the heavy lifting for you:
SELECT przedmiot, SUM(ilosc) AS ilosc
FROM mytable
GROUP BY przedmiot
This should help:
$result=[];
while ($row = mysqli_fetch_array($lista)) {
echo $row['przedmiot'].":".$row['ilosc'].'<br>';
if (!array_key_exists ($result, $row['przedmiot'])) {
$result[$row['przedmiot']] = $row['ilosc'];
} else {
$result[$row['przedmiot']] += $row['ilosc'];
}
}
i would like to ask for your help to solve my problem. Your help is kindly appreciated.
My question is i have two inputs type which are array ( <input type='text' name='cost[]'> and <input type='text' name='price[]'> ) in view. Both inputs type are within a foreach statement. Let's say foreach from a table of database that has 3 records. So, from the view of web browser it requires user to input 3 times on the cost and price fields for every record. In my controller, i want to compare user input as below
-price[1] cannot be more than cost[1]
-price[2] cannot be more than cost[2]
-price[3] cannot be more than cost[3]
by using if else statement. How am i going to code in my controller so that price[1] is only compared to cost[1], price[2] is only compared to cost[2] and price[3] is only compared to cost[3].Below is my code in my controller, but cannot work.
$cost = $this->input->post('cost');
$price = $this->input->post('price');
if ($price > $cost)
{
echo "Rejected";
}
else
{
echo "Accepted";
}
You will need to loop over all the values.
My Codeigniter is a little rusty but I believe $cost and $price should both be arrays. Some something simple like this;
foreach ($price as $key => $value) {
if ($value > $cost[$key] ) {
echo "Rejected";
} else {
echo "Accepted";
}
}
If you want all to be valid then you could just break on the first rejected value. Otherwise you loop through all and warn the user about the invalid ones?
Please try the code below.
For demo: Demo URL
<?php
//$cost = $this->input->post('cost');
//$price = $this->input->post('price');
//Suppose I have added dummy values in these variable as you received from view.
$cost = array(1,2,3);
$price = array(3,4,1);
//as you mentioned each one cost have price like $cost zero index compared with $price zero index.
$i = 0;
foreach($cost as $cos){
if ($price[$i] > $cos)
{
echo "Rejected";
}
else
{
echo "Accepted";
}
$i++;
}
?>
hope you are well the problem that i am having is comparing two values in a array the (columns) of rows.
Is there a way to just check those columns match as i am only checking two rows or is a for each loop the only way.
I am able to get all the data and place it into an array but the if statement i am using does not work in comparing.
if ($countReport == 2) {
while ($rowReport = mysqli_fetch_assoc($resultReport)) {
$temp_array[] = $rowReport;
}
//if (in_array("Hello, world",array_count_values($temp_array))){
//echo "working";
//}
}
This is the data in the array, the stats column is what i am trying to compare like are both values equal to "hello world".
[{"abcID":"8","stats":"Hello, world","time":"23:30:00"},
{"abcID":"7","stats":"Hi, world","time":"23:16:00"},]
Try like this
<?
foreach($array as $k1=>$v1)
{
echo $k1; //returned abcID
echo $v2 //returned 8
foreach ($array2 as $k2 => $v2) {
echo $k2; //returned abcID
echo $v2 //returned 7
if($k1==$k2 && $k1=='stats')
{
if($v1==$v2)
$newarray[]=$v1; //added if they are equal or do what u want.
}
}
}
?>
EDIT: (this is my duh moment, I was overthinking this problem from the start.)
The logical process (no functions or loops are necessary) if you only have the two rows returned is to do a literal check:
if($temp_array[0]['stats']!=$temp_array[1]['stats']){
echo "no match";
}else{
echo "duplicate";
}
The following one-liners deliver the same outcome, but do so less efficiently....
Here is a one-liner for your condition statement requiring no loops:
Example 1:
$temp_array=array(
array("abcID"=>"8","stats"=>"Hello, world","time"=>"23:30:00"),
array("abcID"=>"7","stats"=>"Hi, world","time"=>"23:16:00")
);
if(sizeof(array_unique(array_column($temp_array,"stats")))>1){
echo "no match";
}else{
echo "duplicate";
}
// displays: no match
Example 2:
$temp_array=array(
array("abcID"=>"8","stats"=>"Hello, world","time"=>"23:30:00"),
array("abcID"=>"7","stats"=>"Hello, world","time"=>"23:16:00")
);
if(sizeof(array_unique(array_column($temp_array,"stats")))>1){
echo "no match";
}else{
echo "duplicate";
}
// displays: duplicate
The breakdown:
sizeof( // count the size of the remaining array
array_unique( // remove duplicates from array
array_column($temp_array,"stats") // array of values where 'stats' was the key
)
)
Come to think of it, there are probably several ways to skin this cat.
Here's another:
if(current(array_count_values(array_column($temp_array,"stats")))==1){
echo "no match";
}else{
echo "duplicate";
}
I'm not sure it's worth going on and on.
I am learning PHP and trying to use the while and continue expressions correctly.
I have a script that creates a 6 digit PIN, and I want to ensure that it is unique, otherwise I want to generate another PIN.
while(1) {
$pin = rand(111111,999999);
$sel = mysql_query("SELECT * FROM formusers WHERE pin = '$pin'");
if(mysql_num_rows($sel) != 0) { continue; }
mysql_query("INSERT INTO formusers(email,password,pin) VALUES('".$_POST['srEmail']."','".$_POST['srPass']."','".$pin."')");
if(mysql_affected_rows()!=-1) {
echo "Pin:" . $pin;
exit;
} else {
echo "Existing email, try again<br />";
}
break;
}
Do I have the syntax for the loop correct? It seems to work, but there's no way for me to debug it in the instance the rand() function creates the same PIN twice.
Also, in the event I did run out of unique PINs, what would happen here? Presumably it would loop indefinitely? Is there any way to prevent this?
Yeah, the code works, but as stated the infinite loop is concerning. You could possibly solve that like this:
var $i = 0;
while($i < 10) {
$i++;
$pin = rand(111111,999999);
$sel = mysql_query("SELECT * FROM formusers WHERE pin = '$pin'");
if(mysql_num_rows($sel) != 0) { continue; }
mysql_query("INSERT INTO formusers(email,password,pin) VALUES('".$_POST['srEmail']."','".$_POST['srPass']."','".$pin."')");
if(mysql_affected_rows()!=-1) {
echo "Pin:" . $pin;
exit;
} else {
echo "Existing email, try again<br />";
}
break;
}
This would ensure you would never make more than 10 iterations. However, the larger problem is probably that even that sampling size won't work in the future. This presents a bit of a conundrum. One possible approach is to determine how many unique numbers exist before starting the loop by counting them and then iterate that many times, but that approach is something like n2 (maybe, I'm not real good on big-O, I just know it would be bad).
You can leverage the unique nature of php array keys for this.
function getPins($qty){
$pins = array();
while (count($pins) < $qty){
$pins[rand(111111,999999)] = "";
}
return array_keys($pins);
}
This will make sure that for a given run you will get $qty number of unique pins. You might want to look at appending a unique prefix to each run of the function to avoid multiple runs creating collisions between the two.
You can seed random, so it gives you the same values every time, you run it:
srand (55 ); //Or some other value.
The while loop syntax looks okay to me.
I'm trying to make a simple alphabetical list to order items in my database. The thing I can't figure out is how to actually list it.
I would like it to be the same format as you have on miniclip.com
Here's an image
I looked around, but couldnt find an answer really.
(I would like it to finish even at the end of each vertical column, except the last one for sure)
Any help would be welcome!
In MySQL:
SELECT * FROM table ORDER BY name ASC
In PHP:
$fruits = array("lemon", "orange", "banana", "apple");
sort($fruits);
foreach ($fruits as $key => $val) {
echo "fruits[" . $key . "] = " . $val . "\n";
}
fruits[0] = apple
fruits[1] = banana
fruits[2] = lemon
fruits[3] = orange
Assuming that your result set already is sorted by using the ORDER BY clause, to group the results by their first character you just need to remember the first character of the previous entry and print out the first character of the current entry if they are different. So:
$prevLabel = null;
while ($row = mysql_fetch_assoc($result)) {
$currLabel = strtoupper(substr($row['name'], 0, 1));
if ($currLabel !== $prevLabel) {
echo $currLabel;
$prevLabel = $currLabel;
}
echo $row['name'];
}
This will print the first character as a label for each group that’s members have the same first character.
He doesn't seem to have an issue with the storting, but doing the column format and headers for each new letter.
Suppose $arr contains your alphabetically sorted list with numeric keys. each element has indexes 'name' and 'link'. This should be pretty safe assumption for data from a SQL query.
$firstLetter = -1;
$desiredColumns = 4; //you can change this!
$columnCount = (count($arr)+27)/$desiredColumns+1;
echo "<table><tr><td>";
foreach($arr as $key => $cur)
{
if ($key != 0 && $key % desiredColumns == 0) echo "</td><td>";
if ($cur['name'][0] !== $firstLetter)
{
echo "<strong>$firstLetter</strong> <br />"; $firstLetter = $cur['name'][0];
}
echo "".$cur['name']."<br />";
}
echo "</td><tr></table>";
You'll have to treat numbers as a special case, but this is the idea. If you are using a template engine there are obviously better ways of doing this, but I figure you would have mentioned that. This is a rough sketch, making pretty HTML isn't my thing.
--Query-- get table into $arr. I can't see your tables obviously, Im making assumptions if names nad stuff so you'll need to verify or change them
$sql = "SELECT * FROM table T ORDER BY name";
$conn = //you should have this
$res = mysql_query($sql, $conn);
$arr = array();
while($row = mysql_fetch_assc($res)
$arr[] = $row;
// start above code here. This isn't safe for empty query responses or other error but it works
I presume you're using MySQL (or another SQL) database, in which case you should simply retrieve the data in the required order using a SORT BY clause on the lookup SELECT. (Sorting this PHP is trivial via the sort function, but it makes sense to get the database to do this - that's pretty much what it's for.)
In terms of balancing the output of each of the columns, you could get a COUNT of the required rows in your database (or simply use the count of the resulting PHP array of data) and use this to ensure that the output is balanced.
As a final thought, if this is going to be output on a per-page basis, I'd highly recommend generating it into a static file when the structure changes and simply including this static file as a part of the output - generating this on the fly is needlessly resource inefficient.
The mysql option mentioned above is definitely the best bet. If the data comes out of the DM in order, that's the simplest way to go.
Your next option might be to look at the
asort and ksort functions in PHP to find the exact one you're looking for.
http://www.php.net/manual/en/array.sorting.php
How are you pulling the data?
<?php
$result = mysql_query("SELECT titles FROM gamelist ORDER BY title ASC");
while ($row = mysql_fetch_assoc($result)) {
echo "{$result['title']}<br/>";
}
?>
There are two ways to do it.
You could use your database and use the 'order' clause to pull them by a specific field alphabetically.
You could also use either a key sort or value sort on a PHP array.
The PHP functions are sort($array) and ksort($array).
http://php.net/manual/en/function.sort.php
http://php.net/manual/en/function.ksort.php
<?php
$list = $your_list_array_from_database
//if you need info on how to do this, just let me know
sort($list);
foreach($list as $item) {
echo $item;
}
?>
I found this post and had the same problem. I used the code below to output a list by category name with a header equal to the first letter. In my database table (category) I have name and category_letter. So, name = football and category_list = 'F'.
<section>
<?php
try {
$cats_sql = $dbo->prepare("SELECT name, category_list, FROM category WHERE category_list REGEXP '^[A-Z#]' GROUP BY category_list ASC");
$cats_sql->execute();
$results_cats = $cats_sql->fetchAll();
} catch(PDOException $e) {
include('basehttp/error');
}
$array_cats = $results_cats;
if(is_array($array_cats)) {
foreach($array_cats as $row_cats) {
$cat_var = $row_cats[category_list]; // Each Category list title
?>
<aside>
<h1><a name=""><? echo $cat_var ?></a></h1>
<?php
try {
$search_sql = $dbo->prepare("SELECT name, category_list FROM category WHERE category_list=:cat_var ORDER BY name ASC"); // Pulling a list of names for the category list
$search_sql->bindParam(":cat_var",$cat_var,PDO::PARAM_STR);
$search_sql->execute();
$results_search = $search_sql->fetchAll();
} catch(PDOException $e) {
include('basehttp/error');
}
$array_search = $results_search;
if(is_array($array_search)) { // Output list of names which match category
foreach($array_search as $row_search) {
?>
<h2><?php echo $row_search[name]; ?></h2>
<br class="clear">
<?php
}
}
?>
</aside>
<br class="clear">
<?php
}
}
?>
</section>
Its actually Simple....I did similar thing for my project once. I had to pull out all music albums name and categorize them in alphabetical order.
In my table, "album_name" is the column where names are stored.
$sql= "select * from album_table order by album_name ASC";
$temp_char= ""; // temporary variable, initially blank;
using while loop, iterate through records;
while($row= $rs->fetch_assoc())
{
$album_name= $row['album_name'];
$first_char_of_albm= $album_name[0]; // this will store first alphabet;
$first_char_of_albm= strtoupper($first_char_of_albm); // make uppercase or lower as per your needs
if($temp_char!=$first_char_of_albm)
{
echo $first_char_of_albm;
$temp_char= $first_char_of_albm; // update $temp_char variable
}
}
That's it....
I am posting my answer to this old question for 3 reasons:
You don't always get to write your queries to MySQL or another DBMS, as with a web service / API. None of the other answers address PHP sorting without query manipulation, while also addressing the vertical alphabetical sort
Sometimes you have to deal with associative arrays, and only a couple other answers deal with assoc. arrays. BTW, my answer will work for both associative and indexed arrays.
I didn't want an overly complex solution.
Actually, the solution I came up with was pretty simple--use multiple tags with style="float:left", inside of a giant table. While I was sceptical that having multiple tbody tags in a single table would pass HTML validation, it in fact did pass without errors.
Some things to note:
$numCols is your desired number of columns.
Since we are floating items, you may need to set the width and min-width of parent elements and/or add some <br style="clear: both" />, based on your situation.
for alternative sorting methods, see http://php.net/manual/en/array.sorting.php
Here's my full answer:
function sortVertically( $data = array() )
{
/* PREPARE data for printing */
ksort( $data ); // Sort array by key.
$numCols = 4; // Desired number of columns
$numCells = is_array($data) ? count($data) : 1 ;
$numRows = ceil($numCells / $numCols);
$extraCells = $numCells % $numCols; // Store num of tbody's with extra cell
$i = 0; // iterator
$cCell = 0; // num of Cells printed
$output = NULL; // initialize
/* START table printing */
$output .= '<div>';
$output .= '<table>';
foreach( $data as $key => $value )
{
if( $i % $numRows === 0 ) // Start a new tbody
{
if( $i !== 0 ) // Close prev tbody
{
$extraCells--;
if ($extraCells === 0 )
{
$numRows--; // No more tbody's with an extra cell
$extraCells--; // Avoid re-reducing numRows
}
$output .= '</tbody>';
}
$output .= '<tbody style="float: left;">';
$i = 0; // Reset iterator to 0
}
$output .= '<tr>';
$output .= '<th>'.$key.'</th>';
$output .= '<td>'.$value.'</td>';
$output .= '</tr>';
$cCell++; // increase cells printed count
if($cCell == $numCells){ // last cell, close tbody
$output .= '</tbody>';
}
$i++;
}
$output .= '</table>';
$output .= '</div>';
return $output;
}
I hope that this code will be useful to you all.