How to fix the bug with connection to database - php

I have an html form and a connection to database, and when I hit submit button the information goes to my db. But if I refresh my page after, without pushing any button, the information goes again and again and again. Please help me to fix this.
I also would appreciate help of php form CRUD, from UI. Can you help me with code, let's say there are buttons, which show my database tables, where I can make changes from UI.
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<meta charset="utf-8">
<title></title>
</head>
<body>
<form action="form.php" method="post">
<table>
<tr>
<td>Name:</td>
<td>
<input type="text" name="name" placeholder="name" required> <br>
</td>
</tr>
<tr>
<td>
Surname:
</td>
<td>
<input type="text" name="surname" placeholder="surname" required>
</td>
</tr>
</table>
<input type="submit" name="submit">
</form>
</form>
</body>
</html>
form.php
<?php
//Create connection
$servername='localhost';
$username = 'root';
$password = '';
$dbname='testdb';
//create connection
$conn = new mysqli($servername,$username,$password,$dbname);
if($conn->connect_error){
echo $conn->connect_error;
}else {
echo "connected successfully<br/>";
}
//post method
if(isset($_POST['submit'])){
$name = $_POST['name'];
$surname = $_POST['surname'];
}
#insert data
$result = "INSERT INTO users(name,surname) VALUES('$name','$surname')";
$show = "SELECT * FROM users";
if($conn->query($result)){
echo "data inserted successfully";
}else {
$conn->connect_error;
}
$conn->close();
?>

There are several solutions for your issue.
The PHP approach: Redirect after the successful storage in your database. You can use the PHP header function for redirecting to another page with a success message.
The JavaScript approach: This approach is a little more cumbersome as it requires the data to be submitted using an ansychronous request with JavaScript. After the successful response of your script, you can then hide the form with JavaScript and display a success message for the user.
Help for your CRUD system
Since you have not come up with your own approach, you can not expect that you will get the exact help you need here. There are tons of examples, how you can achieve a CRUD system.
Here 's the basic approach of CRUD.
class Person
{
public function create($name, $surname) : int
{
// insert data into database and return the auto_increament value
return $id;
}
public function read(int $id) : array
{
// read out the data by the given id and return the data
return $data;
}
public function update($id, $data) : bool
{
// update the database entry with the given id and the given data and return the response of the update statement (true or false)
return $result;
}
public function delete($id) : bool
{
// delete the database entry with the given id and return the response
return $result;
}
}
This is how you should beginn. Then you have to deal with the data you need in your view. For reading out a specific person you need an id. For updating a specific person, you need an id. Same for deleting a specific person. Think about how to get the id. You can solve this with an hidden input element in your form or a GET parameter in the URL of the form.

Related

Taking mySQL database input from HTML form with PHP

I'm trying to take in data from a webpage with a HTML form and PHP to my mySQL Database. It connects just fine on both pages but I get an error when I try to submit from the form. It will take in data if I just write it into the PHP myself and click submit, but it won't take it from the form so there must be something wrong there but I can't figure out what. I've never used PHP with mySQL before so I'm not too sure how it all works. Any help with an explanation of how it's working would be appreciated.
Below is my test.html.php page where my form is and the testinsert.php page where I try to insert the data.
(Also, courseID is a foreign key in the 'test' table, so i need to make the courseID selectable from the options, i struggled with this and I don't know if this is where the issue lies. In the current code it is in a drop down menu, it shows the courseID's but there is a blank option in between each option e.g. the list of options will be - '4', 'blank', '5'... etc)
<!DOCTYPE html>
<?php
include 'connect.php';
?>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="style.css" />
<meta name="viewport" content="width=1024, initial-scale=1.0, maximum-scale=1.0,user- scalable=no"/>
</head>
<title>Test Sign Up</title>
<body>
<header>
<h1>Test Sign Up</h1>
</header>
<div class="contactform">
<form action="testinsert.php" method ="post">
<label for="name">Name:</label>
<input type="text" id="name" name="name" placeholder="Enter
your name here" required>
<label for="testsentence">Test Sentence:</label>
<input type="text" id="testsentence" name="testsentence" placeholder="Enter your sentence here" required>
<label for="course">Course:</label>
<select id="course" name="course">
<?php
$query = "SELECT CourseID FROM Course";
$result = mysqli_query($conn, $query);
while($row = mysqli_fetch_array($result)){
echo "<option>" . $row['CourseID'] . "<option>";
}
mysqli_close($conn);
?>
</select>
<button type="submit" name="submit">Submit</button>
</form>
</div>
<p></p>
View Courses
<p></p>
Return to home page
</body>
</html>
Testinsert.php -
<?php
include 'connect.php';
$name = 'name';
$testsentence = 'testsentence';
$courseid = 'course';
$sql="INSERT INTO Test (Name, TestSentence, Course)
VALUES ('$name','$testsentence', '$courseid')";
if (mysqli_query($conn, $sql)) {
echo "<p></p>New record added successfully";
echo '<p></p>Return to home page';
} else {
echo "<p></p>Error adding record";
echo '<p></p>Return to home page';
}
mysql_close($conn);
?>
You are getting blank options AFTER each option with an expected value because you have failed to write a closing option tag. / needs to be written into the second option tag like this:
while ($row = mysqli_fetch_array($result)) {
echo "<option>{$row['CourseID']}</option>";
}
The option tags still render even if you don't properly close them. In this case, the error presents itself by generating twice the desired tags.
I recommend that you use MYSQLI_ASSOC as the second parameter of your mysqli_fetch_array call or more conveniently: mysqli_fetch_assoc
In fact, because $result is iterable, you can write:
foreach ($result as $row) {
echo "<option>{$row['CourseID']}</option>";
}
About using extract($_POST)...
I have never once found a good reason to use extract in one of my scripts. Not once. Furthermore, the php manual has a specific Warning stating:
Warning
Do not use extract() on untrusted data, like user input (e.g. $_GET, $_FILES).
There are more warning down the page, but you effectly baked insecurity into your code by calling extract on user supplied data. DON'T EVER DO THIS, THERE IS NO GOOD REASON TO DO IT.
Here is a decent page that speaks about accessing submitted data: PHP Pass variable to next page
Specifically, this is how you access the expected superglobal data:
$name = $_POST['name'];
$testsentence = $_POST['testsentence'];
$courseid = $_POST['course'];
You must never write unfiltered, unsanitized user supplied data directly into your mysql query, it leads to query instability at best and insecurity at worst.
You must use a prepared statement with placeholders and bound variables on your INSERT query. There are thousands of examples of how to do this process on Stackoverflow, please research until it makes sense -- don't tell yourself that you'll do it layer.
Make sure you added extract($_POST) (or something similar) in your PHP code!
You need to extract the parameters from your POST request before using them, otherwise your $name, $testsentence, and $courseid will be undefined.

echo an error without redirecting to another page and keep all form data?

If for example a username isn't filled in the user is given an error stating so, but after pressing submit they're thrown to another page with the error.
How would I go around keeping the error on the same page as the registration form and keeping all the text entered by the user after submit?
Registration PHP:
<?php
require 'db_connect.php';
$count = 0;
if (isset($_POST['username']))
{
$username = $_POST['username'];
if (!empty($username))
{
$count++;
}
else
{
echo 'Please enter a username';
echo "<br>";
}
}
if (isset($_POST['email']))
{
$email = $_POST['email'];
if (!empty($email))
{
$count++;
}
else
{
echo 'Please enter an email';
echo "<br>";
}
}
if (isset($_POST['password']))
{
$password = $_POST['password'];
if (!empty($password))
{
$count++;
}
else
{
echo 'Please enter a password';
echo "<br>";
}
}
if(strlen($username) > 25)
header('Location: registration.php');
$hashword = password_hash($password,PASSWORD_DEFAULT);
if($count == 3 )
{
$query = "INSERT INTO member ( username, password, email)
VALUES ( '$username', '$hashword', '$email');";
header('Location: login.html');
}
else {
echo '<b>You will be redirected shortly</b>';
echo "<br>";
echo '<b>Please enter ALL details correctly</b>';
header( "refresh:5;url=registration.php" );
}
$result = mysqli_query($connection, $query) or die(mysqli_error($connection));
?>
Registration Form:
<!doctype html>
<html lang="en">
<head>
<title>Gumby template file</title>
<meta charset="utf-8" />
<script data-touch="gumby/js/libs" src="gumby/js/libs/gumby.min.js"></script>
<script src="gumby/js/libs/jquery-2.0.2.min.js"></script>
<link rel="stylesheet" href="gumby/css/gumby.css">
<script src="gumby/js/libs/modernizr-2.6.2.min.js"></script>
<link rel="stylesheet" href="forumhomepage_style.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
</head>
<body>
<form name="register" action="register.php" method="post">
<tr>
<td>Username: </td>
<td><input type="text" name="username" maxlength="25" /></td>
</tr>
<tr>
<td>Email: </td>
<td><input type="text" name="email" id="email" /></td>
</tr>
<tr>
<td>Password: </td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" value="Register" /></td>
</tr>
</table>
</form>
</body>
</html>
It depends on at what level do you want to do this.
Validating that the different data is not empty and has information that makes sense (like the password is at least 7 chars long) can be done via javascript before sending the form data, this way you can stop the form to be sent. You can use jQuery Plugin Validator to help you do this.
But other validations like the insert has failed only can be done at server side, if you need also not to redirect in this case then you have to use ajax to load the data and then refresh the website info without reloading it.
I prefer to only do an initial check with javascript and send the user to the results page. But I also keep the validations as this one of the password length in the php because, even though now a days it's really strange, a user can disable javascript and I don't wana have surprises when checking the database values. But, another example, if you have lots of users you could check that the user does not exist to warn the user at the very first moment before the form is sent and this can only be done performing an ajax call.
You should know how to do both things and decide depending on what you want to do on your projects.
In your case, I would leave the php validations as they are now and check the same (non empty values) in javascript on the form submit event calling event.preventDefault() if an error has been detected.
$('form[name="register"]').submit(function( event ) {
if ($('input[name="username"]').is(":empty")) {
// append a "Username can not be empty message somewhere on your page
event.preventDefault();
}
// I let you finish the jquery code...
});
This example uses jQuery lib. but you can do it without it with just javascript if you want.
There are several ways to do this. The first step is using the required attribute in your input elements:
<input type="text" name="username" required>
This will force the user to at least put something inside the input element. Then there's Javascript or jQuery for client side validation. You can create a custom event handler to catch the form submit and validate the input like so:
document.getElementById("your_form_id_here").addEventListener("submit", function(e){
// Your Javascript validation code here, for example:
var x = document.forms["your_form_id_here"]["username"].value;
if (x == "") {
alert("Username must be filled out");
e.preventDefault();
}
});
You can also put the form handler on the same file as the form and display the errors / values in case something goes wrong. For example:
<?php
if(!empty($_POST['submit'])){
$error = false;
if($_POST['username'] === ''){
$usernameEmpty = 'The username was empty. Please enter a username!';
$error = true;
}
if(!$error){
// No errors found so proceed with the registration
}
}
?>
<form id="myForm" method="post" action="" accept-charset="utf-8">
<?php if(!empty($usernameEmpty)){ echo $usernameEmpty . '<br/>'; } ?>
Username: <input type="text" name="username" value="<?php if(!empty($_POST['username'])){ echo $_POST['username']; } ?>"/>
<input type="submit" name="submit" value="Register"/>
</form>
Lastly there's of course Ajax which will allow you to send the form towards PHP without reloading your page. You could have PHP send the errors back and use Javascript to show the errors inside the DOM.
without ajax you will need ro lead your page with some conditional logic. This will look and see if any fields are filled in and fill them in again, along with setting any error messages to return to the user.
something like:
<?php
//example fields
$username = '';
$field2 = '';
$field3 = '';
if(isset($errorToShow)){
// echo your error message here
}
if($_POST["submit"]){
foreach($_POST as $k=>$v){
$$k = $v;
}
}
// your form can be here.
of course there are other considerations and ajax is a better solution, but this type of thing can work just fine.
You may use ajax
Or if you don't know ajax
You can put all your code in one page and call $_POST indexes into the value of every input.
for ex.
<input type="text" name="username" maxlength="25" value="<?=$_POST['usename'];?>"/>
Or you may use "PHP $_SESSION"
Just store $_POST into $_SESSION
then call it from the html page
for ex.
<input type="text" name="username" maxlength="25" value="<?=$_SESSION['usename'];?>"/>
And the same idea for errors.

Hash a password in PHP before it goes to database, getting error

I had been researching a while and even got a hold of my hosting company for help but I have run into a problem with my PHP code and my database through my website. While the code that I have does hash the password that I enter, when I attempt to use the regular word password it comes up as incorrect. But if I copy and paste the hashed password, it works.
<?php
/* NEW.PHP
Allows user to create a new entry in the database
*/
// creates the new record form
// since this form is used multiple times in this file, I have made it a function that is easily reusable
function renderForm($email, $pass, $error)
{
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>New User</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<?php
// if there are any errors, display them
if ($error != '') {
echo '<div style="padding:4px; border:1px soluser_id red; color:red;">'.$error.'</div>';
}
?>
<form action="" method="post">
<div>
<strong>Update User Info <br><br><br><br><br>Email: *</strong>
<input type="text" name="email" value="<?php echo $email; ?>" /><br/>
<strong>Password: *</strong> <input type="password" name="pass" value="<?php echo $pass; ?>" /><br/>
<p>* required</p>
<input type="submit" name="submit" value="Submit"> <br><br>Back to home?</div>
</form>
</body>
</html>
<?php
}
// connect to the database
include('connect-db.php');
// check if the form has been submitted. If it has, start to process the form and save it to the database
if (isset($_POST['submit'])) {
// get form data, making sure it is valuser_id
$email = mysql_real_escape_string(htmlspecialchars($_POST['email']));
$pass = mysql_real_escape_string(htmlspecialchars($_POST['pass']));
// check to make sure both fields are entered
if ($email == '' || $pass == '') {
// generate error message
$error = 'ERROR: Please fill in all required fields!';
// if either field is blank, display the form again
renderForm($email, $pass, $error);
} else {
// save the data to the database
mysql_query("INSERT users SET email='$email', pass=MD5('$pass')")
or die(mysql_error());
// once saved, redirect back to the view page
header("Location: view.php");
}
} else {
// if the form hasn't been submitted, display the form
renderForm('','','');
}
?>
As you can see it does hash it when I enter it into the database, but when I try to use the password the way it was originally spelled, it tells me it's the wrong one.
I would do the MD5 hashing on the PHP side. Print it before it goes into the database and try to compare it with the input given on the login form.
Also the htmlspecialchars is not needed in this case. Since your escaping is fine. If it would contain weird chars, it would match them against the database.
Also make sure your encoding type is set on both pages and make sure they're the same.
Without seeing your SELECT query in the login form I'd ask if you're MD5 hashing it when you select it as well?
mysql_query("SELECT * FROM users WHERE email='$email' AND pass=MD5('$pass')")
or die(mysql_error());
However, I agree that you shouldn't be using MD5 for password hashing. Check out http://php.net/manual/en/function.password-hash.php

Cannot modify header information - headers already sent [duplicate]

This question already has answers here:
How to fix "Headers already sent" error in PHP
(11 answers)
Closed 9 years ago.
I know that this is well known problem but I've tried all solutions with no avail :(
Here is my code:
<?php
ob_start();
if (!empty($_POST)) { // if submit
$username = $_POST['username'];
$userpass = $_POST['userpass'];
mysql_connect('localhost', 'root', 'root') or die(mysql_error());
mysql_select_db('ita4') or die($connection_error);
function login($username, $userpass) {
$sqlQuery = "SELECT COUNT(userid) FROM users WHERE name='$username' AND password='$userpass' AND admin='t'";
$runQuery = mysql_query($sqlQuery);
return (mysql_result($runQuery, 0) == 1) ? TRUE : FALSE;
}
if(login($username, $userpass)) {
setcookie("username", $username, time()+60*60*24*30);
$_COOKIE['username'] = $username;
echo "Me:".$_COOKIE['username'];
//echo "<script> location.replace('done.html'); </script>";
} else {
echo "<script> alert('Your input data is not found!'); </script>";
}
}
?>
<html>
<head>
<title>Login</title>
<link rel="stylesheet" type="text/css" href="style.css">
<meta http-equiv=content-type content="text/html; charset=UTF-8"/>
</head>
<body>
<div id="upper">
Home • Login • About
</div>
<div id="container">
<div id="loginDiv">
<form action="login.php" onsubmit="return checkEmpty()" method="post" name="loginForm">
<table>
<tr>
<td style="width:100px">Name: </td>
<td>
<input name="username" id="username" type="text" style="width:250px"></td>
</tr>
<tr>
<td style="width:100px">Password: </td>
<td>
<input name="userpass" id="userpass" type="password" style="width:250px"></td>
</tr>
<tr>
<td colspan="2" style="text-align:center"><input id="loginImg" type="image" src="images/loginButton.png"></td>
</tr>
</table>
</form>
</div>
</div>
<div id="lower">
<br><br><br><br><br>
<p style="text-align:center">COPYRIGHTS © 2013 • WWW.HISHAM.WS</p>
</div>
<script type="text/javascript">
function checkEmpty() {
var username = document.getElementById("username").value;
var userpass = document.getElementById("userpass").value;
if(username=="" || username==null) { alert("You've to enter your name!"); }
else if(userpass=="" || userpass==null) { alert("You've to enter a password!"); }
else { return true; }
return false;
}
</script>
</body>
</html>
Thanks in advance
So against my initial reaction to not help you, I decided to go ahead and build the database and table like you have. I created a new database named ita4 and added a table called users with four fields (userid, name, password, and admin). I added a user named josh with a password of josh and an admin setting of 't'. I then put your file into my local development environment and named it login.php. I then loaded up the page in my browser and entered josh for the username and josh for the password and it resulted in it displaying "Me:josh" at the top of the page and the login page still displaying below it. I get no errors.
If you aren't getting that far, then the error message may be because the database connection details are bad or your table doesn't have one of those fields. You do have a "or die(mysql_error()" after the database connect code.
The header needs to be the first thing in the document. Your code should look something like
<?php header("header information"); ?>
<html>
... Your HTML HERE ...
</html>
More information can be found in the PHP documentation here.
As far as i understand, you want to redirect the user to another page if a login occurs.
You could use javascript and/or meta redirections in order to do that.
This question might also help : How to redirect if user already logged in
You did not tell the line number that causes the notice. But I assume it is because you are doing setCookie().
You are already using ob_start() so that is good.
What I suggest is that you pay attention to that NO CHARACTERS should be at the start of the document, before the ob_start(). Look especially for any characters or even white spaces or enters (new lines), before you start <?php. Let <?php be the very first thing in your file.

Carry message through a website using PHP OOP

I am a beginner to PHP and i want to make a static method that if its argument is empty it'll show the message. If not, it'll set the given message to a static variable for later use. But when i call the method to set the message, and then call it in another page to show the message. Nothing appear.
Here's my portion of code for this "session.php" :
class Session {
public static $message;
public static function notify($message = ""){
if(!empty($message)){
self::$message = $message;
} else {
return self::$message;
}
}
}
$session = new Session();
"add_user.php" :
<?php
require_once '../helper/session.php';
?>
<?php
if (isset($_POST["submit"])) {
$user->username = $_POST["username"];
$user->password = $_POST["password"];
$user->first_name = $_POST["first_name"];
$user->last_name = $_POST["last_name"];
if($result = $user->add_user()){
Session::notify("New user added");
redirect_to("../view/login.php");
} else { Session::notify("Cannot add new user"); }
}
?>
"login.php" :
<?php
require_once "../control/add_user.php";
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet" href="../stylesheet/login.css" />
<title>Welcome to Harmony</title>
</head>
<body>
<header>
<h2>Harmony</h2>
</header>
<section>
<div id="formStyle">
<h3>Login or Signup:</h3>
<form action="login.php" method="post">
<p><label for="username">Username: </label>
<input type="text" name="username" value="" placeholder="Username"/></p>
<p><label for="password">Password: </label>
<input type="text" name="password" value="" placeholder="Password"/></p>
<input type="submit" name="submit" value="Submit" />
<input type="button" name="sign_up" value="Sign up" onClick="parent.location='add_user.php'">
</form>
<?php echo Session::notify(); ?>
</div>
</section>
</body>
</html>
You aren't really writing to the session, now are you?
You should create two more methods for getting and setting the variables in the actual session. After the redirect, your message dissapears, because it is only saved on script execution.
function set_notification($message) {
$_SESSION['notification'] = $message; }
function get_notification() {
if(!empty($_SESSION['notification'])) {
return $_SESSION['notification']; }
Something like that :)
Of course, for sessions to work, you should do a session_start() call in the beginning of the script. read more about them here
HTTP by nature is shared-nothing, so anything you do in one request is not available to any other request. You will need to use a shared datastore to persist these messages.
A database, memcache, even a text file on the server (assuming you are operating on a single server and are not load balancing multiple) are all choices.
You can use cookies on the client side to persist a small amount of data. But keep in mind its not a secure solution (without using encryption) and you are limited in the amount of data you can store in cookies.
HTTP - and PHP - is stateless. You need to use session variables to track data across sessions
http://www.php.net/manual/en/book.session.php

Categories