Processing, validating, and sanitizing data - php

Ok I have been stuck on this for some time now. I have a form. The form is in "index.php".
I send the form data to a php file called, "processuserform". I extract all the inputs and assigned them each to their own variable. I then took each variable and ran them through a function that I believe trims and strips the input from any unwanted characters. Within the same function I transformed any special characters into their HTML forms. Next I tried to validate the email. I used a PHP filter for this. I am uncertain on many things and have been searching for quite some time for an answer or at least a path to follow so I can learn how to properly sanitize and validate information. I am under the impression I will need to treat passwords different then everything else and will learn that after I learn how to validate and sanitize information. What you see below is what I have gathered from various sources on the net, which may end up being an incorrect way of designing a web page. I have achieved client side validation using Javascript but am fearful for my site because I do not have server side validation up. What happens if someone, who has javascript turned off, enters the wrong kind of information? How do they get sent back to the registration part and told they have made a mistake. I dont want people being led to a blank screen when they incorrectly enter information. I just want my site to be validated on the server side. I have literally been trying to learn this for 3 months. It is not that I am unintelligent but cannot find a set way to go about doing this. With so many ways I am confused ast to the path to take and what to do next. I will leave my code below and hopefully you guys will have compassion and patience for me. Thanks in advance.
==========================================================================
Form
==========================================================================
<form method="POST" name="signup" action="php/processuserform.php">
<input id="firstname" onkeyup="validateFirstName()" placeholder="First Name"
type="text" /><label id="firstnameprompt"></label>
<br><br>
<input id="lastname" onkeyup="validateLastName()" placeholder="Last Name"
type="text"/>
<label id="lastnameprompt"></label>
<br><br>
<input id="Email" onkeyup="validateEmail()" placeholder="Email" type="text" /><label
id="Emailprompt"></label>
<br /><br />
<input id="Password" onkeyup="validatePassword()" placeholder="Create Password"
type="password" /><label id="Passwordprompt"></label>
<br /><br />
<strong>Male</strong><input id="Gender" type="radio" name="sex" value="male">
<strong>Female</strong><input id="Gender" type="radio" name="sex" value="female">
<br /><br />
Click "Submit" if you agree to "Terms And Conditions"
<br>
<input id="submit" onclick="return validateUserRegistration()" value="Submit"
type="submit" name="submit"/><label id="submitprompt"></label>
<br /><br />
<hr>
</form>
====================================================================
//How I am Processing it.
====================================================================
<?php
//====================================
//Variables
$first_name= check_input($_POST['firstname']);
$last_name= check_input($_POST['lastname']);
$email= check_input($_POST['Email']);
$password= check_input($_POST['Password']);
$gender= check_input($_POST['Gender');
//====================================
//Trim and strip first name
function check_input($first_name)
{
$first_name = trim($first_name);
$first_name = stripslashes($first_name);
$first_name = htmlspecialchars($first_name);
return $first_name; };
//====================================
//Trim and strip last name
function check_input($last_name)
{
$last_name = trim($last_name);
$last_name = stripslashes($last_name);
$last_name = htmlspecialchars($last_name);
return $last_name; };
//====================================
//Trim and strip email
function check_input($email)
{
$email = trim($email);
$email = stripslashes($email);
$email = htmlspecialchars($email);
return $email; };
//=====================================
//Trim and Strip Password
function check_input($password)
{
$password = trim($password);
$password = stripslashes($password);
$password = htmlspecialchars($password);
return $password; };
//======================================
//Trim and strip Gender
function check_input($gender)
{
$gender = trim($gender);
$gender = stripslashes($gender);
$gender = htmlspecialchars($gender);
return $gender; };
//=========================================================
//Validate Email
$email
if(filter_var($email,FILTER_VALIDATE_EMAIL))
{
echo 'This should be a valid email';
}
else
{
echo 'You need some guidance':
}
//========================================================
$hostname="this is right";
$username="this is right";
$password="this is right";
$dbname="this is right";
$db_conx = mysqli_connect($hostname, $username, $password) OR DIE ("Unable to
connect to database! Please try again later.");
if(mysqli_connect_errno()){
echo mysqli_connect_error();
exit();
}
$select = mysqli_select_db($db_conx,$dbname);
mysqli_query($db_conx,"INSERT INTO users (firstname, lastname, email, password,
gender)
VALUES ('$first_name', '$last_name', '$email', '$password', '$gender')");
mysqli_close($db_conx);
header("Location: pages/profile.php")
?>

Well after you removed the unwanted characters from all of your user inputted variables, you now have to validate them as well!
From what I have learned in the past, one of the assumptions you should have as a developer is to NEVER trust that all users know the correct inputs for forms! Never trust the user! So with that in mind, we go and validate server side.
Validation in simplest terms is just making sure that the user inputs data that will work (I don't know the right way to put it) in a way to maintain the quality of your application.
Let's take one of your variables for example.
$email
Okay, you did a validation to check if it's an email, but there are better ways to validate it and you also need to check for other factors such as if the user inputs a blank space etc.
function validateEmail($email)
{
//Regex is a great way to validate email. This checks if it has one # sign and also the lengths of the email.
if (!preg_match("/^[^#]{1,64}#[^#]{1,255}$/", $email))
{
// Email invalid because wrong number of characters in one section, or wrong number of # symbols.
return false;
}
//check if the input was something other than a whitespace.
//Even if you put inside the textfield "required" in html, a whitespace will still be a //valid input so you better check to make sure that users aren't allowed to enter empty //fields!
if (!preg_match("/^[a-zA-Z ]*$/",$email))
{
return false;
}
return true;
}
This is just an example of how you can validate email using Regular Expressions.
You can even validate whether or not the domain is a real domain, or you can validate if the email contains any profane words and such. The key is to know what you don't WANT going into your system.
Make sure you also sanitize your queries in order to avoid any attacks.
Hope this sort of helps!
Cheers!

Related

How to check username and password matches the database values

I'm really sorry if the question looks silly. But I've been trying for days to check my username and password in the database matches what I'm typing in the html page... This is my Login form...
<form method="POST" action="Dashboard/Dashboard.php">
<div class="form-group md-form">
<!--<input type="email" class="form-control" id="email" value="" placeholder="Enter email address">-->
<i class="fa fa-user prefix grey-text"></i>
<input name="username" id="username" type="text" class="form-control" required>
<label for="defaultForm-email">Username</label>
</div>
<div class="form-group md-form">
<!--<input type="password" class="form-control" id="password" value="" placeholder="Enter password">-->
<i class="fa fa-lock prefix grey-text"></i>
<input name="password" id="password" type="password" class="form-control" required>
<label for="defaultForm-pass">Your password</label>
</div>
<div class="text-center">
<button type="reset" class="btn btn-amber btn-sm"><strong>Reset</strong></button>
<input type="submit" name="submit" id="submit" class="btn btn-green btn-sm" value="Sign in">
</div>
</form>
And this is the code(php) I'm using in Dashboard.php
<?php
$servername = "localhost";
$username = "root";
$password = "";
$databaseName = "test";
$conn = mysqli_connect($servername, $username, $password, $databaseName);
$un = $_POST['username'];
$pw = $_POST['password'];
print $pass . "_" . $email;
$query = mysqli_query($conn, "SELECT log_username,log_password FROM login WHERE log_username='$un' AND log_password='$pw'");
$result_can = mysqli_query($conn, $query);
while ($row = mysql_fetch_assoc($result_can)) {
$check_username = $row['username'];
$check_password = $row['password'];
}
if ($un == $check_username && $pw == $check_password) {
$message = "ok";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
} else {
$message = "No";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
}
?>
I really tried like thousands of times, but couldn't figure out where I went wrong... Can anyone please help me?
I know my code is open to SQL injection, but I don't care about it as this is a example I needed to show to my friends So neglect that part.
Stack Overflow is for "professional and enthusiast programmers." With respect, you've shown us code in your question that isn't even close to being worthy of either name. It's grossly insecure, and if you put it on the public internet, your site will be cracked by cybercriminals.
StackOverflow people don't have much of a sense of humor about bad security code. You get strong reactions to code like yours because, well, Equifax, and Ashley Madison, and Adobe, and all the rest of the places that have been cracked by cybercriminals. Why do we jump on you? Because we don't like cybercriminals and we don't want to make life easy for them. Friends don't let friends do bad password security. Friends don't show friends grossly insecure password-validation code.
What's wrong with your code? You're storing passwords as plain text, and you're vulnerable to SQL injection. I will address the first of these issues.
Fortunately, php has outstanding industry-leading facilities to do password security. Read about them here. http://php.net/manual/en/faq.passwords.php Use them. How do you handle passwords?
When a user registers on your site and first presents a password, you hash it, in your code running on your server, something like this.
$usersPassword = $_POST['password']);
$hash = password_hash( $usersPassword , PASSWORD_DEFAULT );
// you then store the username and the hash in your dbms.
// the column holding the hash should be VARCHAR(255) for future-proofing
// NEVER! store the plain text (unhashed) password in your database
When a user tries to log in, you do a query like this on your server:
SELECT log_password FROM log_user WHERE log_username = TheUsernameGiven
You then put the retrieved password into a variable named $hash.
You then use php's password_verify() function, again on your server, to check whether the password your would-be user just gave you matches the password in your database.
Finally, on your server you check whether the user's password needs to be rehashed, because the method you used previously to hash it has become obsolete.
$usersPassword = $_POST['password']);
$valid = password_verify ( $usersPassword, $hash );
if ( $valid ) {
if ( password_needs_rehash ( $hash, PASSWORD_DEFAULT ) ) {
$newHash = password_hash( $usersPassword, PASSWORD_DEFAULT );
/* UPDATE the user's row in `log_user` to store $newHash */
}
/* log the user in, have fun! */
}
else {
/* tell the would-be user the username/password combo is invalid */
}
This sequence is futureproof, because it can rehash passwords later if the old hashing method gets too easy for cybercreeps to crack. Many user accounts have lifetimes far longer than versions of packages like php.
For credentials like passwords to remain secret, you must use https, not http, to connect between browser and server. Otherwise cybercriminals can intercept the traffic from your user to your server and grab her password. It can be a pain in the xxx neck to rig up an https-enabled server, but it's a critical part of deploying a web application. (Services like Heroku allow you to test your apps with https easily.)
Several problems, some were mentioned by comments above.
Mixing mysql_* vs. mysqli_* API
You call the query with mysqli_query() but you try to fetch results with mysql_fetch_assoc(). You can't mix these different APIs. The mysql_* functions will not use the connection you opened with mysqli_connect(), and vice-versa. Pick one MySQL extension and stick with it.
Hint: Don't use mysql_* at all. It's deprecated, and has been removed from PHP 7.0+
Querying with conditions for both username and password
Just search for the username, and fetch the password. If you search for both, then the search will return zero rows, unless the correct password was used.
You don't want that. You want to avoid putting the plaintext password in the SQL query. Just search on the username, and fetch the stored password and then compare what you fetch to the user input password.
Uninitialized variables
If you fetch zero rows from your query, then $check_username and $check_password are never set. Then you compare those variables in your if statement. Not a fatal error, but bad style.
No password hashing
You appear to be comparing the user input, which I assume is plaintext, directly to what's stored in the database. You're Probably Storing Passwords Incorrectly.
Instead, when you store your password, use password_hash() first.
No query parameters
I know you said you don't care about your SQL injection vulnerability, but this is like being an electrician and saying you don't care that your electrical panel is stuffed with oily rags. Be sure to post your disregard for safety on your LinkedIn profile, so employers know who to avoid.
Recommended implementation
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // enable exceptions
$conn = new mysqli($servername, $mysql_username, $mysql_password, $databaseName);
$log_username = $_POST['username'];
$log_password = $_POST['password'];
$sql = "SELECT log_username, log_password_hash FROM login WHERE log_username=?";
$stmt = $conn->prepare($sql);
$stmt->bind_param('s', $log_username);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
if (password_verify($log_password, $row['log_password_hash'])) {
$message = "ok";
// header must be called before any other output
header("Location: Doctors.php");
exit();
}
}
$message = "No";
// header must be called before any other output
header("Location: Doctors.php");
There are several problems here, both in your code and in the thought process. Let's work our way down:
$un = $_POST['username'];
$pw = $_POST['password'];
print $pass . "_" . $email;
That print line should be giving you a warning. The variables $pass and $email do not exist. You should remove that line, unless what you were trying to do is to print $un and $pw instead.
$query = mysqli_query($conn, "SELECT log_username,log_password FROM login WHERE log_username='$un' AND log_password='$pw'");
There's no need to select both the username and password column. If there is a match, they will always be the same as $un and $pw, which you already have. You're only checking whether the username and password are correct or not, so selecting a single column is good enough. Preferably the user id, but only the username will be sufficient.
Keep in mind that -- assuming the query executes successfully -- $query will contain a mysqli_result object.
$result_can = mysqli_query($conn, $query);
This line needs to be removed. You have already executed your query and $query is its result, what you're doing here makes no sense and should be giving you a warning, or perhaps even a fatal error.
while ($row = mysql_fetch_assoc($result_can)) {
$check_username = $row['username'];
$check_password = $row['password'];
}
if ($un == $check_username && $pw == $check_password) {
$message = "ok";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
} else {
$message = "No";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
}
You cannot mix mysql_* and mysqli_* functions. Using mysql_fetch_assoc() here should give you a fatal error. You should use mysqli_fetch_assoc() instead (on $query instead of $result_can), however:
Since you're only interested in whether or not there was any result at all, this whole section can be changed to:
if (mysqli_num_rows($query) > 0) {
$message = "ok";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
} else {
$message = "No";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
}
This will pose other problems, because you cannot use header() to redirect the user after echo'ing your <script> tag (you will get a "headers already sent" error). If you want the Javascript alert, perform the redirect with Javascript as well. Also, that $message variable is rather useless, you might as well put the message directly into the alert:
if (mysqli_num_rows($query) > 0) {
echo "<script type='text/javascript'>alert('ok'); window.location.href='Doctors.php';</script>";
} else {
echo "<script type='text/javascript'>alert('No'); window.location.href='Doctors.php';</script>";
}
Once you fix all of these issues, you still have some thinking to do.
You should never store passwords in plain text in your database.
You may not care about SQL injection right now, but with your current query I can log in as any valid user (e.g. "admin") by typing their username as admin' AND 1 --, or if I just want access I can use a username of any' OR 1 -- and be logged in as the first user in your table. Look into prepared statements and how they work.
You have no error handling at all. You should add checks to see if the database connection was opened successfully, the query executed properly, the form was posted and the username/password fields were filled in and think about how you want to present a useful error message to the user.
The main lesson here should be: when you're developing and it doesn't work, always check the error logs to see if it contains any hints and turn on PHP's error reporting features so you can see what you did wrong right in your browser.

PHP: Automatically send a group email once I post something to my website

I have a function where lets say an 'admin' can post content to my website for regular users to see. Once this is done I would like to be able to send an email to anyone who is registered on my site (I have these stored in a field in my 'users' database). I am using XAMMP and MySQL but will be registering on a live host soon.
I have heard that using PHPMailer will be the best for this however my site will have a maximum of 120 users at a time therefore if I could loop through my records in my database, and call an email function each times and send to that address that would be great. I am new to PHP and have built this website using tutorials online for the most part however this really has me stumped!
I have a contact form where users can contact me however I do not know how to go about my problem above.
<?php
$to = 'davidforde1991#gmail.com';
$subject = 'PLACEMENT_PARTNER_CONTACT';
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$message = <<<EMAIL
HI! My name is $name.
$message
From $name
Oh ya, my email is $email
EMAIL;
$header = '$email';
if($_POST){
mail($to, $subject, $message, $header);
$feedback = 'Thanks for contacting PSquared! We will be in contact soon!';
}
?>
<form action="?" method="post">
<ul>
<li>
<label for="name">Name:</label>
<input type="text" name="name" id="name" />
</li>
<li>
<label for="email">Email:</label>
<input type="text" name="email" id="email" />
</li>
<li>
<label for="topic">Topic:</label>
<select id = "topic">
<option value="Ponies">Ponies</option>
<option value="Mexicans">Mexicans</option>
<option value="Weiner">Weiner</option>
</select>
</li>
<li>
<label for="message">Message:</label>
<textarea id="message" name="message" cols="42" rows="9"></textarea>
</li>
<li><input type="submit" value="Submit"></li>
</ul>
</form>
I know the above code isn't relevant, but I have code in place to loop through fields in my db already if that is of help.
<?php
// Connects to the Database
mysql_connect("localhost", "root", "") or die(mysql_error());
mysql_select_db("users_db") or die(mysql_error());
//checks cookies to make sure they are logged in
if(isset($_COOKIE['username']))
{
$username = $_COOKIE['username'];
$pass = $_COOKIE['pass'];
$check = mysql_query("SELECT * FROM users WHERE user_name = '$username'")or die(mysql_error());
while($info = mysql_fetch_array( $check ))
{
$username = $row['user_name'];
$email = $row['user_email'];
}
//if the cookie has the wrong password, they are taken to the login page
?>
new to php, welcome i guess!
to answer your question,
its something like this
function tell_eveyone_i_just_updated_my_website($additional_info){
if(empty($additional_info)/* && $additional_info!=='0'*/){$additional_info='';}
if(!is_string($additional_info)){
throw new InvalidArgumentException('if $additional_info is not empty, it must be a string!');
}
$pdoh=new PDO('mysql:host=localhost;dbname=users_db;charset=utf8;','root','',array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION));
$pdostatementh=$pdoh->prepare("SELECT `user_name`,`user_email` FROM `users` WHERE 1");
$pdostatementh->execute();
$row=NULL;
while(false!==($row=$pdostatementh->fetch(PDO::FETCH_ASSOC))){
//$username= $row['user_name'];//
$email = $row['user_email'];
mail($email, "i just updated my website!","i just updated my website! ".$additional_info);
}
};
tell_everyone_i_just_updated_my_website("added a new article about cats");
and now to nitpick,
here:
$check = mysql_query("SELECT * FROM users WHERE user_name = '$username'")or die(mysql_error());
you are vunrable to SQL Injection attack... if som1 put their username to something like
this: hacker'; DROP DATABASE users; --
they will delete your database! (solution: mysql_query("SELECT * FROM users WHERE user_name = '".mysql_real_escape_string($username)."'") )
isset($_COOKIE['username'])
DO NOT USE THIS TO CHECK IF SOM1 IS LOGGED IN, A HACKER CAN FAKE THIS. (solution: use $_SESSION )
if($_POST){
should be
if($_SERVER['REQUEST_METHOD'] == 'POST')
(reason is, if a POST request contains no actual POST data, even though it is technically a POST request, $_POST will still evaluate to false..)
next, you may want to verify that name/email/message is actually given in the POST request, or it can cause unhandled errors in your php code.. (but honestly, who reads the server error log anyway, right?...) something like
if(!isset($_POST['name'])){echo "malformed POST request! name missing!";/*~~*/}
next, DO NOT USE mysql_ API, it will removed from PHP soon, and your code will stop working in a future PHP update. instead use PDO or MySQLi

Login: email-password match w/ PHP and MySQL

** UPDATE **
Wonderful help, and solved this by simply omitting the $-sign in
$dbusername = $row['$username_login'];
$dbpassword = $row['$password_login'];
to their column names.
$dbusername = $row['username'];
$dbpassword = $row['password'];
I am currently playing around with PHP and MySQL, following some tutorials on making a simple, social network. I have run into trouble when trying to check if a password matches the username.
Code for the login form:
<form action="login.php" method="POST">
<input type="text" size="25" name="user_login" id="user_login" placeholder="Username" />
<input type="password" size="25" name="password_login" id="password_login" placeholder="Password" /> <br />
<input type="submit" name="login" id="button" value="Login" />
</form>
Snippet of my PHP code for verifying the data (login.php):
$username_login = strip_tags($_POST["user_login"]);
$password_login = strip_tags($_POST["password_login"]);
if ($login) {
if ($username_login && $password_login) {
$connect = mysql_connect("localhost", "root", "") or die("Error connecting");
mysql_select_db("mono_social") or die("Could not find db");
$query2 = mysql_query("SELECT * FROM users WHERE username='$username_login'");
$numrow = mysql_num_rows($query2);
if ($numrow != 0) {
// LOGIN code
while ($row = mysql_fetch_assoc($query2)) {
$dbusername = $row['$username_login'];
$dbpassword = $row['$password_login'];
}
// Check to see if username and password match
if ($username_login==$dbusername && $password_login==$dbpassword) {
echo "You are in";
}
else {
echo "Sorry $username_login. Incorrect password!";
}
}
I have also included code for checking whether any of the fields have been left blank, or if the username does not exist. The code seems to be working well for the aforementioned tests (blank fields and invalid usernames), but NOT when I attempt to login with both a valid username and password.
Any help on this would be highly appreciated :)
Probably your columns are not called '$username_login' and '$password_login'.
$dbusername = $row['$username_login'];
$dbpassword = $row['$password_login'];
Maybe you just have to omit the $ (in case your columns' names are 'username_login' and 'password_login')
The answer above resolves your problem; but also, take note of the following when using PHP to avoid future headaches:
Do NOT put a single quote around your database, table, and column names. You can use their literal names or variables containing the literal names. 'username'='$username' is wrong; username='$username' is right.
If your database, table, or column name contain spaces, wrap a tick mark ` (the character is located on the left part of a US-region keyboard, infront of the key for !) around the name. user column is wrong; `user column` is right.
Wrap your string values with single quotes '; e.g. username='$username'.
Values for columns whose datatypes are numbers do not need single quotes around them; e.g. userid=2
Security Concerns
Since you are just starting with the language, it's best to start right.
Do not use mysql_* functions anymore; it is not safe and it has been deprecated. Instead, use PDO. It's easier and safer to use.
Never use root as your database user, even during development.
On production or development systems, all database users MUST have/use passwords. Prevent authorized access.
Lastly, if an answer has helped you, accept it. It allows others to help you in the future.
Hope this helps.

PHP/AJAX Login taking very long

I've inherited a website that requires users to login too.
The login uses Ajax and PHP only this login procedure can take up to a minute to complete when there is only 4000 users registered.
Could this be due to the way the login is coded?
AJAX
<form name="login-form" onsubmit="return false">
<input type="text" id="the_username" value="Username" onfocus="emptyUsername(this);" onblur="clickrecall(this,'Username')" class="focusfield input push" />
<input type="password" id="the_password" value="Password" class="input" onfocus="emptyPassword(this);" onblur="clickrecall(this,'Password')" />
<span id="dialog-login-fail" title="Login failed"></span>
<input type="submit" onclick="javascript:void(0);" id="loginBtnBre" class="sign-in signin-submit-btn" value="Login Now" />
</form>
PHP
<?php
require 'config.inc.php';
foreach($_POST as $k=>$v)
{
$_POST[$k] = trim($v);
}
if(!isset($_POST['theusername']) or !isset($_POST['thepassword']))
{
print "Please use all fields";
}elseif(empty($_POST['theusername'])){
print "Please enter a username";
}elseif(empty($_POST['thepassword'])){
print "Please enter a password";
}elseif($_POST['theusername'] == "username" && $_POST['thepassword'] == "password")
{
print "Password & User cannot be the ones already listed";
}elseif(!preg_match("/^[a-z0-9]+$/i", $_POST['theusername']))
{
print "Please use only characters and numbers for username, no spaces, dashes or others!";
}else{
$password = md5($_POST['thepassword']);
$user = $_POST['theusername'];
$loginVar = $usersClass->login($user, $password);
if(is_array($loginVar))
{
$_SESSION['loggedIn'] = $loginVar;
#session_regenerate_id(true);
print "success";
}else{
print "Whoops, something went wrong! Try again.";
}
}
?>
Query
public function login($username, $password)
{
$rs = mysql_query("SELECT `id`,`active` from `$this->usersTable` WHERE
`username` = '".mysql_real_escape_string($username)."' AND
`password` = '".mysql_real_escape_string($password)."'");
if($rs) {
$row = #mysql_fetch_object($rs);
return $this->userInfo($row->id);
}else{
return false;
}
First change the browser to make sure that it's not a problem with the browser (rare, yet still happens sometimes).
Then try a PHP profiler to identify the "slow" backend code. There is even a nice tutorial at http://erichogue.ca/2011/03/linux/profiling-a-php-application/
You can use the firebug feature of the firefox to know if the correct information is being posted or not? I can see that there is no problem except a "login" function.
You can echo the query and copy it from firebug and run it to the database.
Track the time it takes to run that query and add some second on it. See if your database query takes lots of time or not.
If your query takes more time then you need to optimize your SQL query
You probably dont have an index on the username or password fields
Run:
alter table `TableName` add index `username` (`username`(500));
alter table `TableName` add index `password` (`password`(500));
From a mysql prompt, where TableName is the name of your table, then try again. If that speeds things up, adjust the indexes to be a more suitable length.
And you really shouldn't be storing passwords as clear text in the database. As bare minimum store them as hashed strings (MD5 etc) or better yet, store them as salted MD5 hashes.
I would change your select to just select based on the username (drop the password) then perform additional checks to make sure the password entered matches that of the returned row.

PHP, question about searching and updating a record

I have a question, I am new to PHP and I have been working on some exercises. The one I am currently working on is to create a simple form that will search a database (first name, last name). The returned results should then be populated into another form. This way, if I want to update the record, all I have to do is change the value of the populated form and hit Update. I have create the database no problem.
The following is the code. (Please don't laugh, I'm very new...I am sure there are much more efficient ways of doing this, but I'm just playing around right now)
Here is the form:
<form action="" method="post">
<strong>Search for name</strong><br>
<label for="fname">First Name</label>
<input type="text" name="fname">
<label for="lname">Last Name</label>
<input type="text" name="lname">
<input type="submit" name="submit" value="Search">
</form>
And here is the PHP:
if( isset( $_POST['submit'] ) ){
$first_name = $_POST['fname'];
$last_name = $_POST['lname'];
if ( $first_name == NULL || $last_name == NULL ) {
echo "please enter search record";
}
else {
$query = "SELECT first_name, last_name FROM formdata WHERE first_name LIKE '%$first_name%' OR last_name LIKE '%$last_name%'";
$result = mysqli_query( $conn, $query );
$result_array = mysqli_fetch_row( $result );
$fname_value = $result_array[0];
$lname_value = $result_array[1];
echo "
<form action='' method='post'>\n
<label for='fname_u'>First Name</label>\n
<input type='text' name='fname_u' value='$fname_value'>\n
<label for='lname_u'>Last Name</label>\n
<input type='text' name='lname_u' value='$lname_value'>\n
<input type='submit' name='update' value='Update'>\n
</form>";
}
}
if( isset( $_POST['update'] ) ) {
$first_name_u = ( $_POST['fname_u'] );
$last_name_u = ( $_POST['lname_u'] );
$query_update = "UPDATE formdata SET first_name = '$first_name_u', last_name = '$last_name_u' WHERE first_name = '$fname_value';";
echo $query_update; // this is just for testing
}
This code seems to work and do what I want, all the way up to when I submit the updated information. I can't figure out how to carry over the value of the $fname_value variable to the if( isset( $_POST['update'] ) ) conditional. I am thinking I can't because they are two different POSTS? I really don't know...I just need to find a way to get value of the retrieved form data and use for the WHERE clause.
Again, I'm very new and just getting my feet wet with this kind of stuff ... Any help would be great
Thanks
I think you have a typo in your code. Your POST data is saved to the variable $first_name, but when you query SQL you are using $first_name_r instead of $first_name.
I'm thinking the typo is the answer, but I have to point out one deadly mistake you've made, and that is that you're piping user-supplied input directly into an SQL query. This opens your code to a slew of malicious attacks called SQL injection attacks. I'm not trying to be preachy, but it's very important that you read and understand that article, especially the part about Mitigation at the bottom.
I would suggest you use something like this instead:
$query = 'SELECT first_name, last_name '.
'FROM formdata WHERE first_name LIKE ? OR last_name LIKE ?;';
$sth = mysqli_prepare($dbh, $query);
mysqli_stmt_bind_param($sth, "s", '%'.$first_name.'%');
mysqli_stmt_bind_param($sth, "s", '%'.$last_name.'%');
$result = mysqli_execute($sth);
I know it's a bit longer and more complicated, but trust me, it will save you a world of headache. The sooner you learn about this and get it deeply ingrained in your psyche that you can never, ever, ever write a query that passes unsanitized input straight to the database, the happier we all will be (and the longer you will get to keep your job eventually. ;).
Sorry if I'm coming on strong, but in my opinion, the single most important lesson you need to pick up early in developing database-driven web sites is that you really need to be proficient at spotting injection vulnerabilities to the point where it's automatic and when you see it, you think, "Ooh! Noooo! Don't do that!!!"
Above answer found your isssue, but on a sidenote:
$first_name = $_POST['fname'];
$last_name = $_POST['lname'];
Do not do this. That my friend is the most common security vulnerability for php applications.
The most 2 most important things to remember when scripting is
Filter input, and
2: Escape output.
See this write-up for more details ..
In your case, the input values are not filtered, or checked for malicious/improper values.
Here is another primer on this page to see a few tips and how to address filtering.
Keep it up, those exercises are a fine way of picking up chops.
Happy coding friend.
Okay, re-reading your post, I think I see what you're trying to do and where you're having difficulty. Normally, you won't have two separate pages for one identical form like this. Typically, you'll code it more along these lines, and please keep in mind that I'm winging this off the top of my head, not actually testing it, so minor corrections and/or tweakage may be required:
<?php
$fname_value = '';
$lname_value = '';
if (isset($_POST['submit']) && $_POST['submit'] === 'Search') {
if (isset($_POST['fname']) && isset($_POST['lname'])) {
// We are processing a submitted form, not displaying a brand new one
// from scratch. Code any post-validation steps.
// Fetch the user information from the database. You'll need to define
// the $host, $user, $password, and $dbname variables above, or
// substitute literal strings with real information in here.
$dbh = new mysqli($host, $user, $password, $dbname);
$sql = 'SELECT first_name, last_name'.
'FROM formdata WHERE first_name LIKE ? OR last_name LIKE ?;';
$sth = $dbh->prepare($sql); // Use parameters to avoid injection!
$sth->bind_param('s', $_POST['fname']);
$sth->bind_param('s', $_POST['lname']);
if ($sth->execute()) {
$result = $sth->get_result();
if (($row = $result->fetch_assoc()) != NULL) {
// Set the default values displayed in the text edit fields.
$fname_value = $row['first_name'];
$lname_value = $row['last_name'];
}
}
// Whatever other processing you want to do if this is a submitted
// form instead of displaying the page from scratch.
}
}
?>
<html>
<body>
<form action="<?= $_SERVER['PHP_SELF'] ?>" method="POST">
<strong>Search for name</strong><br />
<label for="fname">First Name</label>
<input type="text" name="fname" value="<?= htmlentities($fname_value) ?>">
<label for="lname">Last Name</label>
<input type="text" name="lname" value="<?= htmlentities($lname_value) ?>">
<input type="submit" name="submit" value="Search">
</form>
</body>
</html>

Categories