Get Multiple Rows in PHP / MYSQL - php

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

Related

Warp two row with a class after query

I want to warp every two row with a class. So I saw some guideline from here and googling and found foreach array_chunk to do this. And I tried as below which can't display any result. Without foreach its work well. Were is my wrong here please?
In the above picture that I want to do; my every two category warp with a class. And add a divider after each top category.
Here is my tried:
echo '<ul class="dropdown-menu dropdown-menu-large row">';
$sql = "SELECT id,name FROM main_cata ORDER BY id ASC";
$execute = $dbh->query("$sql");
$rowcount = $execute->num_rows ;
$row = $dbh->query($sql) ;
while ($row = $execute->fetch_assoc()) {
foreach (array_chunk($row, 2, true) as $array){
echo'<li class="col-sm-3">';
foreach($array as $rows){
echo '<ul><li class="dropdown-header">'.$rows->name.'</li>';
$sql2 = "SELECT id,name,page FROM catagory WHERE m_cata = '".$rows->id."' ORDER BY id ASC";
$execute2 = $dbh->query("$sql2");
$rowcount2 = $execute2->num_rows ;
$row = $dbh->query($sql) ;
while ($row = $execute2->fetch_assoc()) {
$cid = $row['id'];
$cname = $row['name'];
$page = $row['page'];
echo '<li>'.$cname.'</li>';
}
echo '<li class="divider"></li></ul>';
}
echo '</li>';
}
}
echo '</ul>';
while ($row = $execute->fetch_assoc()) {
fetch_assoc returns 1 row (id, name) from the query, then you are using the result and spliting in 2 (https://secure.php.net/manual/pt_BR/mysqli-result.fetch-assoc.php), What you can do is, make a counter instead of the array chunk that resets every time it reachs 2.
foreach (array_chunk($row, 2, true) as $array){
The content of $row is, for example, array('id' => 1, 'name' => 'Category 1').
foreach($array as $rows){
You are iterating again without needing to.
A simple version:
counter = 0;
echo "<ul>";
while (row = execute->fetch_assoc()) {
if (counter == 0) {
echo "init li";
}
echo "subinit li";
get subcategories
while (row2 = execute2->fetch_assoc()) {
print content
}
echo "subend li";
if (counter == 2) {
counter == 0;
echo "end li";
} else {
counter++;
echo "divider";
}
}
echo "</ul>";

mysql php alphabetical listing with index-letters

I have a mysql database (plattenkiste) with bandnames
id | kuenstler
1 | Aerosmith
2 | Beck
3 | Metallica
4 | Slayer
5 | Zappa, Frank
Now i want an output in alphabetical Order with directlinks and index-letters, showing only the index-letters with bandnames.
Like
Directlinks: A|B|M|S|Z
A
Aerosmith
B
Beck
M
Metallica
S
Slayer
Z
Zappa, Frank
I have a "quick and dirty" code that does what i want:
$abc = "0123456789AÄBCDEFGHIJKLMNOÖPQRSTUÜVWXYZ";
for($i=0; $i<strlen($abc); $i++){
$char = substr($abc, $i, 1);
$query = "SELECT kuenstler FROM plattenkiste WHERE kuenstler LIKE '$char%'";
$ergebnis = $mysqli->query($query);
$num = $ergebnis->num_rows;
if ($num != 0){
echo "<a href='#$char'>$char</a> | ";
}}
for($i=0; $i<strlen($abc); $i++){
$char = substr($abc, $i, 1);
$query = "SELECT kuenstler FROM plattenkiste WHERE kuenstler LIKE '$char%'";
$ergebnis = $mysqli->query($query);
$num = $ergebnis->num_rows;
if ($num != 0){
echo "<h4 id='$char'>$char</h4>";
while($row = $ergebnis->fetch_object()){
echo $row->kuenstler . '<br />';
}
}
}
Is there a shorter, more clean way to get this done?
You can have MySQL do much of the grunt for you, by both sorting the results and (for the initial list) providing only the initial characters. Then you merely need have PHP loop over the resultsets and output the necessary HTML (for the second list, adding a header whenever it encounters a new initial character).
If your plattenkiste.kuenstler column has a case sensitive collation then you may wish to explicitly specify a case insensitive collation in the ORDER BY clauses.
$query = 'SELECT DISTINCT UCASE(LEFT(kuenstler, 1)) AS char
FROM plattenkiste
ORDER BY kuenstler';
$ergebnis = $mysqli->query($query);
if ($ergebnis) {
while ($row = $ergebnis->fetch_object()) {
$char = htmlentities($row->char);
echo "<a href='#$char'>$char</a> | ";
}
}
$query = 'SELECT kuenstler FROM plattenkiste ORDER BY kuenstler';
$ergebnis = $mysqli->query($query);
if ($ergebnis) {
$row = $ergebnis->fetch_object();
while ($row) {
$c = $row->kuenstler[0];
$char = htmlentities(strtoupper($c));
echo "<h4 id='$char'>$char</h4>";
do {
echo htmlentities($row->kuenstler), '<br />';
} while ($row = $ergebnis->fetch_object() and $row->kuenstler[0] == $c);
}
}
I've had to do things like this before as well. The easiest option is to just loop through your results and build a series of arrays...
$artists = $mysqli->query(
'SELECT kuenstler FROM Lattenkiste ORDER BY kuenstler ASC'
);
$letters = array();
// get the results and sort them into arrays
while($artist = $artists->fetch_object()) {
// ge the first letter
$firstLetter = strtoupper($artist->kuenstler{0});
// if we don't have a key for it, make it
if (!isset($letters[$firstLetter])) {
$letters[$firstLetter] = array();
}
$letters[$firstLetter] = $artist->kuenstler;
}
// output the headings
echo '<ul class="directlinks">';
foreach (array_keys($letters) as $letter) {
echo '<li>' . $letter . '</li>';
}
echo '</ul>';
// now output each set of letters
foreach (array_keys($letters) as $letter) {
echo '<h4 id="' . $letter . '">' . $letter . '</h4>';
echo '<ul class="artists">';
foreach ($letters[$letter] as $kuenstler) {
echo '<li>' . $kuenstler . '</li>';
}
echo '</ul>';
}

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

Display php nested array results continuously in two column table

I have a nested array grouping three other arrays: $online, $busy and $offline, in order to display results in this exactly order.
$conteudo = array($online, $ocupado, $offline);
The desired result would be a table in two columns to display results in continuous flow like this:
online1 | online2
online3 | busy1
busy2 | offline1
offline2| offline3
offline4|
I've been trying lots of foreach loops and playing around changing the html tags, but the closest I can arrive of the desired result is this:
<table width='100%' cellpadding='5' border="1">
<?php
$i = 1; //contador de colunas
$max_colunas = 2; // numero de colunas
foreach ($conteudo as $row) {
echo "<tr>";
foreach ($row as $col) {
foreach ($col as $cell) {
if ($i == 1) {
echo "<td>" . $cell . "</td>";
} elseif ($i == $max_colunas){
echo "<td>" . $cell . "</td></tr>";
$i = 0;
} else {
echo "<td>" . $cell . "</td>";
}
$i++;
}
}
echo "</tr>";
}
This code will output a table like this:
onine1 | online2 |online3
busy1 | busy2 |
offline1|offline2 |offline3|offline4
I can't find out why it ignores completely $max_colunas, seems like it prints all the elements inside the array in row.
If I remove lines:
echo "<tr>";
echo "</tr>";
from beginning and end of foreach it will output all in a row like this:
onine1 | online2 |online3 | busy1 | busy2 |offline1|offline2 |offline3|offline4
Any suggestions to get the desired output format will be so appreciated.
Edited on 17/01:
This is how I'm getting the arrays from:
//group people
$online = array(); //group online
$ocupado = array(); //group ocupado
$offline = array(); //group offline
//select people to group
$atendentes = mysql_query("SELECT nome FROM atendentes ORDER BY nome") or die(mysql_error());
$atendentedb = array();
//put selected people in array
while ($row = mysql_fetch_assoc($atendentes)) {
$atendentedb[] = array('nome' => $row["nome"], 'online' => false);
}
//take people online now and check in selected people
$names = modWhosonlineCustom::getOnlineUserNames();
foreach ($names as $name):
//foreach ($atendentedb as $atendente):
for($i = 0; $i < count($atendentedb); $i++):
$att = strtolower($name->username);
if ($atendentedb[$i]['nome'] == $att):
$atendentedb[$i]['online'] = true;
break;
endif;
endfor;
endforeach;
//check each selected people
foreach ($atendentedb as $atendente) :
//save temporary data
$online_ = $atendente['online'];
$nome_ = $atendente['nome'];
//if selected people online
if ($online_) :
//take status to show
$status = mysql_query("SELECT status FROM atendentes WHERE nome = '$nome_' LIMIT 1") or die(mysql_error());
while ($row = mysql_fetch_assoc($status)):
$statusdb = $row["status"];
endwhile;
//verify and save deppending on status
switch ($statusdb):
//if online
case "disponivel":
$descricao = mysql_query("SELECT hp_online FROM atendentes WHERE nome = '$nome_' LIMIT 1") or die(mysql_error());
while ($row = mysql_fetch_assoc($descricao)):
$online[] = array('info'=>$row['hp_online']);
endwhile;
break;
//if busy
case "ocupado":
$descricao = mysql_query("SELECT hp_busy FROM atendentes WHERE nome = '$nome_' LIMIT 1") or die(mysql_error());
while ($row = mysql_fetch_assoc($descricao)):
$ocupado[] = array('info'=>$row['hp_busy']);
endwhile;
break;
endswitch;
//if offline
else:
$descricao = mysql_query("SELECT hp_offline, horario FROM atendentes WHERE nome = '$nome_' LIMIT 1") or die(mysql_error());
while ($row = mysql_fetch_assoc($descricao)):
$offline[] = array('info'=>$row['hp_offline'], 'horario'=>$row['horario']);
endwhile;
endif;
endforeach;
EDITED
So after following help instructions from DaveRandom I got to this code, which is really a drop away from the right format, except for the "mysterious" behaviour with results coming from array $offline, that are displaying all in "block" (all cells in a row, or all cells in a column) while the other arrays are displaying perfectly(??).
//group people
$online = $ocupado = $offline = array();
//select people to group
$query = "SELECT nome, status, hp_online, hp_busy, hp_offline, horario
FROM atendentes
ORDER BY nome";
$atendentes = mysql_query($query) or die(mysql_error());
$atendentedb = array();
// put selected people in array
while ($row = mysql_fetch_assoc($atendentes)) {
$atendentedb[strtolower($row['nome'])] = array_merge($row, array('online' => FALSE));
}
//take people online now and check in selected people
$names = modWhosonlineCustom::getOnlineUserNames();
foreach ($names as $name) {
$uname = strtolower($name->username);
if (isset($atendentedb[$uname])) $atendentedb[$uname]['online'] = TRUE;
}
//check each selected people
foreach ($atendentedb as $name => $atendente) {
//if selected people online
if ($atendente['online']) {
//verify and save deppending on status
switch ($atendente['status']) {
//if online
case 'disponivel':
$atendentedb[$name]['info'] = $online[] = $atendente['hp_online'];
break;
//if busy
case 'ocupado':
$atendentedb[$name]['info'] = $ocupado[] = $atendente['hp_busy'];
break;
}
//if offline
} else {
$atendentedb[$name]['info'] = $offline[] = $atendente['hp_offline'];
$atendentedb[$name]['info'] = $offline[] = $atendente['horario'];
}
}
//*******Display Results
$conteudo = array_merge($online, $ocupado, $offline);
$max_colunas = 2; // numero de colunas
// Start the table
echo '<table width="100%" cellpadding="5" border="1">'."\n";
// Loop all the objects
for ($i = 0, $j = 0; isset($conteudo[$i]); $i++) {
if ($j == 0) {
// Output the beginning of a row
echo " <tr>\n";
}
// Always output a data cell
echo " <td>$conteudo[$i]</td>\n";
if (++$j >= $max_colunas) {
// Output the end of a row and reset the cell counter
echo " </tr>\n";
$j = 0;
}
}
if ($j) {
// We may end up with an incomplete row at the end, so pad it with empty cells
// and close the row
while ($j++ < $max_colunas) {
echo " <td></td>\n";
}
echo " </tr>\n";
}
// Close the table
echo "</table>";
I would say that the first thing to do here is to "flatten" the array - having the multiple dimensions makes this a lot more complicated than it needs to be. So rather than creating $conteudo like this:
$conteudo = array($online, $ocupado, $offline);
...do this instead:
$conteudo = array_merge($online, $ocupado, $offline);
Then you can do this:
$max_colunas = 2; // numero de colunas
// Start the table
echo '<table width="100%" cellpadding="5" border="1">'."\n";
// Loop all the objects
for ($i = 0, $j = 0; isset($conteudo[$i]); $i++) {
if ($j == 0) {
// Output the beginning of a row
echo " <tr>\n";
}
// Always output a data cell
echo " <td>$conteudo[$i]</td>\n";
if (++$j >= $max_colunas) {
// Output the end of a row and reset the cell counter
echo " </tr>\n";
$j = 0;
}
}
if ($j) {
// We may end up with an incomplete row at the end, so pad it with empty cells
// and close the row
while ($j++ < $max_colunas) {
echo " <td></td>\n";
}
echo " </tr>\n";
}
// Close the table
echo "</table>";
See it working
EDIT
Try this code for generating your arrays. Note that the structure of your output arrays has been altered to fit my code sample above - if you use this data anywhere else in you script, you will need to modify that code as well. I have modified this so that there is only one database query, which would seem to be all that is required. I have also modified it so that the $atendentedb holds all the user data, including the status and info keys, and all rows contain a horario key.
Because of the fact that your input arrays originally contained more data than the ones created by this code will, the code may need further modification - but try this out and see how you get on.
//group people
$online = $ocupado = $offline = array();
//select people to group
$query = "SELECT nome, status, hp_online, hp_busy, hp_offline, horario
FROM atendentes
ORDER BY nome";
$atendentes = mysql_query($query) or die(mysql_error());
$atendentedb = array();
// put selected people in array
while ($row = mysql_fetch_assoc($atendentes)) {
$atendentedb[strtolower($row['nome'])] = array_merge($row, array('online' => FALSE));
}
//take people online now and check in selected people
$names = modWhosonlineCustom::getOnlineUserNames();
foreach ($names as $name) {
$uname = strtolower($name->username);
if (isset($atendentedb[$uname])) $atendentedb[$uname]['online'] = TRUE;
}
//check each selected people
foreach ($atendentedb as $name => $atendente) {
//if selected people online
if ($atendente['online']) {
//verify and save deppending on status
switch ($atendente['status']) {
//if online
case 'disponivel':
$atendentedb[$name]['info'] = $online[] = $atendente['hp_online'];
break;
//if busy
case 'ocupado':
$atendentedb[$name]['info'] = $ocupado[] = $atendente['hp_busy'];
break;
}
//if offline
} else {
$atendentedb[$name]['info'] = $offline[] = $atendente['hp_offline'].' '.$atendente['horario'];
}
}
I think you should update counter inside
foreach ($col as $cell) { } so it will count elements of the inner arrays and also move decalration of <tr> there.
if (!is_int($i/2)) { print '<tr><td>' }

PHP foreach() not looping through data as expected?

I have the foillowing PHP code, but I can't get it to work?
This is the main PHP file:
function get_data() {
$query = 'SELECT title, article FROM submissions';
$result = mysql_query($query);
$i = 0;
while ($row = mysql_fetch_assoc($result)) {
++$i;
$row['i'] = $i;
$row['title'] = limittext($row['title'], 15);
}
return $row; //perhaps because $row is not return all?
}
$data = get_data();
require('template/data.inc.php');
?>
and this is template/data.inc.php:
<?php
foreach ($data as $value):
echo $data['i'].'<br>';
echo $data['title'].'<br>';
echo $data['article'].'<br>';
endforeach;
?>
template/data.inc.php is meant to output something like:
1 How to get your site on Google?
Text...
2 Secrets of SEO Revealed
Text...
My guess is get_data() is not returning the array() in a form which is supported within the foreach? - as its currently giving an error.
Here is your problem:
$i = 0;
while ($row = mysql_fetch_assoc($result)) {
++$i;
$row['i'] = $i;
$row['title'] = limittext($row['title'], 15);
}
On every iteration, $row is being reset to current record, and in the end mysql_fetch_assoc will turn it to FALSE. You have to put each $row into auxiliary array and return it as whole resultset:
$i = 0;
$returnArray = array();
while ($row = mysql_fetch_assoc($result)) {
++$i;
$row['i'] = $i;
$row['title'] = limittext($row['title'], 15);
$returnArray[] = $row;
}
return $returnArray;
ANd in your template use $value to get details for each row:
foreach ($data as $value):
echo $value['i'].'<br>';
echo $value['title'].'<br>';
echo $value['article'].'<br>';
endforeach;
The way in which you're building $row and returning it
$i = 0;
while ($row = mysql_fetch_assoc($result)) {
++$i;
$row['i'] = $i;
$row['title'] = limittext($row['title'], 15);
}
return $row;
}
You'll only EVER have the LAST iteration of $row set ... if that's what you want? In other words, $row will only continue a single value.
Your loop continues until $row has an value that is evaluated as false:
while ($row = mysql_fetch_assoc($result)) {
and then you return $row so you always return null or false!
replace
$row['title'] = limittext($row['title'], 15);
with
$row['title'] = limittext($row['title'], 15);
$result[]=$row;
and
return $row;
with
return $result;

Categories