how would I create a link that would when clicked erase a record from a MySQL database based on the id of that item? using php if possible.
edit// The link will require authentication in order to view
Thanks
EDIT: I somehow got it in my head that you were looking for an ajax solution, but it seems that I was wrong. Still, I'll leave this here in case it's useful.. #David's solution is the way to go based on what you asked.
This should get you started. The client script uses jQuery:
<a id="item_45" href="#" class=".btnDelete">Delete this</a>
<a id="item_100" href="#" class=".btnDelete">Delete this</a>
<script>
$(document).ready(function() {
$("a.btnDelete").click(function() {
// get the number from the ID after the '_'. Remember, IDs cannot start with numbers
var itemId = this.id.split("_")[1];
// ask the server for some json
// if the 'status' offset is set to '1', the delete was successful
// otherwise, display what's in the 'error' offset
$.post('deleteStuff.php', {id: itemId}, function(json) {
if(json.status == "1") {
alert("delete was successful");
} else {
alert(json.error);
}
}, "json");
return false;
});
});
</script>
<?php
$id = $_POST['itemId'];
// delete corresponding record from database
if($delete_successful) {
$data = array('status' => '1');
} else {
$data = array('error' => 'Could not delete item. Please contact support';
}
echo json_encode($data);
?>
Put the id in the query string
Read the value from $_GET
Construct the SQL query
Send it
… or don't. Having a bot or a pre-fetching cache delete your database is a really bad idea. Use forms and $_POST. Get requests are supposed to be safe.
<?php
if (isset($_GET['delete']) && preg_match('/[0-9]+/', $_GET['delete'])) {
$id = (int) $_GET['delete'];
$sql = "DELETE FROM $table WHERE id = '$id' LIMIT 1";
$res = mysql_query($sql);
$del = mysql_affected_rows();
}
if ($del) {
echo '<p>Rows deleted: <strong>'.$del.'</strong></p>';
}
// loop over your records here, outputting an <a> tag for each record
// this could be an interactive data-grid table or whatever
echo '<p>Delete record #1</p>';
echo '<p>Delete record #2</p>';
Related
I’m working on a blog website where the idea is that the current user that is logged in can edit and delete their own posts. I finally got it to work, but my question is how I can prevent that a user can write the following input in the URL and do the same actions as my delete.php action.
(Example) Manual URL input with topic_id:
/delete.php?del=133
Do anyone know how I can edit my existing code or know a better solution to the problem I will be much grateful!
This is how my code looks:
Profile.php:
if (#$_GET['id']) {
$check_d = mysql_query("SELECT * FROM users WHERE id ='".$_GET['id']."'");
while ($row_d = mysql_fetch_assoc($check_d)) {
echo "<div class='spacer'></div><h2 class='headertext'>Inlägg skapade av : ".$row_d['username']."</h2>";
$check_u = mysql_query("SELECT * FROM topics WHERE topic_creator='".$row_d['username']."' ORDER BY topic_id DESC");
while ($row_u = mysql_fetch_assoc($check_u)) {
$id = $row_u['topic_id'];
echo "<tr>";
echo "<td class='postmain'><a href='topic.php?id=$id' class='links'>".$row_u['topic_name']."<br /></a></td>";
echo "<td class='postmain'><p class='text'>".$row_u['topic_creator']."</p><br /></td>";
echo "<td class='postmain'><p class='text'>".$row_u['date']."</p><br /></td>";
if($_SESSION['username'] === $row_u['topic_creator']) {
echo "<td class='postmain'><a href='edit.php?edit=$id'><button>Redigera</button></a>";
echo "<a href='delete.php?del=$id'><button>Ta bort</button></a></td>";
}
echo "</tr>";
}
}
}
The highlighted code shows that only the current session (user) who made the post can edit and delete their own posts.
Delete.php:
if (isset($_GET['del'])) {
//getting id of the data from url
$id = $_GET['del'];
//deleting the row from table
$sql = "DELETE FROM topics WHERE topic_id='$id'";
$res = mysql_query( $sql );
//redirecting to the display page
header("Location:admin.php");
}
Using isset function is solution here . The isset function will check that whether user clicked the delete/modify link or not(i.e he pasted delete.php directly in link) . So your code will only execute when user clicks the link .
if (isset($_GET['del']))
{
// your profile.php code here
}
else
{
// error message
}
You can use the same $_SESSION logic to ensure anyone accessing the delete.php has the appropriate permissions.
if (isset($_GET['del'])) {
//getting id of the data from url
$id = $_GET['del'];
// Get the author for the specified post to ensure they are permitted to do so
// TODO
// Check that the author is the same as the $_SESSION user
if($_SESSION['username'] === $postAuthor) {
//deleting the row from table - FIX THIS (see below)
$sql = "DELETE FROM topics WHERE topic_id='$id'";
$res = mysql_query( $sql );
} else {
// User is not authorized, create error handling
// TODO
}
//redirecting to the display page
header("Location:admin.php");
}
Unrelated, beware of SQL injection. Bobby Tables is a good guide and you should not be using the mysql_ functions and should be using prepared statements.
I'm making a web app exercise, where the registered user can log in and create notes. Now I'd like to add a function, that deletes a certain note if I click the "X" I'm about to add to their side, but I cannot really figure out how is it possible to identify a certain note created by this method, more precisely, that how can I return it's id to use for the delete query.
Here is the site you can check the way it looks like now, below I'm gonna attach the way I've listed the comments. Thanks in advance!
http://laszlovaszi.com/mx_agency/index.php
<?php
function confirm_query($result) {
if (!$result) {
die("Database query failed.");
}
}
function find_notes_by_id($user_id) {
global $connection;
$row = array();
$safe_user_id = mysqli_real_escape_string($connection, $user_id);
$query = 'SELECT content ';
$query .= 'FROM notes ';
$query .= 'WHERE user_id = '.$safe_user_id;
$result = mysqli_query($connection, $query);
confirm_query($result);
$final_data = array();
while($row = mysqli_fetch_assoc($result)){ // iterates over the result-set object to get all data
$final_data[] = $row; //assigns value to the array
}
return $final_data;
}
?>
<div class="notes text-center">
<?php
$notes_set = find_notes_by_id($userRow['id']);
if(empty($notes_set)){
echo "No notes have been posted for this user yet.";
} else {
echo "<div class=\"notelist text-left\">";
foreach($notes_set as $note){
echo "<div class=\"note text-left\">";
echo "● ";
echo htmlentities($note['content']);
echo "<br />";
echo "</div>";
}
echo "</div>";
}
?>
</div>
Now I'd like to add a function, that deletes a certain note if I click
the "X" I'm about to add to their side
Make the "X" a link to a javascript function that takes the note id and makes an ajax request to the server to delete the note. The id would be placed in the function call while you render each note in your foreach($notes_set as $note) step. The link could be written this way:
echo "<a onclick='deleteNote($note[id])'> X </a>";
When the user presses the "X", the deleteNote() function will execute. This function would make an AJAX request to delete.php?note=123 (123 is whatever PHP put in as $note['id']).
Here is an example in raw Javascript. If you use a framework such as JQuery, it's even simpler:
<script>
function deleteNote(noteID) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
//remove the note from the DOM and alert user of success
}
};
xhttp.open("GET", "delete.php?note="+noteID, true);
xhttp.send();
}
</script>
In PHP, you can retrieve the note id with $id = $_GET['note']. This value can then be used in your DELETE query.
Just remember to first verify the following before you delete:
the user is authenticated
the note id really belongs to that user
Otherwise, anyone will be able to delete everybody's notes.
I have a HTML table with, for this example, 2 rows (could be more). The middle column is editable and each row in the HTML table is a different column in the database. When I edit row 1 and refresh the page row 2 now has the same value as row 1. I do not want this. The user id (pk) will be the same for each row. The documentation about creating a new record says this would work with updating existing, but does not really help me. I am looking for as much help as I can get.
Here is an image of my table:
How do I get each row to keep its value and not update all other rows?
For example if I update the column in row 1, I want only row 1's column to be updated.
Please help!
Here is my code:
HTML Code:
<td><a class="myeditable" data-name="fb_url" data-type="text" data-pk="<?php echo ($userid);?>" title="Edit"><?php echo ($result['fb_url']);?></a></td>
<td><a class="myeditable" data-name="tw_url" data-type="text" data-pk="<?php echo ($userid);?>" title="Edit"><?php echo ($result['tw_url']);?></a></td>
Post.php Code
require("config.php");
$pk = $_POST['pk'];
$name = $_POST['name'];
$value = $_POST['value'];
if(!empty($value)) {
try // save user selection to the database
{
$stmt = $db->prepare("UPDATE social_preferences SET fb_url = :fburl, tw_url = :twurl WHERE user_id = :userID AND ");
$stmt->bindParam(":userID", $pk, PDO::PARAM_INT);
$stmt->bindParam(':twurl', $value);
$stmt->bindParam(':fburl', $value);
$stmt->execute();
} catch(PDOException $e) { echo 'Connection failed: ' . $e->getMessage(); }
}else {
echo 'No value...';
}
JS Code:
$(document).ready(function() {
//toggle `popup` / `inline` mode
$.fn.editable.defaults.mode = 'inline';
$('.myeditable').editable({
url: 'post.php',
ajaxOptions: {
type: 'post',
},
success: function(data, config) {
if(data && data.id) {
//set pk
$(this).editable('option', 'pk', data.id);
}
}
});
});
When I check the network tab in Chrome dev tools I see this:
Method: POST
Status: 302 Moved Temporarily
OP is talking about rows, but in fact it are columns.
$accepted_names = array('fb_url', 'tw_url');
if (in_array($_POST['name'], $accepted_names)) {
if(!empty($_POST['value'])) {
$value = $_POST['value'];
$id = $_POST['pk'];
try {
$stmt = $db->prepare('UPDATE social_preferences SET ' . $_POST['name'] . ' = :value
WHERE user_id = :id');
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->bindParam(':value',$value);
$stmt->execute();
}
catch (PDOExeption $e) {
echo json_encode(array('status' => 'failed', 'msg' => $e->getMessage()));
exit;
}
echo json_encode(array('id' => $id, 'status' => 'oké', 'msg' => $value));
}
else {
echo jsonencode(array('status' => 'failed', 'msg' => 'No value ....'));
}
}
else {
header($_SERVER['SERVER_PROTOCOL'] . ' 422 Unprocessable entity');
}
I assume that you use oracle SQL.
Put all the users you want to update in an array and use foreach to iterate over them.
Execute your update statement for every one.
I don't know if it is possible to run multiple updates in one statement, but I don't think so.
EDIT:To be sure that only one row is affected use unique identifiers such as user ids if possible.
in fact , you just need to follow the documentation of the X - table in here
X-Table
Ok, this is a information tag.
data-name="your field column in database"
data-pk="your primary key" in data pk you can input multiple PK.
Now please try this example.
HTML:
<td>
<a class="myeditable" data-name="fb_url" data-type="text" data-pk="<?php echo $userid;?>" data-url="post.php" title="Edit"><?php echo ($result['fb_url']);?></a>
</td>
JS Code:
<script>
$(document).ready(function() {
$('.myeditable').editable();
});
</script>
Post.php Code
if(!empty($_POST['name'])) {
$pk = $_POST['pk']; // post from data-pk
$name = $_POST['name']; // post from data-name
$value = $_POST['value']; // this is your value
$stmt=$db->prepare("UPDATE social_preferences SET $name= '".$value."' WHERE your_id= '".$pk."'");
$stmt->execute();
}else {
header($_SERVER['SERVER_PROTOCOL'] . ' 422 Unprocessable entity');
}
I want to delete columns in my sql, which is going with succes. But there is another problem, I need to solve. I've tried and checked here around. All with any kind of succes I will try to explain my problem.
I've a member system where you can add your content, edit you submitted content and now I'm creating to delete your content. My script can delete now post which are created by the same user as logged in. For example my account is called Bobby and someone is called Alex I cannot delete the content of Alex only mimes, thats what I want.
For example my content link of bobby : category.php?nameID=cat2&id=22 And the delete link is deletepost.php?id=22
EX. content link Alex:
category.php?nameID=cat2&id=23 And the delete link is deletepost.php?id=23
When I'm logged in as Bobby and I go to deletepost.php?id=23 and receive a message like You cannot delete this content!
And When I go to mimes deletepost.php?id=22 I need to receive a message like: Your content has been delete succesfully!
I'm only receive NO!
<?php
$user = new User();
if (isset($_GET['id'])) {
$id = mysql_real_escape_string($_GET['id']);
if(!$user->isLoggedIn()) {
Redirect::to('index.php');
}
if($user->isLoggedIn()) {
$pakuser = $user->data()->username;
$sql = mysql_query("DELETE FROM post
WHERE post.id = '$id' AND post.add = '$pakuser'")
or die(mysql_error());
if (!$sql) {
echo 'NO';
}
if ($sql) {
echo 'YES';
}
}
}
?>
Beside from the possible sql injections in your code, you can try this format for a delete query to determine the mistake:
<?php
$sql = "
DELETE FROM
post
WHERE
post.id = ".$id." AND post.add = '".$pakuser."'
";
if(!$res = mysql_query($sql))
{
trigger_error(mysql_error().'<br />In query: '.$sql);
}
elseif(mysql_affected_rows() == 0)
{
echo 'No records Deleted. <br />Query: '.$sql;
}
else
{
echo 'There are '.mysql_affected_rows().' records deleted.';
}
?>
Are you also sure that post.add is the username?
i have already posted a similar question here, but failed to get a response that will fix my problem, also the problem has changed a bit so i'm re-posting and desperate to get some help!
link to previous question:
ajax long polling with mysql
CURRENT CODE:
JS(I run it from php):
$oldIDq = mysql_query("SELECT * FROM messages ORDER BY id DESC LIMIT 1");
while($oldrow = mysql_fetch_array($oldIDq)){
$oldID = $oldrow['id'];
}
$func = '
var oldID = '.$oldID.';
function wait() {
$.ajax({
type: "GET",
url: "../scripts/msg_scripts/msg.php?oldid=" + oldID,
async: true,
cache: false,
success: function (data){
if(data != \'1\'){
var json = eval(\'(\' + data + \')\');
if (json[\'msg_content\'] != "") {
alert("new meassage added");
}
oldID = json[\'oldID\'];
setTimeout(\'wait()\',1000); }
},
disconnect: function()
{
return false;
setTimeout(\'wait()\',1000);
},
error: function(XMLHttpRequest, textStatus, errorThrown){
alert("error: " + textStatus + "(" + errorThrown + ")");
setTimeout(\'wait()\',1000);
}
});
}
$(document).ready(function(){
wait();
});
';
SERVER:
$connect = mysql_connect ("localhost", "root", "")
or die ("couldnt connect");
mysql_select_db ("***") or die ("not found"); //if db was not found die
mysql_query("SET NAMES 'utf8'");
$oldID = $_GET['oldid'];
if($oldID == "") {
die('timeout');
}
else{
$result = mysql_query("SELECT id FROM messages ORDER BY id DESC LIMIT 1");
while($row = mysql_fetch_array($result))
{
$last_msg_id = $row['id'];
}
while($last_msg_id <= $oldID)
{
usleep(10000);
clearstatcache();
$result = mysql_query("SELECT id FROM messages ORDER BY id DESC LIMIT 1");
while($row = mysql_fetch_array($result))
{
$last_msg_id = $row['id'];
}
}
$response = array();
$response['msg_content'] = 'new';
$response['oldID'] = $last_msg_id;
echo json_encode($response);
}
now, i had a session running on the server side of the process and i removed it for now because i understood that long polling has a problem with sessions i also have sessions running on the page which sends the ajax request, since i removed the session my problem has improved in a way, what happens now is that i can basically click on a link on my website and exit the page and get an error, but if i do it more than 4-5 times, the browser freezes an every click on any link just reruns the ajax function and i get a different error. if i refresh the page of the request i imidetly get the second error and the browser freezes. also if that's helpful information if i close the browser and try to reopen any page of my site it doesn't load at all unless i rerun my server(working on localhost right now) also tried it with chrome and ff.
can some one please point me towards the solution?
-- Updated again to retrieve all new messages
Reading your code, you only wish to return the last message, if so then the while loops are in this case pretty useless. Do keep in mind that there might be more 'new' messages between the oldID and the last ID inserted into your database which you skip, so does this code I provide
$connect = mysql_connect ("localhost", "root", "")
or die ("couldnt connect");
mysql_select_db ("***") or die ("not found"); //if db was not found die
mysql_query("SET NAMES 'utf8'");
$oldID = trim($_GET['oldid']);
// empty response, you may fill it with a default msg
$response = array(
'msg_content' => 'none',
'oldID' => $oldID
);
// this if statement will prevent to return a valid
// JSON string to the ajax request
if(empty($oldID)) {
die('timeout');
}
else {
$result = mysql_query("SELECT id FROM messages WHERE id > ".addslashes($oldID)." ORDER BY id DESC");
$index = 1;
// check if results have new messages
if(($num_rows = mysql_num_rows($result) > 0) {
$response['msg_content'] = 'new';
while($row = mysql_fetch_array($result)) {
$response['new_msgs'][] = $row['id']
if($index == $num_rows)
$response['oldID'] = $row['id']; // set oldID to last record
}
}
echo json_encode($response);
--
To your comment on how to use session_write_close properly.
session_start();
$var_id = $_SESSION['id'];
$var_fn = $_SESSION['firstname'];
$var_ln = $_SESSION['lastname'];
$var_mail = $_SESSION['email'];
// close write to session here to release it for other sources
session_write_close();
if (!loggedin()){
header ("Location: index.php");}
if ($_GET['id']) {
$id = mysql_real_escape_string($_GET['id']);}
// you are using session here, use the localized $var_id
else if (isset($var_id)) {
$id = mysql_real_escape_string($var_id);
}
When session_start() is called, the session at that point is locked for writing to any other source, except the current scope (.php file of execution) it's in. This is to make sure that no values can be changed during the readout of session values.
From the documentation
Session data is usually stored after your script terminated without the need to call session_write_close(), but as session data is locked to prevent concurrent writes only one script may operate on a session at any time. When using framesets together with sessions you will experience the frames loading one by one due to this locking. You can reduce the time needed to load all the frames by ending the session as soon as all changes to session variables are done.
To the getting stuck problem, I think the while loop is endless, request the page from your browser http://example.com/pathto/scripts/msg_scripts/msg.php and see what happens
$counter = 0;
while($last_msg_id <= $oldID)
{
usleep(10); // changing to be a bit faster
clearstatcache();
$result = mysql_query("SELECT id FROM messages ORDER BY id DESC LIMIT 1");
$row = mysql_fetch_array($result);
$last_msg_id = $row['id'];
$counter++;
if($counter > 100)
break;
}
echo "counted: {$counter}";
exit();