How to order by a segment of preg_match_all results? - php

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";
}

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);
?>

create div from each item in tags column

My tags column is like this:
first row: sky - earth - sea
second row: iron - silver - gold
third row: apple - fruit - food
...and so on
Want to create a div from each item, like this:
<div class='tagdown'>sky</div>
<div class='tagdown'>earth</div>
$st = $db->query("select tags from posts");
$arr = array();
$items = "";
while ($row = $st->fetch()) {
array_push($arr, explode(' - ', $row['tags']));
}
foreach($arr as $item) {
$items .= "<div class='tagdown'>" . $item . "</div>\n";
}
echo $items;
Notice: Array to string conversion...
Another Try:
for ($i = 0; $i < count($arr); ++$i) {
$items .= "<div class='tagdown'>" . $arr[$i] . "</div>\n";
}
echo $items;
Notice: Array to string conversion...
Any help?
Dont push and again traverse your array. just print out data in while loop. Try following code:
$items = "";
while ($row = $st->fetch()) {
$arr = explode(' - ', $row['tags']);
$items .= "<div class='tagdown'>".implode("</div>\n<div class='tagdown'>",$arr)."</div>\n";
}
echo $items;
Try like shown below
Example :
<?php
$items = "";
$str = "sky-earth-sea";
$arr = explode("-", $str);
$count = count($arr);
for($i = 0; $i < $count; $i++) {
$items .= "<div class='tagdown'>".$arr[$i]."</div></br>";
}
echo $items;
?>
explode() returns an array and you are pushing an array into an other array
its making 1 2D array you can check thar using print_r($arr);
use this
while ($row = $st->fetch()) {
$tag=explode('-', $row['tags'];
foreach($tag as $t){
array_push($arr,$t ));
}
}
You can also use fetch associative if using mysqli_connect
while ($row = $result->fetch_assoc()) {
array_push($arr, explode(' - ', $row['tags']));
}
foreach($arr as $a) {
foreach($a as $v){
$items .= "<div class='tagdown'>" . $v . "</div>\n";
}
}
echo $items;
-------------- OR -------------
$arr = array();
$items = "";
while ($row = $result->fetch_assoc()) {
$tag = explode(' - ', $row['tags']);
foreach($tag as $v){
$items .= "<div class='tagdown'>" . $v . "</div>\n";
}
}
echo $items;

Iterating array/hashmap

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";
}

Get Multiple Rows in PHP / MYSQL

I am trying to pull the image link for 10 different rows based on ids in an array. It seems to break when the query is in the loop..Any ideas how i can accomplish this?
$array = array(54, 319, 342, 298, 281, 190,178,158,138,7);
$shuffleKeys = array_keys($array);
shuffle($shuffleKeys);
$newArray = array();
foreach($shuffleKeys as $key) {
$newArray[$key] = $array[$key];
}
for($i=0;$i<=count($newArray);$i++){
$query = "SELECT logoName,logoImageLink, logoImageLink2, countryImg, logoArtist, afterText, country FROM logos WHERE id = $array($i) ";
$result = mysql_query($query);
/* fetch rows in reverse order */
for ($i = mysql_num_rows($result) - 1; $i >= 0; $i--) {
if (!mysql_data_seek($result, $i)) {
echo "Cannot seek to row $i: " . mysql_error() . "\n";
continue;
}
if (!($row = mysql_fetch_assoc($result))) {
continue;
}
$imageLink = $row['logoImageLink'];
echo "<li class=\".$array($i).\" ><img src=\".$imageLink.\" /></li>";
}
You can use the MySQL IN clause and do this in a single select.
$ids = join(',',$newArray);
$query = "SELECT logoName,logoImageLink, logoImageLink2, countryImg, logoArtist, afterText, country FROM logos WHERE id IN ($ids)";
$result = $mysqli->query($query);
while ($row = $result->fetch_assoc()) {
$imageLink = $row['logoImageLink'];
echo "<li><img src=\"$imageLink\"/></li>";
}

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