Put newest database item on top - php

I've made a microblog system (like Twitter) using PHP and MySQL. Every time someone posts an item it includes the UNIX timestamp in the database. But my question is, how do i get the newest item on top of the page, the second to newest as second, etc? So basically, the one with the 'highest' timestamp on top of the page, the one with a bit 'less' timestamp under that.
This is what I got (I know mysql_ functions are deprecated):
<?php
/*Database test.
© 2013 Sydcul. All rights reserved.
To set the database settings, use the 'install' directory*/
include ($_SERVER['DOCUMENT_ROOT'] . '/test/config.inc.php');
$connection = mysql_connect($host, $user, $password);
mysql_select_db($database, $connection);
$messages = mysql_query("SELECT * FROM `" . $prefix . "microblog`");
while($row = mysql_fetch_array($messages))
{
$names = mysql_query("SELECT first_name,last_name FROM `" . $prefix . "data` WHERE id='" . $row['id'] . "'");
$name = mysql_fetch_assoc($names);
$fullname = $name['first_name'] . " " . $name['last_name'];
echo "<h2>Posted by " . $row['id'] . " (" . $fullname . ")</h2>";
echo $row['message'] . "<br><br>";
}
mysql_close($connection);
?>
Please explain how to do it, instead of only giving me code, otherwise I and the other people on stackoverflow can't learn from it :)

Use ORDER BY in your SQL
SELECT * FROM tablename ORDER BY datefield DESC

if you have an auto_incrementing ID field, fetch your data and ORDER BY ID or else if you have a DateField, Order by that in a descending order
ORDER BY `ID` DESC
as simple as that.

Related

Is it possible to combine these two SQL statements into one?

I am using these two MySQL statements to get all messages between two users, but I am running into a pretty big problem when it comes to manipulating the data later in the code since it's not in order by ID. Is there any way to combine these statements AND order the results by ID?
$sql = "SELECT * FROM messages WHERE sender='" . $username . "' AND receiver='" . $chatPartner . "'"
$sqlTwo = "SELECT * FROM messages WHERE sender='" . $chatPartner . "' AND receiver='" . $username . "'"
Essentially, I need every occurrence of a message between two people, but sorted by ID. As of right now, I am joining the arrays to get my full list, but it's not in order by ID.
SELECT * FROM messages
WHERE (sender='" . $username . "' AND receiver='" . $chatPartner . "'")
OR (sender='" . $chatPartner . "' AND receiver='" . $username . "'")
ORDER BY id DESC
How about just combine both into 1 query ?
$sql = "SELECT * FROM messages WHERE (sender=" . $username . " OR sender =". $chatPartner .") AND (receiver=" . $chatPartner . " OR receiver=" . $username .") ORDER BY id"
You could also write a shorter version of #dtj's answer using row constructors.
SELECT *
FROM messages
WHERE (sender, receiver) IN (($username, $chatPartner),($chatPartner, $username))
ORDER BY id DESC
In my opinion it looks a bit nicer in code and makes it more readable, but remember that it doesn't improve performance of execution.

MySQL does not retrieve first item in PHP

I've now been trying for hour and can't figure the problem out. I've made a php file that fetch all items in a table and retrieves that as JSON. But for some reason after I inserted the second mysql-query, it stopped fetching the first item. My code is following:
...
case "LoadEntryList":
$result2 = performquery("SELECT * FROM Entries WHERE Category = '" . $_POST["Category"] .
"' LIMIT " . $_POST["Offset"] . ", " . $_POST["Quantity"] . "");
$row2 = $result2->fetch_assoc();
while($row = $result2->fetch_assoc()) {
$result3 = performquery("SELECT Username FROM Users WHERE ID = '" . $row2["UserID"] . "'");
$row3 = $result3->fetch_assoc();
echo substr(json_encode($row),0,
strlen(json_encode($row))-1) . ",\"Username\":\"" . $row3["Username"] . "\"}";
}
...
Any help is greatly appreciated.
EDIT: Thanks for all those super fast responses.
First you're fetching a row:
$row2 = $result2->fetch_assoc();
Then you start looping at the next row:
while($row = $result2->fetch_assoc()) {
If you want to loop over all of the rows, don't skip the first one. Just loop over all of the rows:
$result2 = // your very SQL-injectable query
while($row2 = $result2->fetch_assoc()) {
$result3 = // your other very SQL-injectable query
$row3 = $result3->fetch_assoc();
// etc.
}
Note that errors like this would be a lot more obvious if you used meaningful variable names. "row2", "result3", etc. are pretty confusing when you have overlapping levels of abstraction.
Important: Your code is wide open to SQL injection attacks. You're basically allowing users to execute any code they want on your database. Please look into using prepared statements and treating user input as values rather than as executable code. This is a good place to start reading, as is this.
No Need of $row2 = $result2->fetch_assoc();
<?
case "LoadEntryList":
$result2 = performquery("SELECT * FROM Entries WHERE Category = '" . $_POST["Category"] .
"' LIMIT " . $_POST["Offset"] . ", " . $_POST["Quantity"] . "");
while($row = $result2->fetch_assoc())
{
$result3 = performquery("SELECT Username FROM Users WHERE ID = '" . $row["UserID"] . "'");
$row3 = $result3->fetch_assoc();
echo substr(json_encode($row),0,strlen(json_encode($row))-1) . ",\"Username\":\"" . $row3["Username"] . "\"}";
}
?>
Or,
<?
...
case "LoadEntryList":
$Category=$_POST["Category"];
$Offset=$_POST["Offset"];
$Quantity=$_POST["Quantity"];
$result3 = performquery("SELECT Entries.*, Users.Username FROM Entries, Users WHERE Entries.Category=$Category AND Entries.UserID=Users.ID LIMIT $Offset, $Quantity");
$row3 = $result3->fetch_assoc();
echo substr(json_encode($row),0,strlen(json_encode($row))-1) . ",\"Username\":\"" . $row3["Username"] . "\"}";
}
...
?>
I have a addition to David answer(can't comment on it yet)
This line of code:
$result3 = performquery("SELECT Username FROM Users WHERE ID = '" . $row2["UserID"] . "'");
will always return with the same result. If you were to change $row2[... into $row[... the code would take the rows that get updated by the while loop.
I am not content with the accepted result. The snippet can be fixed / replaced, and also a bad code must be replaced. Also not to mention is that I don't know if anyone spotted a really big mistake in the output. Here is the fix and I'll explain why.
$JSON = array();
$result2 = performquery( '
SELECT
e.*, u.Username
FROM Entries AS e
LEFT JOIN Users AS u ON u.ID = e.UserID
WHERE
e.Category = ' . $_POST['Category'] . '
LIMIT ' . $_POST['Offset'] . ', ' . $_POST['Quantity'] . '
' );
while( $row2 = $result2->fetch_assoc() ){
$JSON[] = $row2;
}
echo json_encode( $JSON );
Obviously the main issue is the query, so I fixed it with a LEFT JOIN, now the second part is the output. First it's the way you include the username, and the second what if you had multiple results? Than your output will be:
{"ID":1,"Username":"John"}{"ID":2,"Username":"Doe"}
How do you parse it? So the $JSON part comes in place. You add it to an array and will encode that array. Now the result is:
{["ID":1,"Username":"John"],["ID":2,"Username":"Doe"]}
LE: I left out the sql inject part which as stated by the OP, will be done afterwards? I'm not sure why not do it at the point of writing it, because you may forget later on that you need to sanitize it.

MySQL query with date parameter

My table in mysql has special data stamp (startdata). It is date when event starts. Older events stored in database to, but i don't need them to appear in the MySQL answer.
So is there any way sending query to database that includes parameter i need? (for example, not showing rows where startdate older than today).
Now my code looks like:
$res3 = mysqli_query($con,"SELECT * FROM raspisanie WHERE
instr='" . $instrument . "' AND school IN(" . $array2 . ")
AND type='regular' AND state='1' ORDER by startdate");
Add condition in your where clause.
$res3 = mysqli_query($con,"SELECT * FROM raspisanie WHERE
instr='" . $instrument . "' AND school IN(" . $array2 . ")
AND type='regular' AND state='1' AND startdate >now() ORDER by startdate");

Simple PHP / MySQL data results

I grabbed this piece of code off the Internet and modified it slightly to fit my needs but it doesn't work and I don't know why. I'm sure I've overlooked something but I don't know enough about PHP to know what I'm doing wrong. The uid is showing up, but nothing else. I'm just trying to get information from the MySQL data based on the user's session id. I checked the database to make sure that the uid that shows matches the data -- it does.
<?php
include("connect.php");
session_start();
$uid = $_SESSION['user_id'];
$result = mysql_query("SELECT * FROM users WHERE id = ' . $uid . '");
if ($result) {
echo "Connect"; } else
{ die('Invalid query: '.mysql_error()); }
$info = mysql_fetch_array($result);
echo "<br>ID: ", $uid;
echo "<br>Full Name: " .$info['full_name'] ;
echo "<br>User Name: " .$info['user_name'] ;
echo "<br>";
?>
p.s. - Yes, I know that mysql_query (and other syntax like it) has been deprecated.
$result = mysql_query("SELECT * FROM users WHERE id = '" . $uid . "'"); // not ' . $uid . '
NOTE: You were searching for . ID . not actual ID
Query should be as
$result = mysql_query("SELECT * FROM users WHERE id = $uid ");
Assuming id is int in the table
You had
$result = mysql_query("SELECT * FROM users WHERE id = ' . $uid . '");
^.... ^.... was the issue.

MYSQL/PHP outputting entire table when I only want to output one row

This is definitely a beginner's question. There are two issues. The id in my MYSQL table (set to autoincrement) keeps going up, even though I delete rows from my table (I'm using phpmyadmin). As for the other issue, I can't seem to find a way to work with the row most recently entered by the user. The code echos all existing rows from MYSQL.
I've bolded the most pertinent section of code.
<?php
//establish connection to mysql
$con = mysql_connect("localhost","root","");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
/*retrieve user input from input form
and initialize variables */
$Word1 = $_POST["Word1"];
$Word2 = $_POST["Word2"];
$Word3 = $_POST["Word3"];
$Word4 = $_POST["Word4"];
$Word5 = $_POST["Word5"];
//select db
mysql_select_db("madlibs", $con);
//insert user input for word 1
$sql = "INSERT INTO test (Word1, Word2, Word3, Word4, Word5)
VALUES
('$Word1', '$Word2', '$Word3', '$Word4', '$Word5')";
if(!mysql_query($sql,$con))
{
die('Error: ' . mysql_error());
}
$result = mysql_query ("SELECT * FROM test");
/* take note here */
while($row = mysql_fetch_array($result))
{
echo $row['Word1'] . " " . $row['Word2'] . " " . $row['Word3'] . " " .
$row['Word4'] . " " . $row['Word5'] . " " . $row['id'];
echo "<br />";
} /* take note here */
mysql_close($con);
?>
$result = mysql_query ("SELECT * FROM test order by id desc limit 1");
As for your id question...that's how ids work. They don't fill in gaps.
On a side note: Never ever put user submitted data directly into the query string. Always escape them with mysql_real_escape_string().
SELECT * FROM test ORDER BY Id DESC LIMIT 1

Categories