PHP not retrieving new data until page refresh - php

What is happening is I think my code is selecting the data first (basically old data) then updating it but what I want is for it to update then select the data (new data). How can I do this?
I am going to post where it goes wrong and if you need the full code just ask:
$select_links = $db->query("SELECT pid, added_by,link_title,lid,link_order FROM " . TABLE_PREFIX . "homepage_links WHERE pid='$pid'
ORDER BY link_order DESC LIMIT $start,$show");
$check_link_count_rows = $db->num_rows($select_links);
echo "<b> You Current Have " . $check_link_count_rows . " Links On Your Page: </b><br>";
echo "<form action='' method='POST'>
";
while($select_links_array = $db->fetch_array($select_links)) {
$link_title_display = $select_links_array['link_title'];
$link_id_display = $select_links_array['lid'];
if(!$mybb->input["order_edit_$link_id_display"]) {
$link_order_display = $select_links_array['link_order'];
} else {
$link_order_display = $mybb->input["order_edit_$link_id_display"];
}
$order_edit_value1 = $mybb->input["order_edit_$link_id_display"];
$order_edit_value = $db->escape_string($order_edit_value1);
echo "<br>" . $link_title_display . " <a href='?operation=edit_links&link=$link_id_display'> (edit) </a>
<input type='number' name='order_edit_$link_id_display' value='$link_order_display' style='width:40px;'>
<input type='hidden' name='get_link_id_display_value_$link_id_display' value='$link_id_display'><br>
";
$get_link_id_display_value1 = $mybb->input["get_link_id_display_value_$link_id_display"];
$get_link_id_display_value = $db->escape_string($get_link_id_display_value1);
$update_quick_edit_query = $db->query("UPDATE spud_homepage_links SET link_order='$order_edit_value'
WHERE lid='$get_link_id_display_value'");
}
I cannot find a solution as everything is in the right place for it to work besides this bug.

After a discussion in the comments, I determined that you were attempting to render a page after a post form submission that amends the database. It is perfectly possible to re-read your new database state and render it in a post operation, but it is inadvisable, since browsers cannot refresh the page without asking you if you wish to run the operation again. This does not make for a good user experience, especially in relation to using the back/forward buttons.
The reason for this behaviour is that post operations generally modify the database. They are used for example in credit card purchases or profile amendments where some change in the state of the server is expected. Thus, it is good practice to execute a new round-trip to the server, after the write operation, to change the page method from post to get.
The header() call I linked to will do this, and will resolve your rendering problem too.

Related

Chat page using jQuery's $.ajax and PHP not updating in a timely manner

I'm building a chat page for members of one of my websites. Everything works properly for me, except for the chat's automatic updates. The chat page is supposed to check for new messages every 5 seconds, and manipulating the callbacks shows that this part is working correctly; however, the PHP file that $.ajax references is giving me two very different behaviors. Because the ajax is working correctly in every test I have performed, I will exclude it here, but I can add it if anyone feels it is necessary. This is my annotated PHP:
$new_chat = //new chat message, collected from $.ajax and sanitized
$new_sender = //username of sender, collected from $.ajax and sanitized
$new_time = date('m-d-y');
$most_recent_chat = //unique id# of most recent chat message, collected from $.ajax and sanitized
//This block makes sure that there is a most recent chat; if not, (i.e., the
//page was just loaded so there are no chats on the page) it manually sets one.
//I'm not having any problems with this block.
if (!isset($most_recent_chat)) {
$query = "SELECT MAX(id) AS 'Most Recent' FROM `chat_global`";
$check_last_chat = new mysqli($host,$user,$pass,$game_db);
$check_last_chat->query($query);
if(!$result = $check_last_chat->query($query)) {
die();
}
while ($row=$result->fetch_assoc()) {
$most_recent = $row['Most Recent'];
}
$most_recent_chat = $most_recent-100;
$result->free();
$check_last_chat->close();
}
//Send any new chats to DB
if(isset($new_chat)) {
//First query inserts new chats into the chat table
$query = "INSERT INTO `chat_global` (message,sender,time) VALUES ('".$new_chat."','".$new_sender."','".$new_time."');";
$add_new_chat = new mysqli($host,$user,$pass,$game_db);
$add_new_chat->query($query);
$add_new_chat->close();
//Second query returns all new chats in reference
//to the most recent chat on the user's browser page
$query2 = "SELECT * FROM `chat_global` WHERE id>'$most_recent_chat';";
$most_recent_chats = new mysqli($host,$user,$pass,$game_db);
if(!$result = $most_recent_chats->query($query2)) {
die();
}
while($row = $result->fetch_assoc()) {
echo '<div class="chat-item" data-chat-id="' . $row['id'] . '">';
echo '<p class="chat-message"><strong>' . $row['sender'] . ': </strong>' . $row['message'] . '</p>';
echo '<p class="chat-time">' . $row['time'] . '</p></div>';
}
$result->free();
$most_recent_chats->close();
} else {
//Query 2 from above is repeated; basically, skips adding new message
//and simply retrieves any other new messages
$query2 = "SELECT * FROM `chat_global` WHERE id>'$most_recent_chat';";
$most_recent_chats = new mysqli($host,$user,$pass,$game_db);
if(!$result = $most_recent_chats->query($query2)) {
die();
}
while($row = $result->fetch_assoc()) {
echo '<div class="chat-item" data-chat-id="' . $row['id'] . '">';
echo '<p class="chat-message"><strong>' . $row['sender'] . ': </strong>' . $row['message'] . '</p>';
echo '<p class="chat-time">' . $row['time'] . '</p></div>';
}
$result->free();
$most_recent_chats->close();
}
The if(isset($new_chat)) block is simple and it's not giving me problems. Basically, if there is a new message, it adds the new message to the chat database and then returns all messages with ID numbers higher than the most recent from the browser's point of view. This part works and returns its information to the browser within 1/4 second.
The else block in this code is where I seem to be having some problems. The else block is the same, line for line, as the second half of the if block (from $query2 down). It works, but very slowly; whereas the if block loads from the server in 1/4 second on average, the else block (which is less code) takes an average of 90 seconds to return data. The $.ajax call is the same function whether a user sent a message or not; the only difference is that the if block is referenced if a user sent a message (and the $.ajax call is therefore manual), but the else block is referenced automatically by a repeated setTimeout(function,5000) line in the browser.
I'm 99.9% certain that the setTimeout() is working properly, because if I manually set my $.ajax call to send a generic $new_chat (i.e., "This is a message.") the function works every time; every 5 seconds, it sends the chat, and 1/4 second later, I see it appear in my chat page as expected. (My chat page is populated fully by the above PHP; even messages sent from user A must be sent to the above file, processed, and sent back to user A, that way users can know that their message was sent.)
The bottom line is that I'm at a complete loss as to why this behavior is occurring. The $.ajax is in the same function whether it's automatic or manual; the PHP is the same code, and the slower block is also shorter to boot! The $.ajax call runs perfectly quickly when it's manual, and if a message is sent along with the automatic $.ajax it also runs perfectly quickly. I'm new to AJAX and jQuery so I would like to think that the problem lies with one of those technologies, but nothing makes sense at all from where I'm sitting.

Specifying ID in Mysqli query in php

I'm working on a CMS site, I've got blog posts that I store in a database. I can create, edit and delete them. There's an issue though when I want to edit them.
I can't specify the WHERE clause in the update query to match the id of the blog post I'm trying to edit!
Suppose I've got a blog post with an id of '5'.
If I write this code for it, it works exactly the way it should.
$sqledit = "UPDATE paginas SET message='$_POST[message]' WHERE id= $_POST[id]";
But I don't want to edit just blog post #5, I want to edit the blog post that I'm updating. It seems to me this should work,
WHERE id= $_POST[id]";
... but it doesn't.
That just throws me an undefined id error. But it shouldn't because I can delete blog posts the exact same way with this particular code:
$sqldel = "DELETE FROM `paginas` WHERE id= $_POST[id]";
This does allow me to.
The code below is on the blog page, the edit query is in its own edit.php page
if (isset($_POST['edit'])) // if pressed, execute
{
echo
'<br><br> <div class="blogscript">
<form action="edit.php" method="post">Edit your stuff<br>
<input type="text" placeholder='. $pagetitle . ' ><br><br>
<textarea id="message2" name="message"><p>' . $message . '</p></textarea><br>
<input type="submit" name="editsubmit" value="Confirm" />
<input type="hidden" name="id" value="' . $id . '">. </form></div>';
}
I look forward to any tips I should try out.
EDIT:
This is my edit.php page
<?php
$DB_host = "localhost";
$DB_user = "root";
$DB_pass = "";
$DB_name = "cmsbase";
$MySQLi_CON = new MySQLi($DB_host,$DB_user,$DB_pass,$DB_name);
if($MySQLi_CON->connect_errno)
{
die("ERROR : -> ".$MySQLi_CON->connect_error);
}
$sql = "UPDATE paginas SET message='$_POST[message]' WHERE id= $_POST[id]";
if ($MySQLi_CON->query($sql) === TRUE) {
echo "";
} else {
echo "Error: " . $sql . "<br>" . $MySQLi_CON->error;
}
$MySQLi_CON->close(); //close connection
echo "<script>alert('Edited');location.href='index.php';</script>";
?>
EDIT: This is what the var_dump contains
In order for values to be present in $_POST, you need to have some element (e.g. <input>, <select>, <textarea>) inside your form with a name attribute set to the $_POST key you want.
You can add a hidden input to your form for id.
<input type='hidden' name='id' value='" . $id . "'>
Assuming you are getting the $message variable shown in that form code by selecting from your database, you should be able to get the id from there as well, or potentially from your $_GET if that is how you determine which post is being displayed.
(While this is not actually an answer, what I want to say does not fit in the comments)
Your line
$sql = "UPDATE paginas SET message='$_POST[message]' WHERE id= $_POST[id]";
Is horrific. This is the stuff of nightmares. Lets say that POSTed data in a form, is posted from a script from some robot somewhere, because I'm pretty sure you don't prevent XSRF in your code.
What if that script chose to post:
$_POST ==> array => message = "mwahahaha";
=> id = "1; DROP TABLE paginas;"
And you may think "how would they know my table name?" ,but that's easily found from other nefarious id inserts or other hacks on your code from other entry points which give a SELECT result, and many tables have common names such as "users" / "orders" / "baskets" / "touch-me" etc. (Ok well maybe not touch-me, but you get the idea).
Mysqli_real_escape_string() Could be used but thats only escaping quote marks and special characters, it does not mitigate SQL injection and compromise.
So, what should you do?
In this instance I want to draw your attention to PHP type juggling. Unlike many other languages, PHP has implied data types rather than specific data tyes, so a data type of "1.06" can be string and juggled to being a float as well.
Your id parameter in your MySQL is very probably a numeric integer value, so how can you be sure that the value of $_POST['id'] is also in integer rather than a SQL Instruction?
$id = (int)$_POST['id'];
This forces the value to be an integer, so
$id = (int)"1; DROP TABLE paginas;";
Is actually processed as $id = 1. Therefore saving you lots of compromised tables, spam rows and other nefarious rubbish all over your website, your database and your reputation.
Please take the following concept on board:
NEVER EVER TRUST ANY USER SUBMITTED CODE.
EVER

page not refreshing after clicking delete button

good day
need some help here, my Delete button works but page is not automatically refreshing after i clicked the delete button. i still need to manually retrieve the data from db and it would reflect that data is deleted already...
here is my code for delete php: how can i make this to refresh the page automatically?
<?php
require 'include/DB_Open.php';
$id = $_POST['id'];
$idtodelete = "'" . implode("','",$id) . "'";
$query = "DELETE FROM tbl WHERE ticket in (" . $idtodelete . ")";
$myData = mysql_query($query);
echo "DATA DELETED";
if($myData)
{
header("Location: delete.php");
}
include 'include/DB_Close.php';
?>
I suggest fetching the data after your delete logic. Then the delete logic will be executed before fetching the tickets.
Then a redirect to the same page isn't even necessary.
//
// DELETE
//
if (isset($_POST['delete'] && isset($_POST['id'])) {
// Do delete stuff,
// notice delete variable which would be the name of the delete form button e.g.
// If you like, you can still echo "Data deleted here" in e.g. a notification window
}
//
// FETCH data
//
$query = "Select * FROM tbl";
...
if you use post method better with this
if ($_SERVER["REQUEST_METHOD"] == "POST")
{
$id = $_POST['id'];
$idtodelete = "'" . implode("','",$id) . "'";
$query = "DELETE FROM tbl WHERE ticket in (" . $idtodelete . ")";
if (mysql_query($query))
{
header("Location: delete.php");
} else {
echo "Can not delete";
}
}
As suggested on one of the comments, and on the php documentation:
http://it2.php.net/manual/en/function.header.php :
Remember that header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP. It is a very common error to read code with include, or require, functions, or another file access function, and have spaces or empty lines that are output before header() is called. The same problem exists when using a single PHP/HTML file.
Basically you have to take out the :
echo "DATA DELETED";
What's the point to try to echo that string if the page is going to be redirected anyway?
If you want to make it fancy you could use Ajax to delete it, and trigger a setTimeout() on JavaScript x seconds after showing the message.
Or if you really really really really, REALLY, want to do it this way, you could disable the errors report/display (using error_reporting(0) and ini_set('display_errors', 'Off'). By experience I know that it will work, but it's nasty and extremately ultra highly not recommended

Opening new page in PHP via <a href> with mysql host

Basically I've connected my PHP to the mysql database which loads a bunch of users names. I want to be able to click on any of the users name so I've hyperlinked them all through a while loop and . When I click one of the links it opens a new page but I would like to be able to tell which username I clicked on. I think I could do this by using $_GET but I'm getting the following errors:
<?php echo "$first" . " " . "$last";?>;
Also, what should I write in the new page? So far on the new page this is what I've wrote:
$first=$row['FName'];
$last=$row['LName'];
echo "USERNAME: " . "$first";
UPDATE:
echo "<tr>
<td><b><center>.$info['Name']."</td></center></b>
</tr>";
This also gives error, but I think it shouldn't? Maybe I've made a simple mistake with the " somewhere, please check if you can find
In your new page you would check $_GET variable to see if the keys are set.
You have link with usersProfile.php?firstname=somename&lastname=somelastname so the keys you are looking for are firstname and lastname.
You would have to check if the key is set in order to avoid getting undefined indexes.
Ex. $firstname = isset($_GET['firstname']) ? $_GET['fisrtname'] : null;
This checks if the key is set and if it is sets $firstname to the data from the url otherwise to null
If I understand your question correctly, it appears that you are trying to create a link for each user that will send you to a different or personal page when clicked.
In that case, it might be easier to simply query the entire table and have that set up in your html page as a separate .
For instance:
//Database connections
$query="SELECT * FROM userTable WHERE firstName = $firstname and lastName = $lastName";
//Change the query to whatever you want
$result = mysql_query($query)
while($row = mysql_fetch_assoc($result))
{
echo "<a href='somepage.php'>" . $row['Username'] . "</a>";
}
This is just an example and a good amount would need to be added to it, but this more than likely would be easier for what you are trying to do. In this case, the loop would output all the names you have pulled from the database.

What is the right way to update mysql database using data coming from a dynamically generated list of textboxes?

I have a set of dynamically generated textboxes that holds the number of a certain product the user wants (quantity). I am trying to incorporate functionality that allows the user to change the number in the textbox to reflect the right number using php/mysql. I have the code below that pulls the current quantity the user enters from the previous page, but I’m not sure how to incorporate the changes in quantity from the current page. I’m assuming I will have to use UPDATE but I don’t know how to include it only for a certain product (or row).
#$link = $_GET['link'];
$price = $_GET['price'];
$title = $_GET['title'];
$retailer = $_GET['retailer'];
$options = $_GET['options'];
$quantity = $_GET['quantity'];
$session = session_id();
$_SESSION['sess_var'] = $session;
mysql_query("INSERT INTO sessionid (sessionid, link, retailer, price, title, qt, options) VALUES('$session' , '$link', '$retailer', '$price', '$title', '$quantity', '$options') ");
$query = "SELECT * FROM `sessionid` WHERE `sessionid` = '$session' ";
$result = mysql_query($query) or die(mysql_error());
echo '<table class="table"><tbody><form action = "viewcart.php" method = "get">';
$subtotal = 0;
$i=1;
while($row = mysql_fetch_assoc($result)) {
echo '<tr><td></td><td><h3>' . $row['title'] . '</h3></td><td>' . $row['options'] . '</td><td><div class="span3 offset1"><input type="text" name="box[' . $i . '] "value="' . $row['qt'] . '" class="span1"> <input type="submit" class="btn" value = "Refresh"> <h4> $' . $row['price'] . '</h4></td></tr>';
$i++;
$prodtotal= $row['qt'] * $row['price'];
$subtotal= round($subtotal+ $prodtotal, 2);
$_SESSION['subtotal']=$subtotal;
}
echo '</form></tbody></table>';
There are many ways to handle your situation. Here are 3 approaches for you to consider:
If you want to keep the DB session updated with every update on page and you want to do the update through form submission and page refresh then you will need to recognize which form is filling the super global that you are using: The one on the previous page or the one on the current page. I have done this in the past by adding a hidden form field (such as <input type="hidden" name="form_alias" value="update_form" />. You could also consider inserting on the previous page and redirecting on successful insert.
If you want to keep the DB session updated but want to avoid the need for refreshing the page just for a quantity update then you can submit the update through AJAX. (See MahanGM's note.)
If you do not need to update the DB session with every tiny quantity update and you like the idea of putting less stress on the db and server and do not mind doing more client-side (JavaScript) calculations, then you can just update the client-side content dynamically through JavaScript and only update the db upon form submission.
PS - Beware of SQL injection. Your current code is quite vulnerable to it. You are doing nothing to the user-passed data and it can be easily manipulated through the URL since you are using GET instead of POST. If you are not too far along I recommend switching to PDO and using prepare. Otherwise consider using mysql_real_escape_string.

Categories