MySQL Select Random from All but not double time - php

i want to show Random Item with Select by WHERE code = $Code
But if he finds like 10 Items, i want to show only 1 by 1. All 10 must show in a Row, Random Order with a 5 seconds timer. The Problem is, i dont will show the same Item again and again. If the 10 Items are done, he must look again to database and start again
I already tried to do it with putting all in array but my skills are low :(
Thats my try...
$result = $db->query( 'SELECT * FROM ads WHERE zipcode = "'.$zipcode.'";');
while($row = $result->fetch_assoc()) {
$data[] = $row;
}
$count = mysqli_num_rows($result);
for($i = 0; $i < $count; $i++) {
$random = rand(0, $count);
$count -= 1;
$result[] = $data[$random];
echo json_encode($data);
unset($data[$random]);
}

Related

Even distribution of PHP arrays across columns

So, I want to distribute evenly lists across 3 columns. The lists cannot be broken up or reordered.
At the moment, I have 5 lists each containing respectively 4, 4, 6, 3 and 3 items.
My initial approach was:
$lists = [4,4,6,3,3];
$columns = 3;
$total_links = 20;
$items_per_column = ceil($total_links/$columns);
$current_column = 1;
$counter = 0;
$lists_by_column = [];
foreach ($lists as $total_items) {
$counter += $total_items;
$lists_by_column[$current_column][] = $total_items;
if ($counter > $current_column*$links_per_column) {
$current_column++;
}
}
Results in:
[
[4],
[4,6],
[3,3]
]
But, I want it to look like this:
[
[4,4],
[6],
[3,3]
]
I want to always have the least possible variation in length between the columns.
Other examples of expected results:
[6,4,4,6] => [[6], [4,4], [6]]
[4,4,4,4,6] => [[4,4], [4,4], [6]]
[10,4,4,3,5] => [[10], [4,4], [3,5]]
[2,2,4,6,4,3,3,3] => [[2,2,4], [6,4], [3,3,3]]
Roughly what you need to do is loop over the number of columns within your foreach(). That will distribute them for you.
$numrows = ceil(count($lists) / $columns);
$thisrow = 1;
foreach ($lists as $total_items) {
if($thisrow < $numrows){
for($i = 1; $i <= $columns; $i++){
$lists_by_column[$i][] = $total_items;
}
}else{
//this is the last row
//find out how many columns need to fit.
//1 column is easy, it goes in the first column
//2 columns is when you'll need to skip the middle one
//3 columns is easy because it's full
}
$thisrow++;
}
This will be an even distribution, from left to right. But you actually want a modified even distribution that will look symmetrical to the eye. So within the foreach loop, you'll need to keep track of 1.) if you're on the last row of three, and 2.) if there are 2 remainders, to have it skip col2 and push to col3 instead. You'll need to set that up to be able to play around with it,...but you're just a couple of logic gates away from the land of milk and honey.
So, I ended up using this code:
$lists = [4,4,6,3,3];
$columns = 3;
$total_links = 20;
$items_per_column = ceil($total_links/$columns);
$current_column = 1;
$lists_by_column = [];
for ($i = 0; $i < count($lists); $i++) {
$total = $lists[$i];
$lists_by_column[$current_column][] = $lists[$i];
//Loop until reaching the end of the column
while ($total < $items_per_column && $i+1 < count($lists)) {
if ($total + $lists[$i+1] > $items_per_column) {
break;
}
$i++;
$total += $lists[$i];
$lists_by_column[$current_column][] = $lists[$i];
}
//When exiting the loop the last time we need another break
if (!isset($lists[$i+1])) {break;}
//If the last item goes onto the next column
if (abs($total - $items_per_column) < abs($total + $lists[$i+1] - $items_per_column)) {
$current_column++;
//If the last item goes onto the current column
} else if ($total + $lists[$i+1] > $items_per_column) {
$i++;
$lists_by_column[$current_column][] = $lists[$i];
$current_column++;
}
}

PHP Count Generated Results From Loop

I have this for loop that generates 10 results:
<?php
include "dbconnect.php";
$table = "SELECT id FROM players ORDER BY RAND()* ( 1 / percentage)";
for ($i = 0; $i < 10; $i++){
$result[0] = mysql_fetch_array(mysql_query($table));
foreach ($result as $winner){
echo $winner[0] . " ";
}
}
?>
It generates a result like:
10 10 11 9 13 11 10 12 8 12
My question is how do I count the generation? For the above example it would be:
8's = 1, 9's = 1, 10's = 3, 11's = 2, 12's = 2, 13's = 1.
I basically want to count the amount of specific results generated. Sorry if i'm not making much sense.
You need to get off of MySQL functions and check out PDO or MySQLI at a minimum. But for the meat of the question:
Don't run a query, full or limited in the loop
Look at the LIMIT clause in the query
array_count_values will count the values. You can loop it and echo or whatever
Example:
$table = "SELECT id FROM players ORDER BY RAND()*(1/percentage) LIMIT 10";
$result = mysql_query($table);
while($row = mysql_fetch_array($result)) {
$winner[] = $row[0];
}
echo implode(' ', $winner);
foreach(array_count_values($winner) as $number => $count) {
$output = "$number's = $count";
}
echo implode(', ', $output);
You're existing code to make the random choice work would look like (LIMIT 1):
$table = "SELECT id FROM players ORDER BY RAND()*(1/percentage) LIMIT 1";
for($i = 0; $i < 10; $i++){
$result = mysql_fetch_array(mysql_query($table));
$winner[] = $row[0];
}
echo implode(' ', $winner);
if you check the php manual:
http://php.net/manual/en/function.mysql-query.php
then try something like this:
while ($row = mysql_fetch_assoc($table)) {
echo $row['column_name'];
echo $row['column_name'];
//.. you get the idea
}
The id is usually the first column in a database table. This is why you are just getting the id. You need to access each row in the same way you access arrays.
I should point out that the mysql library is deprecated. So you should consider using something like PDO instead.

Code not working, Sorting MySQL results into pages

Ok so iv got this code which is suppose to bring back all my results from my database and display 5 results per page. At the moment I have 12 results in my database and it is only showing 10, it wont show the 3rd page as there isnt 5 results to display. Here is my code
//$_GET['page'] is to get the current page opened
if (isset($_GET["page"])) { $page = $_GET["page"]; } else { $page=1; };
$results_per_page = "5"; //number of results I want displayed per page
$start_from = ($page-1) * $results_per_page;
$query = "SELECT * FROM items WHERE subcat = '$conditions' LIMIT $start_from, $results_per_page";
$result = mysql_query($query) or die("Unable to verify user because : " . mysql_error());
while ($row_condition=mysql_fetch_array($result)) {
//Display the results here
}
//Count number of results from database and work out how
//many pages I need to display all the results.
$result1 = mysql_query("SELECT * FROM items WHERE subcat = '$conditions'");
$num_rows = mysql_num_rows($result1);
$num_pages = $num_rows / $results_per_page;
if ($num_rows > $results_per_page){
?>
<div id="pagenum">
<?php
//This creates and displays the page numbers for the user to select
foreach( range( 1, $num_pages) as $i) {
if ($thepage == $i){
echo '<b>' . $i . '</b>';
}else{
echo '' . $i . '';
}
//This places a line between each number of pages
if ($i == $num_pages){
}else{
echo " | ";
}
}
?>
</div>
<?php
}else{ echo "Test";}
?>
So can anyone see a problem with this?, so I have 12 entries in my database. However im only getting 2 pages, 5 on each page and im not getting the 3rd page as there are only 2 results left and it seems to want 5 to finish it.
Thanks
You need to use ceil function:
$num_pages = ceil($num_rows / $results_per_page);
I think your biggest problem is that PHP will make give you a float when you divide two numbers that don't result in a whole one.
$one = 12;
$two = 5;
$result = $one / $two; // That will result in 2.4
Now, the issue is you, technically, have three pages, but PHP will NOT treat the .4 pages as a page, so when you loop through it will technically only do it twice. Since your using range and it's 2.4, it seems like PHP is rounding down. I would suggest something like this:
$result1 = mysql_query("SELECT * FROM items WHERE subcat = '$conditions'");
$num_rows = mysql_num_rows($result1);
$num_pages = ceil($num_rows / $results_per_page);
if ($num_rows > $results_per_page){
for($i = 0; $i < $num_pages; $i++) {
ceil() will force that division to round up every time, which will always give you that extra page.
Give it a shot! Let me know if it fixes your issue!

PHP loop to sort table

I'm querying a database for names that are numbered 1-26 alphabetically. I have the following code, but since HTML is structured tr then td, the table appears alphabetically by row as opposed to by column. How can I make it appear in order by column?
$query = mysql_query("SELECT name FROM people WHERE main=1 ORDER BY id");
$i = 0;
while($result = mysql_fetch_array($query)) {
$name = $result['name'];
if ($i % 5 == 0) echo "<tr>\n";
echo "<td width=\"150\">";
echo "".$name."<br />";
echo "</td>\n";
$i++;
if ($i % 5 == 0) echo "</tr>\n";
};
alpha beta charlie
delta echo foxtrot
vs.
alpha charlie echo
beta delta foxtrot
Also, I'm open to reworking the code if there's a more efficient way.
You could just access the output array in strides. Compute how many rows you need as the number of results divided by 5, and use the row count as the stride.
$ncols = 5;
$nrows = $nresults / $ncols + ($nresults % $ncols == 0 ? 0 : 1);
for ($i = 0; $i < $nrows; $i++)
{
// start row
for ($j = 0; $k < $ncols; $j++)
{
// print $results[$nrows * $j + $i]
}
// end row
}
You'll have to transfer your query results into an array $results first. Since you'll have to know the total number of results, this is sort of mandatory, though I'd be curious if anyone has a solution that can work while fetching the results.
Update: See Justin's answer for a cool solution that grows the output while fetching the query results line by line. Since it's currently being worked on, here's a summary (credits to Justin):
$nresults = mysql_num_rows($query);
$ncols = 5;
$nrows = (int) ceil($nresults / $ncols);
$i = 0; $cols = array_fill(0, $nrows, "");
while ($result = mysql_fetch_array($query))
$cols[$i++ % $nrows] .= "<td>$result['name']</td>";
echo "<tr>" . implode("</tr><tr>", $cols) . "</tr>";
Edit:
After the discussion in the comments between myself, Kerrek SB and the OP bswinnerton, the following code seems to be the most effective:
$columns = 3;
$rowcount = mysql_num_rows($query);
$rows = ceil($rowcount / $columns);
$rowdata = array_fill(0, $rows, "");
$ctr = 0;
while ($result = mysql_fetch_array($query))
$rowdata[$ctr++ % $rows] .= '<td>'.$result['name'].'</td>';
echo '<tr>'.implode('</tr><tr>',$rowdata).'</tr>';
This will create three columns, filled vertically (my original answer would create three rows). It also properly initializes the array (preventing PHP warnings), yields a correct row count for result counts that aren't divisible by the column count, and incorporates Kerrek's clever "calc-row-in-the-subscript" trick.
Original Post:
You could use arrays and implode() This way, you only have to make one pass through your results:
$row = 0;
$rows = 3;
$rowdata = array();
while($result = mysql_fetch_array($query))
{
if ($row >= $rows) $row = 0;
$rowdata[$row++] .= '<td>'.$result['name'].'</td>';
}
echo '<tr>'.implode('</tr><tr>',$rowdata).'</tr>';

Empty results when I store records in array, repeat them to reach certain nr and use foreach to display them

This is what my code does:
it gets 4 rows from my table, stores them in an array, repeats them untill they reach 20 inside that array then echo's them whit a foreach loop... problem is i get an empty result at the end of each foreach cycle of the 4 results.
$result = mysql_query("SELECT * FROM ".$table."");
$row_nr = mysql_num_rows($result); // Find out how many rows I have in the table, lets say 4
while($rows = mysql_fetch_assoc($result)){
$arrayrows[] = $rows; // Put my 4 rows in the array
}
// Now I multiply nr. of rows to reach desired number which is 20
$dbRow=0;
for($n=0; $n <= 20; $n++)
{
if($dbRow > $row_nr) $dbRow = 0;
$fullarrayrows[$n] = $arrayrows[$dbRow];
$dbRow++;
}
// after some php pagination code I slice the array:
$arrayslice = array_slice($fullarrayrows, $offset, $rowsperpage);
// Now i display my array
foreach($arrayslice as $slice)
{
echo ''.$slice['name'].'';
echo '<br />';
}
Problem is I get some empty records in the foreach
name1name2name3name4HERE I GET THE EMPTY ENTRYname1name2name3name4AGAIN I GET THE EMPTY ENTRY
... and so on, at the end of each cycle
Thank you very much , please give me an ideea of what's wrong:)
$dbRow indexes start at 0 and end at 3
but $row_nr equals 4
so change this line
if($dbRow > $row_nr) $dbRow = 0;
to
if($dbRow >= $row_nr) $dbRow = 0;

Categories