I've created a code that updates an Sql entry, but when you leave an value blank, it removes the existing value.
<?php
$servername = "localhost";
$username = "root";
$password = "HahahNo";
$dbname = "DATA";
$id = $_POST["id"];
$firstname = $_POST["firstname"];
$lastname = $_POST["lastname"];
$email = $_POST["email"];
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "UPDATE MyGuests SET firstname='$firstname', lastname='$lastname', email='$email' WHERE id=$id";
if ($conn->query($sql) === TRUE) {
echo "Success";
} else {
echo "Error updating record: " . $conn->error;
}
?>
Is there any way not to clear the not filled in values? Im fairly new to php.
Check if $_POST contains values.
First check if $_POST value has been set with isset() (has been posted).
Then check if the string isn't empty with strlen():
if (!isset($_POST['firstname'] || strlen($_POST['firstname']) == 0) {
echo 'Please enter first name';
} else {
// Do your DB update
}
Edit: Naturally empty() is better because you only need one check to do:
if (empty($_POST['firstname']) {
echo 'Please enter first name';
} ...
Thanks to #Fred -ii-
Edit II: As pointed out by #alex
if ($_POST['firstname']) {
echo 'Please enter first name';
} ...
would work too. Explained in PHP type comparison tables
You can write condition before execute function,
//all values are not null then update is perform
if(!is_null($firstname) && !is_null($lastname) && !is_null($email)){
if ($conn->query($sql) === TRUE) {
echo "Success";
} else {
echo "Error updating record: " . $conn->error;
}
}
What you're looking for is validation of user-supplied data. You're right - a user who hasn't read the instructions of your form could cause unintended data loss. Additionally a malicious user or innocent child could cause more harm with SQL injection.
First check your field meets minimum requirements. You could validate email addresses, postcodes, phone numbers, URLs... but to answer your question Daenu's answer is perfect.
Once you are satisfied the data meets your databases' requirements, check it is safe. Strip it of any malicious SQL commands. You can use prepared statements with PDO or MySQLi.
Also think about the specification of the data. Is the data type of each field a string or integer or float? What character set is your web page in (UTF-8 is a safe choice) and therefore what character set does your data arrive with? Does your database match (UTF8MB4 is a good companion)?
Related
I am using this code to send data to mysql database and its functioning well though users are sending blank data and duplicating too.
<?php
require "conn.php";
$lostidno = $_POST ["lostidno"];
$phonenol = $_POST ["phonenol"];
$mysql_qry = "INSERT INTO lostdb.lost (lostidno, phonenol) VALUES ('$lostidno', '$phonenol')";
if ($conn->query($mysql_qry) === TRUE)
{
echo "Information Recieved!";
}
else
echo "Sorry! An Error Occured:" . $mysql_qry . "br" . $conn->error;
$conn->close();
?>
How do I prevent this?
You can use trim function to remove spaces at the beginning and the ending of a string. After that you are able to check if the two parameters aren't empty:
<?php
require "conn.php";
$lostidno = trim($_POST["lostidno"]);
$phonenol = trim($_POST["phonenol"]);
if(!empty($lostidno) && !empty($phonenol))
{
$mysql_qry = "INSERT INTO lostdb.lost (lostidno, phonenol) VALUES ('$lostidno', '$phonenol')";
if ($conn->query($mysql_qry) === TRUE) {
echo "Information Recieved!";
}
else {
echo "Sorry! An Error Occured:" . $mysql_qry . "br" . $conn->error;
}
$conn->close();
}
?>
You should also have a look at this to prevent SQL injections.
1. To avoid blank values
Check the values of variables before executing insert query on database using empty() PHP function.
2. Avoid duplicate values
You can do it in two ways, Either specify UNIQUE constriant in database TABLE or run SELECT query before inserting data into database.
//this to check the duplicate records
Fire the select query : select * from lostdb.lost where col1= $lostidno and col2 = $phonenol;
//this is to check the blank condition
if($lostidno !== "" && $phonenol != "")
{
$mysql_qry = "INSERT INTO lostdb.lost (lostidno, phonenol) VALUES ('$lostidno', '$phonenol')";
}
The best way to prevent duplicates is to mark the unique database columns as UNIQUE
ALTER TABLE <table_name> ADD UNIQUE(<column_name>);
To prevent blank data from ever getting into the database you need to check them with a few modifications in the code you posted:
if( ($lostidnol != "") && ($phonenol != "") )
{
if ($conn->query($mysql_qry) === TRUE)
{
echo "Information Recieved!";
}
else
{
//error
}
}
else
{
//Notify the user that they're trying to insert blanks
}
If you want to provide proper user experience you should also provide some client side validation using JavaScript or jQuery
Use trim function to remove blank spaces from string.
<?php
require "conn.php";
$lostidno = trim($_POST ["lostidno"]);
$phonenol = trim($_POST ["phonenol"]);
//Check record exist or not.
$unique_check = "select count(*) as cnt from lostdb.lost where lostidno='".$lostidno."' and phonenol='".$phonenol."'";
//Execute above query and check record already exist or not. If record not exist then only allow to insert it.
$result_unique_check = $conn->query($mysql_qry)->one();
$record_exist = $result_unique_check['cnt'];
if($record_exist > 0){
echo "Record alreay exist.";
}else{
//Insert new record
$mysql_qry = "INSERT INTO lostdb.lost (lostidno, phonenol) VALUES ('$lostidno', '$phonenol')";
if ($conn->query($mysql_qry) === TRUE)
{
echo "Information Recieved!";
}
else
echo "Sorry! An Error Occured:" . $mysql_qry . "br" . $conn->error;
$conn->close();
}
?>
I need to create a form that gathers a first name, last name, and an email address. I have created a table in MySQL called guestbook. The table looks something like the following:
CREATE TABLE guestbook (
id int unsigned NOT NULL AUTO_INCREMENT,
firstName varchar(50) NOT NULL,
lastName varchar(50) NOT NULL,
email varchar(250) NOT NULL,
status int NOT NULL,
sort int NOT NULL
);
And here is my code thus far:
<?php
Global $Conn;
$Conn = new mysqli("localhost","151_millet","2gZMXYGC","GUESTBOOK");
if(!$Conn) {
$ErrorMsg = "Couldn't connect to the database";
}
$FName = $_POST["fname"];
$LName = $_POST["lname"];
$Email = $_POST["email"];
// The series of ifs below tests to see if each field is blank
// If it is blank it will output an error message for each that is blank
if($FName == "") {
$ErrorMsg .= "First Name Was Left Blank<br>";
}
if($LName == "") {
$ErrorMsg .= "Last Name Field Was Left Blank.<br>";
}
if($Email == "") {
$ErrorMsg .="Email field was left blank.<br>";
}
I have no idea how to check for duplicates in the email field. Any help would be appreciated. I think I need to come up with a way to test $_POST against whats already in the db.
Alrighty, now we've cleaned up this question a bit. Let's get down to business.
You want to check for duplicates in your database. There are a couple of things you need to do for this. Let's try to keep this as simple as possible while we're working on it too.
First off, it's good to see you're using MySQLi and not the deprecated mysql_* functions. But we can handle MySQLi in a more object oriented manner. Also, using globals is frowned upon (and is actually not necessary, even in your current code!)
One other thing to note is that there are slightly different styles of code used in modern PHP, like camel case, and how you format if statements. If you're interested in learning PHP, then you should take a look at the PHP-FIG PSRs.
<?php
$conn = new mysqli("localhost", "151_millet", "2gZMXYGC", "GUESTBOOK");
if ($conn->connect_errno) {
// This is an error that will stop us from continuing, so assigning
// the error message to a string, doesn't really help us in this case
// The application NEEDS to stop
throw new RuntimeException("Unable to connect to MySQL database.");
}
$firstName = $_POST["fname"];
$lastName = $_POST["lname"];
$email = $_POST["email"];
if (!$firstName || !$lastName || !$email) {
echo "Please make sure to fill in all of your details.";
// You may want to handle this differently, this is just to keep things
// Very simple
exit;
}
$query = "SELECT COUNT(1) FROM guestbook WHERE email = ?";
$stmt = $conn->prepare($query);
$count = 0;
if ($stmt) {
$stmt->bind_param("s", $email);
$stmt->execute();
$stmt->store_result();
$count = $stmt->num_rows;
$stmt->close();
}
if ($count > 0) {
echo "A user with that email address already exists.";
exit;
}
// Do other stuff
That should help you out with what you need to do to check if an email address already exists. But you should also enforce this in your database by adding a unique key to the email column. That will mean that even if your code fails and would allow a duplicate email address entry, your database won't.
I have been trying to get a page working for a number of days now, and there doesn't seem to be much help from the "related" questions on this site.
I have made a signup.php page, which has a form for inputting user credentials to signup up for the site I am building, when the form is filled out and the user presses the 'submit' button, the form uses the action "signupsuccess.php" which has all of the php code for inserting the credentials into the database, and then redirects the user to the "Login.php" page.
My problem:
I have written code to say that if the user has not put in any data for one of the fields in the form, then they are brought back to the signup.php page by using this code:
<?php
if(!isset($_POST['fname'])&&($_POST['lname'])&&($_POST['email'])&&($_POST['pass'])){
header('Location:Signup.php');
exit;
}
else{
$host = "localhost";
$user = "******";
$password = "******";
$conn = mysql_connect($host, $user, $password);
$db = mysql_select_db('*****', $conn);
if(! get_magic_quotes_gpc() )
{
$fname = addslashes ($_POST['fname']);
$lname = addslashes ($_POST['lname']);
$email = addslashes($_POST['email']);
$pass = addslashes($_POST['pass']);
}
else
{
$fname = $_POST['fname'];
$lname = $_POST['lname'];
$email = $_POST['email'];
$pass= $_POST['pass'];
}
$query = mysql_query("select * from users where pass='$pass' AND email='$email'", $conn);
$rows = mysql_num_rows($query);
if ($rows == 1) {
$errors[] = 'That user already exists, try another email';
}else
{
$sql = "INSERT INTO users ".
"(fname,lname, pass, email) ".
"VALUES('$fname','$lname','$pass','$email')";
$retval = mysql_query( $sql, $conn );
if(! $retval )
{
die('Could not enter data: ' . mysql_error());
}
}
}
mysql_close($conn);
?>
But the header() just won't bring the user back when they haven't put anything in to the fields. Is there anything I am doing obviously wrong or can anyone help me sort out the redirection of the user if they haven't entered anything.
Your if statement is incorrect. If you're just trying to check to see if those variables are set you need to call isset() on all of them.
You can do this with individual calls to isset() or all in one call.
if(!isset($_POST['fname'],$_POST['lname'],$_POST['email'],$_POST['pass'])){
header('Location:Signup.php');
exit;
}
FYI, you are wide open to SQL injections. addslashes() does not prevent SQL injections. Also, the mysql_* funcstions are obsolete and you should not be writing new code using them. Look into mysqli or PDO instead.
I don't think you really need a redirection, you probably should overcome this issue from the frontend, maybe a js validation could do the trick and is way simpler.
1.- change the action of submit to run the function "validate()"
2.- create the function that will be something like:
$(document).ready(function(){
function validate(){
if ($.trim($("#inputid").val()) == ""){
$(this).css('border', '2px solid red');
} else if ($.trim($("#inputid2").val()) == "") {
$(this).css('border', '2px solid red');
} else if ($.trim($("#inputid3").val()) == "") {
$(this).css('border', '2px solid red');
} else {
submit();
}
}
});
Where '#input?' is the selector for the input you want to validate and null is the value that you want to avoid, in this case, no value, just empty input. Then if all the inputs are filled it will execute submit() function which you should create to do whatever he has to.
Note: This kind of selectors are for jquery so you must include it in your code as well, put this in your header
<script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
Note 2: This is the frontend approach. I don't know if this is convenient but at least is an option and helps.
Good luck!
Your if statement was the problem. because the isset was only affecting
$_POST['fname'],
the if statment was being skipped so
header('Location:Signup.php')
was not being reached.
I like to put
echo 'test';
in my code while i am testing it and move it around the code. That way, if it is not echoing 'test', i know that the code isn't even being reached. That could have helped you in this case, showing you that the problem wasn't the header, it was the if statement. Also, consider using PDO for mysql connections. It is more secure against mysql injections.
Your condition (if corrected according to the previous answers) would still always result in the else case. Since you are checking for $_POST fields, those will always be present. isset()returns false if the variable is not set (but it is: it comes from your form) or is NULL (which it is not: it contains an empty value). So, isset() will return true fopr every field. What you need is, for each field: if (empty(trim($_POST['fname']))) || ... )empty() returns false when the variable is not set or empty (i.e NULL, an empty string, 0, 0.0, false, etc, see here: http://php.net/manual/en/function.empty.php)Plus, you need to do something about the deprecated mysql_functions and your vulnerability to attacks.
I'm trying to check for an existing entry in MySQL before executing the INSERT statement. If the user enters a name already in the database (field is set to unique) then they should be prompted to re-enter the name.
The problem I'm having is that if the new entry matches a record in any form then the error message displays and no INSERT happens.
For example, if the user enters DUMMY_NEW and there is a record DUMMY_OLD they aren't able to add the record even though DUMMY_NEW does not exist in the table.
I've searched and tried other answers already but can't seem to get this to work.
Code with extraneous bits removed for clarity:
//Create connection to database using mysqli
$conn = new mysqli($dbhost, $dbuser, $dbpass, $db);
//Set variables according to user input on previous form
$Server_Name = $_POST['Server_Name'];
//Check for duplicate server name - if exists inform user else run INSERT ($stmt)
$checkdup = "SELECT * FROM dcr_table WHERE SERVER_NAME = '".$Server_Name."'";
$dupresult = $conn->query($checkdup);
if($dupresult = 1)
{
print "<br>Error! <p></p>";
echo "" . $Server_Name . " already exists in the DCR";
print "<p></p>Please check the Server Name and try again";
}
else {
//Define the INSERT statement
$stmt = "INSERT INTO dcr_master (Server_Name, Description,..., ... , ... )";
//Execute the INSERT statement
$conn->query($stmt);
//Success and return new id
echo "<br><p></p>Record Added!<p></p>";
echo "New id: " . mysqli_insert_id($conn);
//Drop the connection
$conn->close();
};
Edit:
I'm aware of the injection vulnerability. The MySQL account only has SELECT, INSERT and UPDATE rights to the table. The end user must supply the password or submit will fail. This is small app with limited user access at the moment. MySQL escape strings will be implemented after current issue is resolved.
Edit 2:
Using Hobo Sapiens method does work in reporting an existing entry however a new (empty) row is still added to the table. The record ID still auto-increments so what I get is id#300 - record, id#301 - blank, id#302 - record. Is this a result of the IGNORE in the INSERT statement?
Your code creates a race condition if two people attempt to create the same ame at the same time and you're not handling the fallout properly.
If you have set the SERVER_NAME column to UNIQUE then you needn't check for the existence of a server name before you perform your INSERT as MySQL will do that for you. Use INSERT IGNORE ad check the number of affected rows after the query has executed to find out if it worked:
//Create connection to database using mysqli
$conn = new mysqli($dbhost, $dbuser, $dbpass, $db);
//Set variables according to user input on previous form
$Server_Name = $_POST['Server_Name'];
//Define the INSERT statement with IGNORE keyword
$stmt = "INSERT IGNORE INTO dcr_master (Server_Name, Description,..., ... , ... )";
if ($conn->query($stmt) === false) {
die("Database error:".$conn->error);
}
// Check for success
if ($conn->affected_rows == 0) {
print "<br>Error! <p></p>";
echo "" . $Server_Name . " already exists in the DCR";
print "<p></p>Please check the Server Name and try again";
} else {
//Success and return new id
echo "<br><p></p>Record Added!<p></p>";
echo "New id: " . $conn->insert_id;
}
This is an atomic operation so no race condition, and it involves only one call to the database.
I recommend you use either the OOP style or the procedural style for mysqli_*() but don't mix them. Usual warnings about SQL injection apply.
Use mysqli_num_rows
$row_cnt = $dupresult->num_rows;
if ($row_cnt > 0) {
echo "There is a matching record";
}else {
//insert into table
}
This statement:
if($dupresult = 1)
will always return 1. You should first retrieve the first query result (if any), like so:
$row=$dupresult->fetch_array(MYSQLI_NUM);
and then compare the result against NULL:
if(!$row)
Although the item is successfully added to the database, I'm not sure that I'm executing the mysql_real_escape_string() function correctly and, thus, getting the error. Any help is appreciated.
Success!
Warning: array_map() [function.array-map]: Argument #2 should be an array in /home/site4/public_html/lab/mailing_list_dev_1-0/mailing_list_add.php on line 32
Thanks for signing up!
Here's the code in question...
<?php
// connects the database access information this file
include("mailing_list_include.php");
// the following code relates to mailing list signups only
if (($_POST) && ($_POST["action"] == "sub")) {
if ($_POST["email"] == "") {
header("Location: mailing_list_add.php");
exit;
} else {
// connect to database
doDB();
// filtering out anything that isn't an email address
if ( filter_var(($_POST["email"]), FILTER_VALIDATE_EMAIL) == TRUE) {
echo 'Success!';
} else {
echo 'Invalid Email Address';
exit;
}
// check that the email is in the database
emailChecker($_POST["email"]);
// get number of results and do action
if (mysqli_num_rows($check_res) < 1) {
// free result
mysqli_free_result($check_res);
// cleans all input variables at once
$email = array_map("mysqli_real_escape_string", ($_POST["email"]));
// add record
$add_sql = "INSERT INTO subscribers (email)
VALUES('".$_POST["email"]."')";
$add_res = mysqli_query($mysqli, $add_sql)
or die(mysqli_error($mysqli));
$display_block = "<p>Thanks for signing up!</p>";
// close connection to mysql
mysqli_close($mysqli);
} else {
// print failure message
$display_block = "You're email address, ".$_POST["email"].", is already subscribed.";
}
}
}
?>
<html>
<?php echo "$display_block";?>
</html>
You're treating $_POST['email'] as an array, which it probably ins't.
If you only intended to escape email, do
$email = mysqli_real_escape_string($dbConn, $_POST['email']);
Then in your INSERT statement, use the escaped $email instead of $_POST['email']
$add_sql = "INSERT INTO subscribers (email) VALUES('$email')";
array_map() is meant for arrays. If all you have is a single value then just call the function directly.
There is at least one bug, here:
// Does not work because $_POST["email"] is a string, not an array
$email = array_map("mysqli_real_escape_string", ($_POST["email"]));
This looks like something you adapted from code that was working, but right now it's broken. You probably wanted something like this:
$post = array_map("mysqli_real_escape_string", $_POST["email"]);
after which you can use $post["email"] safely, as it has been escaped.
Of course escaping everything inside $_POST is possibly not the best way to go about this. There's still the mundane but spot-on way to consider:
$email = mysqli_real_escape_string($_POST['email']);
This is apparently not mysqli_real_escape_string problem but array_map() problem. Or rather misuse of the latter one.
However, you will face mysqli_real_escape_string() problem as soon as you solves this one.
To solve this latter your doDB() function have to return connection id, which you have to use with every mysqli_* function.
$conn = doDB();
$email = mysqli_real_escape_string($conn,$_POST["email"]);
thus you will have all your [listed] problems solved but I believe that emailChecker will may cause the same kind of problem of inexistent $check_res variable. Instea d of which such a function apparently have to return just a boolean and used like
if (!emailChecker($_POST["email"])) {