Iterating array/hashmap - php

Edit: Nico Parodi's answer is correct. I will eventually return to finding out why, but for now I will just take it as it is and hope nothing else fails.
I have a table with three fields: "date", "name", "location". I want to group all the records selected from this table based on their date.
By copy-pasting some code from php mysql group by date with yyyy-mm-dd format, I've managed to get this array, date -> name:
$result = mysqli_query($con,"SELECT date, name, location FROM events");
while($row = mysqli_fetch_array($result)) {
$foo[$row['date']][]=$row['name'];
}
Everything's great, I can iterate it without issues. Now I want to store all the row columns as a value for the date key, so I try to store the entire row as a value:
$result = mysqli_query($con,"SELECT date, name, location FROM events");
while($row = mysqli_fetch_array($result)) {
$foo[$row['date']][]=$row;
}
And now I can't iterate it. count($rowCol) seems to give me the nr of columns in all the array for either keys, not just for one. How can I iterate it?
foreach($foo as $date => $events) {
echo $date . ": "; // this is okay
foreach($events as $key => $rowCol){
for ($i = 0; $i<count($rowCol); $i++) {
echo $rowCol[$i] . " ";
}
}
}

for ($i = 0; $i<count($rowCol); $i++) {
echo $rowCol[$i] . " ";
}
$rowCol has the double of fields that you expect as mysqli_fetch_array() fetches as both associative and numeric array.
So,
for ($i = 0; $i<(count($rowCol)/2); $i++) {
echo $rowCol[$i] . " ";
}
should work.

Replace :
for ($i = 0; $i<count($rowCol); $i++) {
echo $rowCol[$i] . " ";
}
By
foreach($rowCol as $k =>$v) {
echo $v . " ";
}

for ($i = 0; $i<count($rowCol); $i++) {
echo $rowCol[$i] . " ";
}
this part of code doesn't work because rowCol is an associative array + numeric array. Try to replace mysqli_fetch_array with mysqli_fetch_row

Can you tell us what's the output of this code? (show plain text, no HTML):
foreach($foo as $date => $event) {
echo $date . ": ";
foreach($event as $key => $value){
print_r($value);
}
echo "\n";
}
Original answer:
$events contains a single event, your code should look more like this:
foreach($foo as $date => $event) {
echo $date . ": ";
foreach($event as $key => $value){
echo $value . " ";
}
echo "\n";
}

Related

How to count/sum this values of the same word in PHP?

I am confused to count these words,
I've some data like this :
web = 1
sistem=1
web=1
sistem=1
web=1
sistem=1
sistem=0
sistem=0
web=0
sistem=0
web=0
sistem=0
web=0
web=0
I want to make result like this :
web = 3
sistem = 3
I'm using array_count_values(), but this result is not good
Array ( [web=1] => 3 [sistem=1] => 3 [sistem=0] => 4 [web=0] => 4 )
My code like this :
foreach ($g as $key => $kata) {
if (strpos($cleanAbstrak, $kata)) {
echo $kata . $ada . "<br>";
$p[] = $kata . "=" . $ada;
// print_r($p);
echo "<br><br>";
} else {
echo $kata, $tidak . "<br>";
$q[] = $kata . "=" . $tidak;
// $m = explode(" ", $q);
// print_r($q);
// echo $q . '<br>';
echo "<br><br>";
}
}
$s = array_merge($p, $q);
echo "<br><br>";
print_r($s);
echo "<br>";
$f = array_count_values($s);
// print_r($f);
echo "<br><br>";
thank you very much if you are willing to help me
RESULT THIS CODE
Another simple way is use a counter like that:
$web=0;
$sistem=0;
foreach ($g as $key => $kata) {
if (strpos($cleanAbstrak, $kata)) {
$sistem=$sistem + $ada;
} else {
$web=$web+$tidak
}
}
echo 'web='.$web.'<br> sistem='.$sistem;
First, you need to separate word and value.
Second, you need to check the value : if it's zero you let it go (can't hold it back anymore). Else you count the value ; if it's written, i suppose it can be greater than 1 ; if it's not, it should be "word", or nothing (which would greatly facilitate counting).
Something like
<?php
$tab = [
'web=1',
'sistem=1',
'web=1',
'sistem=1',
'web=1',
'sistem=1',
'sistem=0',
'sistem=0',
'web=0',
'sistem=0',
'web=0',
'sistem=0',
'web=0',
'web=0',
];
$tab_clean = [];
foreach($tab as $item) {
preg_match('/([a-z]+)=([\d]+)/', $item, $matches);
//print_r($matches);
$word = $matches[1];
$number = $matches[2];
for($i = 0; $i < $number; $i++) {
$tab_clean[] = $word;
}
}
$tab_count = array_count_values($tab_clean);
print_r($tab_count);
?>

For each loop add 1 in PHP

I have been trying to return a list of results from MySQL using PHP.
The basic query is simple and the output is multiple columns. I want to add a number so the array looks like this:
Club 1
Club 2
I have tried the below but it keeps breaking the script:
if (mysqli_num_rows($result) > 0) {
while($row = mysqli_fetch_assoc($result)) {
for($i=1; $i++){
$club = $row['club_name'];
echo '<p>' . $i . $club . '</p>';
}
}
}
I have then tried placing the for statement outside the while and inside it, changed it to foreach and used the format ($i=1; $i<100; $i++){} and it still doesn't work.
Sorry if this is an obvious one I've tried numerous different ways and it just isn't working for me.
Try creating a counter variable ($i) and incrementing it on every iteration of the while loop ($i++), like this:
if (mysqli_num_rows($result) > 0) {
$i = 1;
while($row = mysqli_fetch_assoc($result)) {
$club = $row['club_name'];
echo '<p>' . $i . $club . '</p>';
$i++;
}
}
Then, to change the format to match 1. Club Name, change
echo '<p>' . $i . $club . '</p>';
to
echo "<p>$i. $club</p>";
But, I'd personally recommend to use an <ol> instead and skip setting the counter altogether like this:
if (mysqli_num_rows($result) > 0) {
echo "<ol>";
while($row = mysqli_fetch_assoc($result)) {
$club = $row['club_name'];
echo "<li>$club</li>";
}
echo "</ol>";
}

Number_format specific item in foreach php

Thanks for directing the link about the mySql API, i think there is a need to change to mySQLi or PDO. I have post the near-complete code below of same case, as my first time, could you please help what's error below, as it doesn't show the results as expected as the code using mysql_... please help. (assuming the select statement is correct please.)
<?php
$Ticker = htmlspecialchars($_GET["Ticker"]);
$StartDate = htmlspecialchars($_GET["StartDate"]);
$EndDate = htmlspecialchars($_GET["EndDate"]);
echo "<td>testing.</td>";
echo "</table>";
$pdo = new PDO('mysql:host=;dbname=, ,);
$statement = $pdo->query("Select Ticker, xxx as 'Last Update',Price, xxx as TTlUndetAmt,
FROM trade
WHERE Ticker = '$Ticker' and DATE(xxx) between '$StartDate' and '$EndDate'
GROUP BY Ticker, date
ORDER BY Ticker ASC, Date(ReleaseDT) DESC");
$row = $statement->fetch(PDO::FETCH_ASSOC);
//echo htmlentities($row['_message']);
echo "<table>";
while ($row = mysql_fetch_assoc($sql_result)) {
echo "<tr><td>";
foreach ($row as $value) {
if ($value === end($row)) {
echo number_format($value);
} else
{
echo $value . ",";
}
}
echo " </td></tr> " . "\n";
$i++;
}
?>
I got the results from select statement from mysql database. I use php to get the required data. I want specify the format only a specific item of each row to be numeric, i.e. (thousand separated). How could I do so? can below code do so?
Current output:
ticker1,2014-09-03 ,1.190,0,37247000
ticker2,2014-09-03 ,1.180,0,23246000
ticker3,2014-09-03 ,1.170,0,19188000
Expected Output:
ticker1,2014-09-03 ,1.190,0,37,247,000
ticker2,2014-09-03 ,1.180,0,23,246,000
ticker3,2014-09-03 ,1.170,0,19,188,000
The code I am using:
while ($row = mysql_fetch_assoc($sql_result)) {
echo "<tr><td>";
foreach ($row as $value) {
echo $value . ",";
if ($value === $row[5]) {
echo number_format($value);
}
}
echo " </td></tr> " . "\n";
$i++;
}
echo "</table>";
I found out that the above code will create duplicate role at the last row [5].
To my limited knowledge, I changed to
while ($row = mysql_fetch_assoc($sql_result)) {
echo "<tr><td>";
foreach ($row as $value) {
if ($value === end($row)) {
echo number_format($value);
} else
{
echo $value . ",";
}
}
echo " </td></tr> " . "\n";
$i++;
}
I would incorporate the key. That way, you can just check for the field name:
while ($row = mysql_fetch_assoc($sql_result)) {
echo "<tr><td>";
foreach ($row as $key => $value) {
echo $value . ",";
if ($key === 'YourFieldName') {
echo number_format($value);
}
}
echo " </td></tr> " . "\n";
$i++;
}
echo "</table>";
The function mysql_fetch_assoc already returns a key/value array, so you don't need anything there. Note though, that mysql_fetch_assoc is part of an old and deprecated API. If you like, have a look at: Choosing a MySQL API.
I would bring in the names, and use a $key=>$val in your foreach as such:
foreach ($row as $key=>$value)
{
echo $value . ",";
if ($key == "theRightColumn") // guessing the column name
{
echo number_format($val);
}
else
{
echo $val;
}
}
You have to change the modification in this line
foreach ($row as $value) {
to
foreach ($row AS $key => $value) {

How to order by a segment of preg_match_all results?

I'm using PHP to generate a list of references to a text by doing a preg_match_all search on a database table. Here is the PHP code:
$query = "SELECT primary_tag,display_short_title,content FROM topics;";
$result = mysql_query($query) or die("Query failed : " . mysql_error());
$num_results = mysql_num_rows($result);
for ($i = 0; $i < $num_results; $i++) {
$row = mysql_fetch_array($result);
if (preg_match_all("/(\<i\>U\<\/i\>|U) [0-9]{1,2}\.[0-9]{1,7}/", $row["content"], $matches)) {
foreach ($matches[0] as $match) {
$match = ltrim(strip_tags($match), "U ");
echo '<p class="textmark_result">' . $match;
echo ' ' . $row["display_short_title"] . '';
echo "</p>\n";
}
}
}
And the results (viewing source) look like this:
<p class="textmark_result">15.1737 Medicine</p>
<p class="textmark_result">5.678 Science</p>
<p class="textmark_result">14.665 Science</p>
In the resulting web page, I want to order the results by the decimal in the middle, the $match in the code, so that (in this example) 5.678 comes first, then 14.665, then 15.1737. Is there a way to do that?
Thank you!
Three steps to do:
Get all your matches and add them to an array - floatval($match) is the key.
Sort the resulting array by key (floats sort by numeric value, strings sort by characters - therefore floatval(...)).
Iterate on the sorted array
Code:
// MySQL stuff goes here ...
// create empty array
$results = array();
for ($i = 0; $i < $num_results; $i++) {
$row = mysql_fetch_array($result);
if (preg_match_all("/(\<i\>U\<\/i\>|U) [0-9]{1,2}\.[0-9]{1,7}/", $row["content"], $matches)) {
foreach ($matches[0] as $match) {
$match = ltrim(strip_tags($match), "U ");
// array pseudo key is the float value of $match
// add '_key' member for usort()
$row['_key'] = floatval($match);
$results[] = $row;
}
}
}
// sort the array by the float key
usort($results, function($a, $b) {
if($a['_key'] == $b['_key']) return 0;
elseif($a['_key'] > $b['_key']) return 1;
else return -1;
});
// ... then display stuff in order
foreach($results as $row) {
echo '<p class="textmark_result">' . (string)$row['_key'];
echo ' <a href="../Essays/topic.php?shorttitle='
. $row["primary_tag"] . '">' . $row["display_short_title"] . '</a>';
echo "</p>\n";
}

unknown columns, column names, and rows into HTML table

I'm trying to display all the information in a msSQL table in an HTML table and have up with something that is not so great.
<table border="1">
<?
echo "<tr>";
for ($i = 0; $i < mssql_num_fields($result); ++$i){
echo "<th>" .$column_names[$i] . "</th>";
}
echo "</tr>";
$num_rows = mssql_num_rows($result);
for ($i = 0; $i < $num_rows; ++$i){
echo "<tr>";
foreach ($column_names as $key => $val){
$result_row = mssql_query("SELECT * FROM username WHERE id = '$i'");
$row = mssql_fetch_assoc($result_row);
echo "<td>";
echo $row[$val];
echo "</td>";
}
echo "</td>";
}
?>
</table>
This works. The first part prints out the column names successfully, but as for the rest:
1) I think it is sort of cumbersome to make a query for every time through the loop
2) it doesn't really work because the ids of the rows go much higher than the number of rows in the table, as some ids aren't used.
It seems like I should be able just make one query and pull everything from the database at one go, then build my HTML table from that, but I can't figure out how to access it row by row where I could go $row[next row][shifted value from $column_names. How can improve this query?
function table_cell($item, $header=false) {
if (!$item) return '';
$elemname = ($header) ? 'th' : 'td';
$escitem = htmlspecialchars($item, ENT_NOQUOTES, 'UTF-8');
return "<{$elemname}>{$escitem}</{$elemname}>";
}
function table_header_cell($item) {
return table_cell($item, true);
}
function table_row($items, $header=false) {
$func = ($header) ? 'table_header_cell' : 'table_cell';
return "<tr>\n\t".implode("\n\t", array_map($func, $items))."\n</tr>\n";
}
function echo_result_as_table($result) {
if ($result && $row = mssql_fetch_assoc($result)) {
$columnnames = array_keys($row);
echo "<table>\n", table_row($columnnames, true), "\n";
do {
echo table_row($row), "\n";
} while ($row = mssql_fetch_assoc($result));
echo "</table>\n";
}
}
$result = mssql_query("SELECT * FROM username");
echo_result_as_table($result);
if ($result) mssql_free_result($result);
If you have an array of associative arrays instead of a raw mssql result handle, you can use a function like this to produce a table string:
function array_to_table($arrayofassoc) {
if (!$arrayofassoc) return '';
$tablestr = '<table>';
$tablestr .= table_row(array_keys($arrayofassoc[0]), true);
$tablestr .= implode('', array_map('table_row', $arrayofassoc));
$tablestr .= '</table>';
return $tablestr;
}
try this:
while($row = mysql_fetch_results($result)){
echo '<td>'.$row['column_name'].'</td>';
}
with 'column_name' being the name of the column in mysql.
but some will say..."wait, but PDO"

Categories