I have a PHP script that reads a database table and inserts all the rows into an HTML table until it's displayed all available rows as shown here:
require_once('dbconnect.php');
$sql =
"SELECT
ID, Site, Type, Requested, Quote,
PO, CADs, MCS, DFP,
SIM, Prereqs, Design, Report, Delivered
FROM Predictions";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo '<table class="table table-hover table-condensed">';
while($row = $result->fetch_assoc()) {
echo
'<tbody>'.
'<tr>'.
'<td>'.$row['ID'].'</td>'.
'<td>'.$row['Site'].'</td>'.
'<td>'.$row['Type'].'</td>'.
'<td>'.$row['Requested'].'</td>'.
'<td>'.$row['Quote'].'</td>'.
'<td>'.$row['PO'].'</td>'.
'<td>'.$row['CADs'].'</td>'.
'<td>'.$row['MCS'].'</td>'.
'<td>'.$row['DFP'].'</td>'.
'<td>'.$row['SIM'].'</td>'.
'<td>'.$row['Prereqs'].'</td>'.
'<td>'.$row['Design'].'</td>'.
'<td>'.$row['Report'].'</td>'.
'<td>'.$row['Delivered'].'</td>'.
'<td>'.
'<a href="#">'.
'<span class="edit"><i class="fa fa-pencil"></i></span>'.
'</a> | <a href="#">'.
'<span class="delete"><i class="fa fa-times"></i></span>'.
'</a>'.
'</td>'.
'</tr>'.
'</tbody>';
}
echo "</table>";
}
else
echo "0 results";
$conn->close();
That all works fine, but now I want to have what is essentially a delete button (you can see the markup above that creates the icon/link) that will populate automatically to correspond with the appropriate ID for the mysql database table. Image of table for visual idea of what I'm going for.
My delete script so far is below, but I have no idea what to put in the "WHERE id=", or how to incorporate it into my first script once it's setup properly.
<?php
require_once('dbconnect.php');
$sql = "DELETE FROM Predictions WHERE id=";
if($conn->query($sql) === TRUE)
echo "Item deleted successfully";
else
echo "Error deleting record; ". $conn->error;
$conn->close();
So basically I need advice to modify both of these scripts so that a delete link (or form, I don't care) is generated in the first script then applies the second script and it knows the corresponding id to use. In my search to solve this problem I saw some potential solutions using _GET, but in the same thread others said that is in fact a very bad and insecure solution.. so I'm very confused!
I'm learning PHP as I go, and I've only been going at it for about 2 days, so please have mercy :)
Change this
<a href='#'><span class='delete'>
to
<a href='deletepage.php?id=" . $row["ID"] . "'><span class='delete'>
then on "deletepage.php", whatever you are going to call that page do something like
require_once('dbconnect.php');
$id = (int)$_GET['id'];
$sql = "DELETE FROM Predictions WHERE id=" . $id;
if($conn->query($sql) === TRUE) {
echo "Item deleted successfully";
} else {
echo "Error deleting record; ". $conn->error;
}
$conn->close();
I don't know what driver you are using here but the preferred solution would be using a prepared statement with a parameterized query.
So pretty much you send the id via a GET parameter to your "delete page". That page takes that value, casts it to an int to avoid SQL injections (read further below), and then deletes the data. You also could instead of echoing a success there use a header to redirect them to the previous page. You could append a GET parameter to that url display a success message. (or you could always do all this on the same page and just check if the id is being sent).
Also you should have this page behind someone secure login system. You don't want any user/bot able to execute that deletepage.php.
How can I prevent SQL injection in PHP? http://php.net/manual/en/security.database.sql-injection.php https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#Defense_Option_1:_Prepared_Statements_.28Parameterized_Queries.29
I'm guessing you are using mysqli so take a look at this doc for prepared statements with that driver, http://php.net/manual/en/mysqli.quickstart.prepared-statements.php.
Related
I currently have a database with a table called rooms; which has two attributes: roomID and roomType. I have inserted data into this using MySql which is all fine. I am using PHP and MYSQL in order to show what's currently in the database on the page (which is working just fine) and then a delete.php page where I have a text field for Room ID and Room Type. I wish to delete whatever I prefer from the 'rooms' table however I keep getting the Unknown table 'roomid' in MULTI DELETE error, even though I only have the one table.
Below is my current PHP
<?php
include ('connect.php');
if(isset($_POST['roomID'])){
$roomID = $_POST['roomID'];
$roomType = $_POST['roomType'];
$sql = "DELETE FROM rooms WHERE roomID='"$roomID"' AND roomType='"$roomType"' ";
if ($conn->query($sql) === TRUE) {
echo "Record deleted successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
}
?>
Would appreciate any help
WARNING!
Little Bobby says your script is at risk for SQL Injection Attacks.. Even escaping the string is not safe!
Here's the problem -
If only you had used prepared statements you wouldn't have had to worry about concatenating the variables properly. The following portion of your query line is missing the proper concatenation:
WHERE roomID='"$roomID"' AND roomType='"$roomType"'
Ok, I'm confused. I have some code that searches a database table for a username, and then uses an if else statement to run some code depending on if the user is found or not. My code is below. The problem is that the code isn't even seeing the if else statement, and I have no idea why. Any help is appreciated.
$sqluser = "select * from users where username='" . $user ."'"; //Searching to see if the user is in the database
echo $sqluser . "<br><br>"; //writes out the select statement to make sure it is correct
$query = mssql_query($sqluser); //returns the results
$num_rows = mssql_num_rows($query); //gets the number of rows returned
echo $num_rows; //writes out the number of rows
if ($num_rows==0) //determines what happens next if the user exists or not
{
//displays an error box if the user doesn't exist
echo "<script type=text/javascript>";
echo "alert('That user doesn't exist. Please try again.')";
echo "</script>";
}
else
{
//will be code to run if the user does exist
echo "<script type=text/javascript>alert('Testing.')</script>";
}
I couldn't add a comment. So I will write this as an answer instead.
Since you state that the alert JavaScript is showing in the page source, this mean that the IF/ELSE statement in PHP is working fine. The problem is with the single quote. You have a single quote inside a single quoted alert function. Hence the JavaScript alert function cannot be executed.
echo "alert('That user doesn't exist. Please try again.')";
Try using this instead
echo "alert('That user doesn\'t exist. Please try again.');";
I have a PHP script that reads a database table and inserts all the rows into an HTML table until it's displayed all available rows as shown here:
require_once('dbconnect.php');
$sql =
"SELECT
ID, Site, Type, Requested, Quote,
PO, CADs, MCS, DFP,
SIM, Prereqs, Design, Report, Delivered
FROM Predictions";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo '<table class="table table-hover table-condensed">';
while($row = $result->fetch_assoc()) {
echo
'<tbody>'.
'<tr>'.
'<td>'.$row['ID'].'</td>'.
'<td>'.$row['Site'].'</td>'.
'<td>'.$row['Type'].'</td>'.
'<td>'.$row['Requested'].'</td>'.
'<td>'.$row['Quote'].'</td>'.
'<td>'.$row['PO'].'</td>'.
'<td>'.$row['CADs'].'</td>'.
'<td>'.$row['MCS'].'</td>'.
'<td>'.$row['DFP'].'</td>'.
'<td>'.$row['SIM'].'</td>'.
'<td>'.$row['Prereqs'].'</td>'.
'<td>'.$row['Design'].'</td>'.
'<td>'.$row['Report'].'</td>'.
'<td>'.$row['Delivered'].'</td>'.
'<td>'.
'<a href="#">'.
'<span class="edit"><i class="fa fa-pencil"></i></span>'.
'</a> | <a href="#">'.
'<span class="delete"><i class="fa fa-times"></i></span>'.
'</a>'.
'</td>'.
'</tr>'.
'</tbody>';
}
echo "</table>";
}
else
echo "0 results";
$conn->close();
That all works fine, but now I want to have what is essentially a delete button (you can see the markup above that creates the icon/link) that will populate automatically to correspond with the appropriate ID for the mysql database table. Image of table for visual idea of what I'm going for.
My delete script so far is below, but I have no idea what to put in the "WHERE id=", or how to incorporate it into my first script once it's setup properly.
<?php
require_once('dbconnect.php');
$sql = "DELETE FROM Predictions WHERE id=";
if($conn->query($sql) === TRUE)
echo "Item deleted successfully";
else
echo "Error deleting record; ". $conn->error;
$conn->close();
So basically I need advice to modify both of these scripts so that a delete link (or form, I don't care) is generated in the first script then applies the second script and it knows the corresponding id to use. In my search to solve this problem I saw some potential solutions using _GET, but in the same thread others said that is in fact a very bad and insecure solution.. so I'm very confused!
I'm learning PHP as I go, and I've only been going at it for about 2 days, so please have mercy :)
Change this
<a href='#'><span class='delete'>
to
<a href='deletepage.php?id=" . $row["ID"] . "'><span class='delete'>
then on "deletepage.php", whatever you are going to call that page do something like
require_once('dbconnect.php');
$id = (int)$_GET['id'];
$sql = "DELETE FROM Predictions WHERE id=" . $id;
if($conn->query($sql) === TRUE) {
echo "Item deleted successfully";
} else {
echo "Error deleting record; ". $conn->error;
}
$conn->close();
I don't know what driver you are using here but the preferred solution would be using a prepared statement with a parameterized query.
So pretty much you send the id via a GET parameter to your "delete page". That page takes that value, casts it to an int to avoid SQL injections (read further below), and then deletes the data. You also could instead of echoing a success there use a header to redirect them to the previous page. You could append a GET parameter to that url display a success message. (or you could always do all this on the same page and just check if the id is being sent).
Also you should have this page behind someone secure login system. You don't want any user/bot able to execute that deletepage.php.
How can I prevent SQL injection in PHP? http://php.net/manual/en/security.database.sql-injection.php https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#Defense_Option_1:_Prepared_Statements_.28Parameterized_Queries.29
I'm guessing you are using mysqli so take a look at this doc for prepared statements with that driver, http://php.net/manual/en/mysqli.quickstart.prepared-statements.php.
<?php
include "conn.php";
include "session.php";
$name_enterd=$_GET['Name'];
$sql = "DELETE FROM myDB.Mynew WHERE firstname='$name_enterd' OR lastname='$name_enterd'";
echo "<br>";
$result=$conn->query($sql);
if($result==1)
{
echo "<br> Data deleted successfully";
}
else
{
echo "No Data Found<br>";
}
?>
when I run this code 1st time it works properly by deleting the data. But when i run it again it still gives me the same answer" Data Deleted Successfully" even there is no data with that value exists.
i.e $result still gets value1.
Your code should look more like this:
<?php
include "conn.php";
include "session.php";
$name_enterd=$_GET['Name'];
$sql = "DELETE FROM myDB.Mynew WHERE firstname='$name_enterd' OR lastname='$name_enterd'";
echo "<br>";
$result=$conn->query($sql);
if($result->rowCount() > 0)
{
echo "<br> Data deleted successfully";
}
else
{
echo "No Data Found<br>";
}
?>
Specifying rowCount gives you just the number of rows affected by the query
Even when the query only affects 0 rows it has still completed successfully, so you would expect $result to be 1.
You are getting the correct output. When doing that query, you're asking the database to check if there is data with that firstname or lastname and delete it. Even if there is no data with that matches it, the query has still run successfully.
You need to do use
$result->rowCount() == 1
instead of
$result == 1
It really depends what you want to use the result for. If you simply want to tell the user it has been deleted, using what you have is fine. However, if you want to let the user knows if anything has actually been deleted, you need to use my suggestion above or an alternate method to determine if this is the case.
Actually it looks like you might be using mysqli in this code, so maybe you could try using affected_rows instead of rowCount:
see http://php.net/manual/en/mysqli.affected-rows.php.
What does
$result->affected_rows
give you?
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.