I am trying to present the user with a confirm yes/no prompt before deleting an author from a Mysql Database. When a user hits Delete in the authors.html.php, the controller includes a confirm.php. The confirm.php prompts the user for a yes or no to confirm. If the yes button is clicked, the confirm.php is meant to pass the id back to the controller which then checks if the action isset, and if yes, delete the author based on the id.
Unfortunately the author does not get deleted, so the issue is with the the inclusion of the confirm prompt. Without the confirm include, the script works perfectly well, but I want to figure out what is going wrong and it's all too easy to use Javascript.
Any help appreciated.
My controller: index.php
//inlcude the data connection.
include $_SERVER['DOCUMENT_ROOT'] . '/authors/includes/db.inc.php';
try
{
$result = $pdo->query('SELECT id, name FROM author'); //Rows of a result set returned by fetch are represented as associative arrays,
}
catch (PDOException $e)
{
$error = 'Error fetching authors from the database!';
include 'error.html.php';
exit();
}
foreach ($result as $row)
{
$authors[] = array('id' => $row['id'], 'name' => $row['name']);
}
include 'authors.html.php';
if(isset($_POST['action']) and $_POST['action'] == 'Delete') {
include "confirm.php";
if(isset($_POST['action']) and $_POST['action'] == 'Yes') {
try {
$sql = 'DELETE FROM author WHERE id = :id';
$s = $pdo -> prepare($sql);
$s->bindValue(':id', $_POST['id']);
$s->execute();
}
catch (PDOException $e) {
$error = "Error deleting author.";
include 'error.html.php';
exit();
}
header('Location: .');
exit();
}// if yes
} // end if isset delete
The authors.html.php then displays a list of authors:
<?php foreach ($authors as $author): ?><!-- loop through the list of authors pulled from the database by the controller -->
<li>
<form action="" method="post">
<div>
<?php htmlout($author['name']); ?> <!--display a list of authors and an edit and delete button-->
<input type="hidden" name="id" value="<?php
echo $author['id']; ?>">
<input type="submit" name="action" value="Edit">
<input type="submit" name="action" value="Delete">
</div>
</form>
</li>
<?php endforeach; ?>
confirm.php ......
<form action="" method="post">
<input type="hidden" name="id" value="<?php echo $author['id']; ?>">
<input type="submit" name="action" value="Yes">
<!--input type="submit" name="action" value="No"-->
</form>
Strictly speaking in terms of PHP, Instead of trying to process everything in a single action file (controller in MVC), what you should be doing is.. Make the second form to post to a different controller.
Say you have a form/table that contains the button/form that deletes the author. Let that form/button call a file named as confirm.php with the id of that author passed.
Inside the confirm page you render the confirm form with the yes/no input. And then this confirm.php will post to a delete.php which will check if the confirmation value is set inside the $_GET/$_POST and proceed as such.
Also on a side note I recommend that you learn some very basic javascript and use the confirm() function.
Also on a side side note, I strongly recommend that you learn some validation, sanitization, escaping, and about sessions.
Sorry I cant put comment in your Post, just a answer (I dont have required reputation).
So, your logic is wrong, see:
if(isset($_POST['action']) and $_POST['action'] == 'Delete') {
include "confirm.php";
if(isset($_POST['action']) and $_POST['action'] == 'Yes') {
When the $_POST['action'] == 'Yes' the script will not pass to the:
try {
$sql = 'DELETE FROM author WHERE id = :id';
$s = $pdo -> prepare($sql);
$s->bindValue(':id', $_POST['id']);
$s->execute();
}
Because the $_POST['action'] is not 'Delete' anymore.
I think the condition if(isset($_POST['action']) and $_POST['action'] == 'Yes') must be outside the if(isset($_POST['action']) and $_POST['action'] == 'Delete').
Related
I'm trying to create a form on a webpage, which takes an id number entered by the user, and deletes the corresponding record in a database. I'm unable to get it working.
This is the delete code which isn't working:
<?php
if (isset($_POST['deleteSubmit'])) {
$details = $conn->real_escape_string($_POST['deleteNum']);
$deleteSQL = "DELETE FROM userName WHERE id = '$details'";
$result = $conn->query($deleteSQL);
if (!$result) {
echo 'Error!';
exit($conn->error);
} else {
header('Location: index.php');
exit;
}
}
?>
<h4>DELETE NAME (DELETE)</h4>
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
<label for="num">Enter User Reference to be Deleted:</label><br>
<input num="deleteNum"type="number"><br>
<input num="deleteSubmit" type="submit" value="Delete">
</form>
For reference, this is the post code which is working (it's being used to add names to the database):
<?php
if (isset($_POST['nameSubmit'])) {
$details = $conn->real_escape_string($_POST['newName']);
$insertSQL = "INSERT INTO userName (name) VALUES ('$details')";
$result = $conn->query($insertSQL);
if (!$result) {
echo 'Error!';
exit($conn->error);
} else {
header('Location: index.php');
exit;
}
}
?>
<h4>ENTER NAME (POST)</h4>
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
<label for="fname">Enter Name:</label><br>
<input name="newName"type="text"><br>
<input name="nameSubmit" type="submit" value="Submit">
</form>
The database connection file is being called in both programs and is working for the post.php element, which is why I haven't included it or reference to it.
The database has one table called userName which contains two columns id (which is auto incremented) and name.
I've tried changing some of the syntax on the delete.php file with no success. I've ran the $deleteSQL code directly in my database and it works.
I see no error messages when enter an id and click the delete button.
For anyone who reads this in future, the query was solved by #kenlee;
(1) Change num="deleteSubmit" to name="deleteSubmit"
(2) change num="deleteNum" type="number" to name="deleteNum" type="number"
(3) Please use paratemerized prepared statement in your queries
So I am trying to prevent form resubmission using sessions
and this is my code :
<?php
session_start();
if(isset($_GET['unid']))
{
if ($_GET['unid']==$_SESSION["uid"])
{
echo "Form is Submited do something";
}
else
{
echo "no you can't do that";
}
}
$unid = md5(uniqid());
$_SESSION["uid"] = $unid;
?>
<form method="GET">
<input name="name" value="test">
<input name="unid" value="<?php echo $unid;?>">
<input type="submit">
and it works ...but if the user opens another tab then it will break so how can I fix it ?
I'm not sure about this but may be assigning a new global session variable will work, say $_SESSION['checkSub']. So once the form is submitted, set it to 1 or true and only let form submission if it isn't 1 or false.
You can check to see if the unid is set in the session before generating a new unique id. See updated code below:
<?php
session_start();
if(isset($_GET['unid']))
{
if (isset($_SESSION['unid']) && $_GET['unid']==$_SESSION['unid'])
{
//form has been submitted with matching unid - process it as needed
unset($_SESSION['unid']);
}
else
{
// Form was resubmitted or some other logic error
}
}
$unid = ''; //declare here for good scope
if (isset($_SESSION["unid"])) {
$unid = $_SESSION["unid"];
}
else {
$unid = md5(uniqid());
$_SESSION["unid"] = $unid;
}
?>
<form method="GET">
<input name="name" value="test">
<input name="unid" value="<?php echo $unid;?>">
<input type="submit">
Rather than using form method GET, try to use POST. It will work for you. The $_POST array will only have data in it when form is submitted, so you should not have to use the session to know whether form is submitted or not.
I have database generated content in a table with edit and delete buttons in a form at the end of the row.
<td>
<form action="?" method="post">
<div class="">
<input type="hidden" name="id" value="<?php htmlspecialchars($item['id']); ?>">
<input type="hidden" name="action" value="edit_daily_shift_report">
<input type="submit" value="Edit" onclick="return confirm('Edit this report?');">
<input type="hidden" name="action" value="delete_daily_shift_report">
<input type="submit" value="Delete" onclick="return confirm('Delete this report?');">
</div>
</form>
</td>
If I remove the delete button, the edit code works fine. But with both buttons present, the edit button fails and the item in the row is deleted. I am stumped. Not only is the action value of the edit button ignored, the action value of the delete button is executed. Any help is appreciated!
Here is the controller edit and delete code:
/*********************** Edit Daily Shift Report ************************/
if (isset($_POST['action']) && $_POST['action'] === 'edit_daily_shift_report')
{
include '../includes/dbconnect-local.php';
try
{
$sql = 'SELECT * FROM daily_shift_report WHERE id = :id';
$s = $db->prepare($sql);
$s->bindValue(':id', $_POST['id']);
$s->execute();
}
catch (PDOException $e)
{
$error = 'Error deleting data.' . $e->getMessage();
include 'error.html.php';
exit();
}
// Assign page title value
$pageTitle = 'Edit Daily Shift Report';
// Store single row resut in $item associative array
$item = $s->fetch(PDO::FETCH_ASSOC);
// Display report content in form
include 'edit_daily_shift_report.html.php';
exit();
}
/********************* Delete from Daily Shift Report *******************/
if (isset($_POST['action']) && $_POST['action'] === 'delete_daily_shift_report')
{
include '../includes/dbconnect-local.php';
try
{
$sql = 'DELETE FROM daily_shift_report WHERE id = :id';
$s = $db->prepare($sql);
$s->bindValue(':id', $_POST['id']);
$s->execute();
}
catch (PDOException $e)
{
$error = 'Error deleting data.' . $e->getMessage();
include 'error.html.php';
exit();
}
echo '<span style="color:#ff0000;">Daily Shift Report DELETED successfully!</span>';
}
Thank you.
You need to understand how the post request works. As you know, you have two action fields, one for delete and one for edit.
Your problem is in short that there is no way to Connecticut specific input fields to different buttons.
What i would rather suggest is that you set the name of the buttons to action and the value as the value you already use for the hidden fields.
With this you also have to make a minor change in your html. Instead of:
<input type="submit" value="something" onclick="something">
Use this:
<button name="action" value="edit" onclick="something">Edit</button>
And the same goes for delete button
When you use button tag instead of input, you can set a value to the button which is different from the display, which makes it a cleaner PHP code when checking the value of $_POST['action'] afterwards
I am looking to develop a website containing stages. I want for example to pass by the stage 2 only when i click on the finish button in the page of stage 1 so the stage 2 page can't be accessible by its url or whatever only if the user pass by another page.
Is there a method to do this ??? i am a beginner in security so please try to help me, thanks in advance coders
Make use of sessions to develop this model.
index.php
<?php
#extract($_POST);
if(isset($sub))
{
session_start();
$_SESSION['authenticate']=true;
header("location:test1.php");
exit;
}
?>
<form action='' method="post">
<input type="SUBMIT" name="sub" value="Finish" />
</form>
open.php
<?php
session_start();
if(!isset($_SESSION['authenticate']))
{
echo "You are not allowed to access";
}
else { echo "You came from index.php ! so you are a valid user"; }
session_destroy(); //<-- I added this so you can test your example multiple times.
I think, this show work :)
Use can either redirect your user directly from index.php to open.php
header('Location : open.php');
Or,
in open.php, put this
if($_SERVER['HTTP_REFERER'] == 'index.php page's full link') {
//Do or Show whatever you want to show here
} else {
// Tell the user that you are not authorized
}
If that doesn't work, echo $_SERVER['HTTP_REFERER'] and see what link it gives you. And put that link where specified above.
Cool? :)
Edit (As per the comments) --
Lets say you have a form in your form in stage1.php
<form method="post" action="">
<span class="error"><?php echo $error; ?></span>
Name: <input type="text" name="name"><br/>
Email: <input type="text" name="email"><br/>
<input type="submit" name="submit" value="Submit">
</form>
use this php in stage1.php
if (isset($_POST['name'])||isset($_POST['email'])) {
if (!empty($_POST["name"])||!empty($_POST["email"])) {
$error = "Please fill in all the fields correctly";
}
else {
$name = $_POST['name'];
$email = $_POST['email'];
//You can also save the above Variables Globally by $GLOBALS['name'] = $_POST['name'];
//So that you can use the details when you reach the final stage
header('Location : stage2 page's link');
}
}
?>
and in Page 2 lets say you have another form, then there also check
<?php
if(!empty($name)||!empty($email)) {
//the above is check for global variables email and name are not empty - means stage 2 was filled properly
//Do things for the second page's form like you did for stage 1
} else {
header('Location : stage1 page's link');
//redirect back to stage 1.
}
?>
I have a Customer Details PHP page. To get to this page, the user either signs up with new details on signup.php or they log in on login.php.
Ive been told the best way to submit data and be redirected to the correct page is to use action="details.php" in the form, and then at the start of the details.php file use the values from the $_POST array to populate my SQL database.
However, I need to do the same sort of thing with the login.php code, so at the top of details.php there will be the code to enter the form data from signup.php and the verifying code from login.php.
Surely there is a way of doing the data submission directly from signup.php so there isnt two sets of PHP in the details.php file? If not how do i differentiate so that login only uses the login code and signup uses the submit code?
Common practice is to have PHP check for form data+possible redirect and after that form print
Example: (my common usage)(i merged login&signup into one file)
<?php
$error = "";
if( !empty($_POST['signup']) ){
//do signup
//$signup = assign true/false whether sign up was successfull or not
if( !$signup ){ //if signup wasnt successfull generate error
$error = "Sign up error.";
}
}
if( !empty($_POST['login']) ){
//do login
//$login = assign true/false whether login was successfull or not
if( !$login ){ //if login wasnt successfull generate error
$error = "Log in error.";
}
}
if( empty($error) ){
//there were no errors
header("Location: details.php"); //redirect to details.php
exit(); //send nothing else!
}
?>
<div class="error"><?php if(!empty($error)){ echo htmlspecialchars($error); /*escape*/ } ?></div>
<form action="#" method="POST">
<input type="hidden" name="signup" value="yes">
<!-- ...some other input fields... -->
<button type="submit">Sign Up</button>
</form>
<br>
<form action="#" method="POST">
<input type="hidden" name="login" value="yes">
<!-- ...some other input fields... -->
<button type="submit">Log In</button>
</form>
You could set a hidden field on each page as below:
<input type=hidden name='referrerpage' value='signup'>
AND
<input type=hidden name='referrerpage' value='login'>
and do:
if ($_POST['referrerpage']=='signup'){
//do this
} else{
//do this
}