I have a script that posts form responses to a MySQL Database. However, it is on occasion posting twice to the table with seconds between each row.
Here is the handling script:
if (isset($_POST['SignIn']))
{
$Name = $_POST['Name'];
$Sleep = $_POST['Sleep'];
$Soreness = $_POST['Soreness'];
$Fatigue = $_POST['Fatigue'];
$Energy = $_POST['Energy'];
$Stress = $_POST['Stress'];
$Total = $Sleep + $Soreness + $Fatigue + $Energy + $Stress;
$Comments = $_POST['Comments'];
$sql = "
INSERT INTO
YDP_Wellbeing (Name, Sleep, Soreness, Fatigue, Energy, Stress, Total, Comments)
VALUES
('$Name', $Sleep, $Soreness, $Fatigue, $Energy, $Stress, $Total, '$Comments')";
if (mysqli_query($con, $sql))
{
$_SESSION['alert-type'] = 'success';
$_SESSION['alert-head'] = 'Welcome!';
$_SESSION['alert-body'] = 'Thank You <strong>' . $Name . '</strong> You\'re Response Has Been Submitted.';
header("location: index.php");
}
else
{
echo "Failed: " . mysqli_error($con);
}
}
Sometimes it posts once, other times it posts twice, so the issue is intermittent it would appear?
The most likely cause of the inconsistent behavior is the failure to stop the script after the redirect. Without adding die() or exit(), the script will continue to execute.
Since you've enclosed the section in an if clause that tests for a POST submission, I assume that if it fails the test it will present a form to be submitted. Since the script fails to terminate after the redirect, it will print the form again (and may or may not redirect).
Therefore what is likely happening is your user is submitting the form; and then upon seeing the same form presented after submission either
goes on his merry way,
resubmits the form, or
attempts to press the back button and resubmits the form accidentally
Your code is vulnerable to the followings Attacks
1.) sql injection Attack as you passed variable directly into sql queries. I have mitigated it using prepared statements
2.) Html Injections and XSS attack: you will need to ensure sanitization for form inputs. i used intval() for integers and strip_tags() for strings assuming that
you want to strip out dangerous html.
3.) session fixation attack. I also eliminate that using session _regenerate_id()
Here is your code Re written
<?php
$servername = "localhost";
$username = "db username goes here";
$pass = "your db password here";
$db_name = "your db name here";
// Create connection
$conn = new mysqli($servername, $username, $pass, $db_name);
// Check connection
if ($conn->connect_error) {
echo "Connection to db failed";
}
if(isset($_POST['SignIn'])) {
$Name = strip_tags($_POST['Name']);
$Sleep = intval($_POST['Sleep']);
$Soreness = intval($_POST['Soreness']);
$Fatigue = intval($_POST['Fatigue']);
$Energy = intval($_POST['Energy']);
$Stress = intval($_POST['Stress']);
$Total = $Sleep + $Soreness + $Fatigue + $Energy + $Stress;
$Comments = strip_tags($_POST['Comments']);
// prepare your data
// i stands for integers and s stands for string
$stmt = $conn->prepare("INSERT INTO YDP_Wellbeing (Name, Sleep, Soreness, Fatigue, Energy, Stress, Total, Comments) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->bind_param("siiiiiis", $Name,$Sleep,$Soreness,$Fatigue,$Energy,$Stress,$Total,$Comments);
$stmt->execute();
if($stmt){
echo "data inserted successfully";
// create session
session_start();
// prevents session fixation attacks using session regenerate id
session_regenerate_id();
//
$_SESSION['alert-type'] = 'success';
$_SESSION['alert-head'] = 'Welcome!';
$_SESSION['alert-body'] = 'Thank You <strong>' . $Name . '</strong> You\'re Response Has Been Submitted.';
header("location: index.php");
}else{
echo "data insertion failed";
}
}
$stmt->close();
$conn->close();
?>
Related
This is an assignment for a PHP course I'm taking. We created a database in mySQL, and we are working on making a website to view/insert/update/delete information in the database. Right now, I'm getting a "Page not working" error while running an if statement to see if an ID # already exists in the database.
I have tried commenting out parts of my code to determine where the problem is, and I'm pretty sure it's an issue with the code underneath my "database connections" comment. This is a beginner's class, and I'm following my professor's walkthrough video for the assignment, but I can't figure out what I'm doing wrong.
<?php
session_start(); //starts the session
//Set all variables
$uniqueid = $_POST["uniqueid"];
$breed = $_POST["breed"];
$color = $_POST["color"];
$furlength = $_POST["furlength"];
$dogweight = $_POST["dogweight"];
//test if variables come in correctly
//echo "variables: " . $uniqueid . $breed . $color . $furlength . $dogweight;
//test if all fields filled
if (($uniqueid == "") || ($breed == "") || ($color == "") || ($furlength == "") || ($dogweight == "")) {
$_SESSION["errormessage"] = "You must complete all fields!"; //error message if any field is empty
header("Location:insert.php");
exit;
}
else { //if all fields filled
$_SESSION["errormessage"] = ""; //no error message
}
//database connections -- THIS IS PROBABLY WHERE THE ISSUE IS
include("includs/openDBConn.php"); //include the database
//check that # adding isn't already part of database
$sql="SELECT UniqueID FROM Dogs WHERE UniqueID=".$uniqueid;
$result=$conn->query($sql);
if($result->$num_rows > 0) { //make sure database loads the rows
echo("num rows= ".$result->$num_rows); //echo the number of rows
}
else { //if there are no rows
echo("No data found"); //give error message
}
?>
On a different page, there are fields for me to type in UniqueID, breed, color, etc. This page is supposed to check that all fields are filled in (that part works), and then check if there is already a row with the UniqueID that I typed in. If there is, it's supposed to echo the number of rows it found with that UniqueID (which is supposed to be 1).
I'm very new to PHP, so if I'm missing any essential information please let me know. I appreciate any advice!
Your code is full of vulnerabilities. It is prone to sql injection, xss attack, csrf, html injection.
I have re-written it to avoid most of this issues.
1.) Sql Injection is now mitigated using prepare queries
2.) Html injection is mitigated using intval for integer variables and strip_tags for strings. you can read more about data validations and sanitization in php to see more options available
3.) xss attack has been mitigated via htmlentities(). you can also use htmlspecialchars(). Read more about all this things
see better secured codes below
Please put your database credentials where possible
I do not know whether this your unique id is a string or integer(number)
// if UniqueID is integer or number use i parameter
$stmt->bind_param("i", $UniqueID);
// if UniqueID is a string use s parameter
$stmt->bind_param("s", $UniqueID);
here is the code
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "ur dbname";
// Create connection
$connect = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($connect->connect_error) {
die("Connection to db failed");
}
session_start(); //starts the session
// ensure that the Id is integer using intval
//$uniqueid = intval($_POST["uniqueid"]);
// sanitize your data against xss and html injection
$uniqueid = strip_tags($_POST["uniqueid"]);
$breed = strip_tags($_POST["breed"]);
$color = strip_tags($_POST["color"]);
$furlength = strip_tags($_POST["furlength"]);
$dogweight = strip_tags($_POST["dogweight"]);
//test if all fields filled
if (($uniqueid == "") || ($breed == "") || ($color == "") || ($furlength == "") || ($dogweight == "")) {
$_SESSION["errormessage"] = "You must complete all fields!"; //error message if any field is empty
header("Location:insert.php");
exit();
}
//Avoid sql injection using prepared statement
$stmt = $connect->prepare("SELECT UniqueID FROM Dogs WHERE UniqueID = ?");
// UniqueID is integer or number use i parameter
$stmt->bind_param("i", $UniqueID);
// if UniqueID is a string use s parameter
//$stmt->bind_param("s", $UniqueID);
$stmt->execute();
$stmt -> store_result();
$stmt -> bind_result($UniqueID);
if ($stmt->num_rows >= "1") {
while ($stmt -> fetch()) {
// ensure that xss attack is not possible using htmlentities
// fetch UniqueID
echo "your UniqueID: .htmlentities($UniqueID). <br>";
}
}else{
echo "No data found";
}
$stmt->close();
$connect->close();
?>
you have a syntax error on $result->$num_rows, that should be $result->num_rows without the second dollar sign,
and of course, your example here has security vulnerabilities that you also need to address, but that is not your question
The form sends the data to this page. The print_r outputs everything I want to put into the table onscreen to check it's there, but nothing goes to the table. I have only managed to populate the table manually in phpmyadmin. Iam sorry if it's a really easy fix - I have only been learning for two weeks!
There are no errors showing in the logs or on screen when I run the page. The print_r does echo the array as it should be but nothing appears in the table
<?php
session_start();
// Change this to your connection info.
$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'root';
$DATABASE_PASS = '';
$DATABASE_NAME = 'users';
$username = ($_POST['username']);
$password = ($_POST['password']);
$companyName = ($_POST['companyName']);
$confirmPassword = ($_POST['confirmPassword']);
// Try and connect using the info above.
$con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS,
$DATABASE_NAME);
if (mysqli_connect_errno()) {
// If there is an error with the connection, stop the script and
display the error.
die ('Failed to connect to MySQL: ' . mysqli_connect_error());
}
print_r ($_POST);
// Now we check if the data was submitted, isset() function will check
//if the data exists.
if (!isset($_POST['username'], $_POST['password'],
$_POST['companyName'])) {
// Could not get the data that should have been sent.
die ('Please complete the registration form!');
}
// Make sure the submitted registration values are not empty.
if (empty($_POST['username']) || empty($_POST['password']) ||
empty($_POST['companyName'])) {
// One or more values are empty.
die ('Please complete the registration form');
}
print_r ($_POST);
// We need to check if the account with that username exists.
if ($stmt = $con->prepare('SELECT id, password FROM phplogin WHERE
username = ?')) {
// Bind parameters (s = string, i = int, b = blob, etc), hash the
//password using the PHP password_hash function.
$stmt->bind_param('s', $_POST['username']);
$stmt->execute();
$stmt->store_result();
// Store the result so we can check if the account exists in the
// database.
if ($stmt->num_rows > 0) {
// Username already exists
echo 'Username exists, please choose another!';
} else {
// Username doesnt exists, insert new account
/* $stmt = $con->prepare('INSERT INTO phplogin (username, password,
companyName ) VALUES (?, ?, ?)');*/
if (false !== true){
/* We do not want to expose passwords in our database, so hash the
password and use password_verify when a user logs in.
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
$stmt->bind_param('sss', $_POST['$username'], $password,
$_POST['$companyName']);
$stmt->execute();*/
$sql = 'INSERT INTO phplogin (username, password, companyName )
VALUES ($username, $password, $companyName)';
echo 'You have successfully registered, you can now login!';
echo (" ".$password." ".$username." ".$companyName);
echo ' well done';
} else {
/* Something is wrong with the sql statement, check to make sure accounts table exists with all 3 fields.*/
echo 'Could not prepare the new statement!';
print_r ($_POST);
}
}
}
$con->close();
?>
//$sql = 'INSERT INTO phplogin (username, password, companyName ) VALUES ($_POST[username], $password, $_POST[companyName])';
PHP thinks it should execute VALUES even though it is not any proper action. Use /* THIS IS COMMENT */ because it prevents stuff like this happening.
Also as a side note: Do not assign values in if statement. You can assign $stmt on its own line and just check
If($stmt === true) {}
Or
If($stmt !== true) {}
You get the point.
Also another side note is that you should prefer using PDO. It is alot of easier to handle and understand because of ts syntax and it makes OOP much much more easier. Mysqli is ok to use, but i personally do not recommend using it.
If I want to add content to the table using "INSERT INTO", I don't get an error message and the table is not filled. I'm new with PHP. explanations would be nice. The database runs on XAMPP.
I don't know what to try. I've already used another table, but it doesn't work. The user should have full access to the table. The names also match.
<?php
$username = $_POST["username"];
$passwort = $_POST["passwort"];
$mail = $_POST["mail"];
$passwort2 = $_POST["passwort2"];
$pass = sha1($passwort);
$db = mysqli_connect("localhost", "phptest1", "o84XM5wxo65QBjkF", "phptest1");
if($passwort == $passwort2) {
echo "Password is correct.";
$db = "INSERT INTO user (Username, Mail, Password) VALUES ('$username', '$mail', '$pass')";
} else if(!($passwort == $passwot2)) {
echo "Password is not correct";
} ?>
The variable $db actually contains information about the connection. You cannot insert a query into your database the way you are trying to
You can use $db (in your case) in order to check whether the connection has been correctly established or not and then if everything works correctly you can user mysqli_query() to inject the query into your database.
You can do it like so:
<?php
if(isset($_POST['submit'])){ //You have to check if your submit button is pressed
$username = $_POST["username"];
$passwort = $_POST["passwort"];
$mail = $_POST["mail"];
$passwort2 = $_POST["passwort2"];
$pass = sha1($passwort);
$db = mysqli_connect("localhost", "phptest1", "o84XM5wxo65QBjkF", "phptest1");
if(!$db){
die('Connection could not be established! Check provided information');
}
if($passwort == $passwort2) {
echo "Password is correct.Inserting query now";
$query = "INSERT INTO user (Username, Mail, Password) VALUES ('$username', '$mail', '$pass')";
$result = mysqli_query($db, $query); //keep $result for debugging purposes.
} else {
die("Password is not correct");
} //no need for else if as there are only 2 conditions.
if(!$result){ //check if query was successful.
die('Query Error');
}
echo "Query Updated successfully";
}
?>
This code is really simplistic and for testing purposes only.
I just wanted to show you the way you can send queries to your database. You better use other encryption techniques i.e. crypt() and of course functions like mysqli_real_escape_string() when retrieving data from users, in order to avoid potential injection attacks.
Check this post for more info about preventing injections.
Hope that helps.
This question already has answers here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Reference - What does this error mean in PHP?
(38 answers)
Closed 5 years ago.
I have a users table and I want to be able to delete a user when a link is clicked. $user_name is set in a session. Here is the link:
<?php echo "Delete Account" ?>
Here is the code on delete_user.php:
<?php
session_start();
session_destroy();
require "connection.php";
?>
<?php
if($_GET['id'] != ""){
$user_name = $_GET['id'];
$sql = "DELETE FROM users WHERE user_name='{$user_name}'";
$result = mysqli_query($connection, $sql);
header('Location: register.php');
}
?>
<?php include "footer.php";?>
I don't understand why it's not deleting the user from the database when this code is executed?
There's no clear reason as to why your code is not working. However, you mentioned being new to PHP, so picking up good practices with your code could (1) help solve the issue at hand, (2) make your code more efficient, and easier to debug.
I recommend you use mysqli in the object-oriented manner, it requires less code, and usually easier to follow.
Making the connection is simple:
<?php
$host = 'localhost';
$user = 'USERNAME';
$pass = 'PASS';
$data = 'DATABASE';
$mysqli = new mysqli($host, $user, $pass, $data);
// catch errors for help in troubleshooting
if ($mysqli->errno)
{
echo 'Error: ' . $mysqli->connect_error;
exit;
}
?>
Creating a safe environment for your server keep in mind these things:
Do not trust user input (ever!)
Do not perform direct queries into your database.
When developing, break your code into steps so you can easily troubleshoot each part.
With those three simple things in mind, create a delete file.
<?php
if (isset($_GET['id'])
{
// never trust any user input
$id = urlencode($_GET['id']);
$table = 'users';
// set a LIMIT of 1 record for the query
$sql = "DELETE FROM " . $table . " WHERE user_name = ? LIMIT 1";
// to run your code create a prepared statement
if ($stmt = $mysqli->prepare( $sql ))
{
// create the bind param
$stmt->bind_param('s', $id);
$stmt->execute();
$message = array(
'is_error' => 'success',
'message' => 'Success: ' . $stmt->affected_rows . ' were updated.'
);
$stmt->close();
}
else
{
$message = array(
'is_error' => 'danger',
'message' => 'Error: There was a problem with your query'
);
}
}
else
{
echo 'No user id is set...';
}
The code will help you set the query, and delete the user based on their user_name... Which I am not sure that is the best solution, unless user_name is set to be an unique field on your MySQL database.
Firstly this is a horrible way to do this, you are prone to SQL Injections and also using GET literally just tags the query to the end of the URL which is easily obtainable by a potential hacker or ANY user as a matter of fact. Use POST instead with a bit of jQuery magic, I would also recommend using Ajax so that you don't get redirected to php file and it will just run. As it is not anyone can access that URL and delete users so I recommend using PHP SESSIONS so that only people from your site can delete users. Also simply passing the id to the PHP file is very insecure as ANYONE could simply create a link to your php file on their site and delete users.
Therefore try this to fix your code (with added security):
PLEASE NOTE: I am aware that this may not be the best way nor the worst but it is a fairly secure method that works well.
Your main page, index.php:
<?php
session_start();
// Create a new random CSRF token.
if (! isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = base64_encode(openssl_random_pseudo_bytes(32));
}
// Check a POST is valid.
if (isset($_POST['csrf_token']) && $_POST['csrf_token'] === $_SESSION['csrf_token']) {
// POST data is valid.
}
?>
...
<form id="delete_user_form" action="delete_user.php" method="post">
<input type="hidden" name="user_id" value="<?php echo $user_name; ?>" />
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>" />
<input type="submit" value="Delete User" />
</form>
In your .js file (make sure you have jQuery linked):
window.csrf = { csrf_token: $("input[name= csrf_token]").val() };
$.ajaxSetup({
data: window.csrf
});
$("#delete_user_form").submit(function(event) {
event.preventDefault(); //Stops the form from submitting
// CSRF token is now automatically merged in AJAX request data.
$.post('delete_user.php', { user_id: $("input[name=user_id]").val() }, function(data) {
//When it it's complete this is run
console.log(data); //With this you can create a success or error message element
});
});
Now for your delete_user.php file, this should fix the errors:
<?php
session_start();
require "connection.php";
// Checks if csrf_token is valid
if (isset($_POST['csrf_token']) && $_POST['csrf_token'] === $_SESSION['csrf_token']) {
if(isset($_POST['user_id']) && $_POST['user_id'] != ""){
$user_name = $_POST['user_id'];
$sql = "DELETE FROM users WHERE user_name = '$user_name' LIMIT 1"; //LIMIT 1 only allows 1 record to be deleted
if ($conn->query($sql) === TRUE) {
echo "Record deleted successfully"; //You get this in your javascript output data variable
} else {
echo "Error deleting record: " . $conn->error; //You get this in your javascript output data variable
}
$conn->close();
}
}
?>
I don't know what your connection.php contains so this is what I'd put in it:
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
My PHP script was written to send email and SMS when some new information is entered in the front end to members in database. However the email code and SMS code are working individually, but when put together the code is not getting executed.
The code in fact skipped. I tried making a deliberate error in the called function but it did not recognize it. Why?
<?php
error_reporting(E_ALL ^ E_NOTICE);
define('INCLUDE_CHECK', true);
require 'functions.php';
include ("generatesms.php");
include ("class.phpmailer.php");
include ("../sendsmsV3.5/sendsmsV3.5/CurlProcess.php");
include ("../sendsmsV3.5/sendsmsV3.5/Way2Sms.php");
include ("class.smtp.php");
// The above files can be included only if INCLUDE_CHECK is defined
$host = "localhost"; // Host name
$username = "root"; // Mysql username
$password = ""; // Mysql password
$db_name = "test"; // Database name
$tbl_name = "mails"; // Table name
// Connect to server and select database.
mysql_connect($host, $username, $password) or die("cannot connect");
mysql_select_db($db_name)or die("cannot select DB");
// Get values from form
$subject = $_POST['subject'];
$email = $_POST['email'];
$phone = $_POST['phone'];
//$dept = $_POST['dept'];
$content = $_POST['content'];
$month = $_POST['birthday-mm'];
$day = $_POST['birthday-dd'];
$year = $_POST['birthday-yyyy'];
$date_eve = "$year-$month-$day";
$dept = $_POST['branch'];
if (empty($dept)) {
echo("You didn't select any DEPEARTMENTS.");
} else {
$N = count($dept);
for($i=0; $i < $N; $i++) {
echo $dept[$i]; echo "<br>";
$dep = $dept[$i];
// Insert data into mysql
$sql = "INSERT INTO $tbl_name(subject, body, dept, phone, email, date_eve) VALUES ('$subject', '$content', '$dep', '$phone', '$email', '$date_eve')";
$result = mysql_query($sql);
// if successfully insert data into database, displays message "Successful".
if ($result) {
echo "Successful";
echo "<BR>";
newssender($dept, $content, $subject);
generatesms($dept,$date_eve,$subject);
echo "<a href='index.php'>Back to main page</a>";
} else {
echo "ERROR";
}
}
}
// close connection
mysql_close();
Firstly you have a big problem with all of your SQL. You shouldn't use mysql_* functions as they are deprecated and you're not sanitizing your inputs leaving you exposed to vulnerabilities. (http://www.tizag.com/mysqlTutorial/mysql-php-sql-injection.php)
If you could pose your newssender() function code I can give you a detailed/specific answer but in the meantime I will give a general solution that goes through some debugging processes for other users.
if you have code like this:
myFunction1();
myFunction2();
and myFunction1() is run but myFunction2() is NOT, you can try commenting out // myFunction1() (which it sounds like you did) and at that point if myFunction2() runs then obviously the problem resides in myFunction1(). Here are the things to look for:
Fatal errors. Make sure you have errors and notices turned on to find syntax or other errors in your code
Look for any die or exit that may exist in your code. Those end the script and no more code is executed.
A quick way to test #2 is to do this:
myFunction1();
echo 'I made it here!';
If you don't see "I made it here!" on your screen then obviously the code didn't get that far, meaning the code ended before it returned from myFunction1()
I hope that helps!