PHP infinitely repeats first MySQL result - php

I have this code that I've been working on and when I run it I get the first result 10 times (it used to repeat infinitely until I added the if statement). It's supposed to return the first 10 results. I've looked at a couple other similar questions but none of the solutions on those worked here. Can anyone see what I'm missing?
<?php
$link = mysql_connect('XXXXXXXXX.com', 'XXXXXX', 'XXXXX');
$db = mysql_select_db('a1007515_troop1', $link);
$i = 1;
while($row = mysql_fetch_array(mysql_query('SELECT * FROM `posts` ORDER BY `pid` DESC LIMIT 10;')))
{
$authinfo = mysql_fetch_array(mysql_query('SELECT * FROM `users` WHERE `id` = '.$row['aid'].' LIMIT 1'));
echo '
<div class="content">
<h1 class="title">'.$row['title'].'</h1>
<span class="authinfo">This post was made by '.$authinfo['name'].'<i>('.$authinfo['username'].')</i> on '.$row['date'].'.</span>
<p class="txt">'.$row['content'].'</p>
</div>';
if ($i == 10) { break; }
++ $i;
}
mysql_close($link);
?>

Maybe try simplifying things, try and stick to doing one thing per line, rather than trying to compress it.
Calling mysql_query in the while will repeat that query every time the while loop is run, rather than fetch the next result. Running another mysql query while iterating through the results of another one can also cause problems.
$link = mysql_connect('mysqlwebhost', 'user', 'pass');
$db = mysql_select_db('dbname', $link);
$result = mysql_query('SELECT * FROM `posts` p, `users` u WHERE u.id = p.aid ORDER BY `pid` DESC LIMIT 0,10;');
while ($row = mysql_fetch_assoc($result)) {
echo '
<div class="content">
<h1 class="title">'.$row['title'].'</h1>
<span class="authinfo">This post was made by '.$row['name'].'<i>('.$row['username'].')</i> on '.$row['date'].'.</span>
<p class="txt">'.$row['content'].'</p>
</div>';
}
mysql_close($link);
You may also wish to avoid using mysql_* functions as they have been deprecated. Have a look at either mysqli or PDO.

The problem is that you execute the SQL statement again each time you test the while() condition:
while($row = mysql_fetch_array(mysql_query('SELECT * FROM `posts` ORDER BY `pid` DESC LIMIT 10;')))
{
...
}
The above code will execute this function every time the while() is evaluated:
mysql_query('SELECT * FROM `posts` ORDER BY `pid` DESC LIMIT 10;')
Instead use:
$stmt = mysql_query(...) or die(mysql_error());
while($row = mysql_fetch_array($stmt)) {
...
}
Next you should use a join. You are following a pattern that "over queries" the database.
You only need the following SQL and a single loop:
SELECT u.*
FROM `posts` p
JOIN `users` u
ON u.id = p.aid
ORDER BY `pid` DESC
LIMIT 0,10;

Related

MySQL: Query on another query result and return both results?

I am using following 'php' and 'MySQL' code to list most recent topics from my database and to list related titles below each of those titles...
// First Query
$query= mysql_query("SELECT * FROM my_table ORDER BY id DESC limit 0,20");
$result = mysql_query($query)
while($row = mysql_fetch_array($result)){
echo "Main Topic: ".$row['title'];
$main_title = $row['title'];
echo "Related to this Topic:";
// Second Query
$related_query= mysql_query("
SELECT * MATCH (title)
AGAINST('$main_title'IN NATURAL LANGUAGE MODE)AS
score FROM my_table MATCH(title) AGAINST('$main_title'IN NATURAL LANGUAGE MODE)
HAVING score > 10 ORDER BY score DESC
");
$related_result = mysql_query($related_query)
while($related_row = mysql_fetch_array($related_result)){
echo "<br>". $related_row['title'];
}
}
This works fine. But the problem is that it uses a MySQL queries within a loop. (second query runs 20 times) I've read it is not a good programming practice because it uses server resources heavily.
So, is there a way to do this with just one query or two queries without having to run a query within a loop?
Thank you
First off, STOP USING mysql_*() functions. They have been deprecated for years.
Second, once you start using a reasonable database interface like PDO or even just mysqli, you can do prepared queries. The query can be prepared outside the loop, which will save resources and reduce the time taken.
Third, it's possible this could be done with one query, but would need DB structure posted to be certain.
EDIT: here's some untested PDO code:
<?php
try {
$db = new PDO("mysql:host=localhost;dbname=my_database", "user", "pass");
} catch(PDOException $e) {
echo $e->getMessage();
exit;
}
$result = $db->query("SELECT * FROM my_table ORDER BY id DESC LIMIT 20");
$result->setFetchMode(PDO::FETCH_ASSOC);
$stmt = $db->prepare("SELECT * MATCH (title) AGAINST (? IN NATURAL LANGUAGE MODE) AS score FROM my_table MATCH (title) AGAINST (? IN NATURAL LANGUAGE MODE) HAVING score > 10 ORDER BY score DESC");
while ($row = $result->fetch()) {
echo "Main Topic: $row[title]";
$params = array($row["title"], $row["title"]);
$result2 = $stmt->execute($params);
$result2->setFetchMode(PDO::FETCH_ASSOC);
while ($row2 = $result2->fetch()) {
echo "<br>$row2[title]";
}
}

MySQL resource's fetched row count

Looked all over and couldn't find a way to do this.
I want to count the amount of results from a query that's being looped.
for example...
If I have 5 pokemon, and 2 of them are Pikachus, it will display 4 pokemon but with a 2 next to the pikachu, I want to count the number of different pokemon you own not including the secound Pikachu.
this is what I have so far.
<div class="reg-box3" style="width:100%; margin:5px;">
<?php
$result = mysql_query("SELECT *, COUNT(*) number FROM user_pokemon WHERE belongsto='". $_SESSION{'username'}."'AND (slot='0') GROUP BY pokemon ORDER BY pokemon");
while($row = mysql_fetch_array($result))
{
$sql2 = "SELECT * FROM pokemon WHERE name='".$row['pokemon']."'";
$result2 = mysql_query($sql2) or die(mysql_error());
$battle_get2 = mysql_fetch_array($result2);
?>
<div style="width: 24.5%; float: left;padding:.1%; ">
<?php
$idd= mysql_real_escape_string($row['id']);
$iddd = strip_tags($idd);
?>
You are missing AS from your query before number. If you add it, the desired count will be stored in the $result['number'] variable.
By the way you might find mysql_num_rows() easier in this case. Just call it on your MySQL resource, and it returns the number of rows fetched.
Edit: using mysql_num_rows is this simple: $count = mysql_num_rows($result);
<?php
$result = mysql_query(
<<<SQL
SELECT
`t2`.`name` AS `name`,
COUNT(*) AS `count`
FROM `user_pokemon` AS `t1`
JOIN `pokemon` AS `t2` ON (`t1`.`pokemon` = `t2`.`name`)
WHERE
`t1`.`belongsto` = '{$_SESSION{'username'}}'
AND `t1`.`slot` = 0
GROUP BY `name`
ORDER BY `name`
SQL
);
while($row = mysql_fetch_array($result)){
var_dump($row);
}
?>
No guarantees it works as I don't know your table structure and not sure if I got it right from your queries.
PS: Don't count records with mysql_num_rows(). It requires transferring data from the server while, if you do it directly in MySQL, you get the maximum of performance with the most ease of use.

how to count the total comment

I want to count the total comment/post posted on my page. i have a table in my database named test. within table i have a column named comment, where every post is been stored. the problem am having is to echo out the total number of comment and keep updating as viewers keep on posting there comment and i tried using this code
<?php
$handle = mysql_query("SELECT `comment`, COUNT(*) AS `count`
FROM test GROUP BY `comment` ");
if ($handle) {
$results = mysql_fetch_assoc($handle);
echo ($results[0]['count'] + $results[1]['count']);
}
?>
but it keep on echoing out 0. pls help me out.
Try this:
list($count) = mysql_fetch_row(mysql_query("select count(*) from `test`"));
echo $count;
Alternatively, if you are already running a query to get some comments, you can try this:
$sql = mysql_query("select sql_calc_found_rows * from `test` order by `id` desc limit 10");
// ^ Get the 10 most recent comments
list($count) = mysql_fetch_row(mysql_query("select found_rows()"));
// this avoids having to run the entire query again, great for efficiency!
while($comment = mysql_fetch_assoc($sql)) var_dump($comment); // just an example

Merge Two MySQL Queries in one Array

Purpose of this query is to retrieve a true image plus 3 random generated images from same table, then show them randomly. User(child) have to select correct image.
Thanks
$sql= "SELECT * FROM `login` WHERE `user` = '$word'";
" UNION"
"SELECT * FROM `login` WHERE `user` != '$word' ORDER BY RAND() LIMIT 3";
$row2=mysql_query($sql);
$i=1;
while ($r = mysql_fetch_array($row2))
{
echo '<td> ';
echo '<img src="sigg/'.$r['img'].'" width="130" height="130" /><br>';
echo $r['user'];
echo '</td>';
$i++;
}
Use the UNION clause:
$sql = "(SELECT * FROM `login` WHERE `user` = '$word')";
$sql.= " UNION";
$sql.= " (SELECT * FROM `login` WHERE `user` != '$word' ORDER BY RAND() LIMIT 3)";
$sql.= " ORDER BY RAND()";
To get the results you can use for example MySQLi (poseted before OP added his code with mysql_* functions):
$MySQL=new mysqli("localhost", "username", "password", "database");
$query = $MySQL -> query($sql);
while ($entry = $query -> fetch_row())
{
// $entry is an array with the results, use for example:
echo $entry[0]; // will return the first column of your table
echo $entry[1]; // will return the second column of your table
// try also:
var_dump($entry); // outputs everything for testing purposes
}
Please, don't use the mysql_* functions, they are deprecated and will be removed in the future versions of PHP. Use MySQLi or PDO instead. See Why shouldn't I use mysql_* functions in PHP? for more details.
Your request is not clear enough to provide a solid answer, so I'll try to answer it the best I can.
You should use Union in your query to get one big list of entries. However, just doing
SELECT * FROM `login` WHERE `user` = '$word'
UNION
SELECT * FROM `login` WHERE `user` != '$word' ORDER BY RAND() LIMIT 3
will give you a list of entries where user = $word in the first part and random 3 other entries.
As I said, I don't know the exact purpose of this, but I think you're better of querying the entire list from your database server.
Here's the php code:
$connection = mysql_connect(HOST, USER, PASSWORD);
mysql_select_db(DATABASE_NAME, $connection);
$sql = "SELECT img, user FROM `login` WHERE `user` = '{$word}' UNION SELECT img, user FROM `login` WHERE `user` != '{$word}' ORDER BY RAND() LIMIT 3";
$results = mysql_query($sql, $connection);
$rows = array();
// Insert results in a new array to shuffle it
while ($row = mysql_fetch_array($results)) {
$rows[] = array(
'img' => $row['img'],
'user' => $row['user']
);
}
shuffle ($rows); // Randomize order
// Construct HTML
$html = '';
foreach ($rows as $entry) {
$html .= '<td><img width="130px" height="130px" src="sigg/' . $entry['img'] . '">
$html .= $user . '</img></td>';
}
echo $html;
You will need to replace capitalized words with what's necessary.
A few explanations:
replace * with only what you need from tables (use fewer memory)
first insert results in an array so you can randomize the order (from MySQL you'll always have the first line the results from first query)
construct the html and output it all at once (executing multiple echo relies on the buffering to not send it to the browser, but that option might be off: What is output buffering).

What would be the most efficient way to SELECT, then DELETE this immediately

What would be the most efficient way to SELECT this, then DELETE it immediately.
SELECT * from `usersOnline` WHERE timestamp>NOW()-INTERVAL 5 SECOND ORDER BY rand() LIMIT 1;
How could I take this same select query, but also make it delete what it selected in the most efficient way?
$query = 'SELECT * FROM `usersOnline` WHERE timestamp>NOW()-INTERVAL 5 SECOND ORDER BY rand() LIMIT 1;';
$result = mysql_query($query);
$record = mysql_fetch_assoc($result);
$query = 'DELETE FROM `usersOnline` WHERE id = ' . $record['id'];
mysql_query($query);
with mysql, you would have to do one and then the other. you would use the key from the select result to then delete that record directly afterwards. in this example, i am assuming your primary key column is named "id". you would replace the myssql functions with whichever method you are using to access the database of course.
you can do like this nested query
DELETE
FROM SomeTable
WHERE EXISTS
(SELECT * from `usersOnline` WHERE timestamp>NOW()-INTERVAL 5 SECOND ORDER BY rand() LIMIT 1;
)
thanks
use DELETE FROM: http://dev.mysql.com/doc/refman/5.0/en/delete.html
I know this example mixed prepared statments with regular statements. But it's up to the developer how to write the code. This is just a proof of concept, kept simple for easy reading.
$mysqli = new mysqli('localhost', 'user', 'password', 'userTable');
$result = $mysqli->query("SELECT * from `usersOnline` WHERE timestamp>NOW()-INTERVAL 5 SECOND ORDER BY rand() LIMIT 1");
$stmt = $mysqli->prepare("DELETE FROM 'usersOnline WHERE id = ?");
while ($row = mysql_fetch_assoc($result)) {
$stmt->bind_param('i', $row["id"]);
$stmt->execute();
}
$stmt->close();
$mysqli->close();

Categories