Results 1 to 3 of 3

Thread: Pre-populate form with SQL using Cookies or Session?

  1. #1
    Join Date
    Jul 2017
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Pre-populate form with SQL using Cookies or Session?

    So, I am trying to make a form where some of it is already filled in if a user is signed in. The first 4 fields (a couple of text fields, a radio button field, and a check box field) would be pre-populated, based on what the person had submitted for their "register" form. The rest of this second form would be some check boxes, and a couple of text fields.
    So, would the best way to do this be to set a cookie when they sign in? The sign in page is like this:

    Code:
    <?php 
    // check for required fields from the form
    if ((!isset($_POST['email'])) || (!isset($_POST['password']))) {
    	header("Location: userlogin.html");
    	exit;
    }
    //connect to server and select database
    $mysqli = mysqli_connect("localhost", "accessi4_lara", "buster77", "accessi4_ftoo362")
    			or die(mysqli_error());
    // use mysqli_real_escape_string to clean the input
    $email = mysqli_real_escape_string($mysqli, $_POST['email']);
    $password = mysqli_real_escape_string($mysqli, $_POST['password']);
    //create and issue the query 
    $sql = "SELECT username FROM frmak_form_1 WHERE 
    email = '".$email."' AND 
    password = '".$password."' ";
    $result = mysqli_query($mysqli, $sql) or die(mysqli_error($mysqli));
    // get the number of rows in the result set; should be 1 if a match
    if (mysqli_num_rows($result) == 1) {
    while ($info = mysqli_fetch_array($result)) {
    		$username = stripslashes($info['userName']);
    			}
    // set authorization cookie
    	setcookie("auth", "1", 0, "/", "accessibilityscout.com", 0);
    	//create display string
    	$display_block = "
    		<p>".$username." is authorized! </p>
    		<p>Authorized Users' Menu: </p>
    		<ul>
    		<li><a href=\"submitReview.php\">Click here to submit a review! </a></li>
    		</ul>
    		";
    		} else {
    			//redirect back to the login form if not authorized
    			header("Location: userlogin.html");
    			exit;
    		} 
    // close connection to MySQL
    		mysqli_close($mysqli);
    ?>
    <!DOCTYPE html>
    <html>
    <head>
    	<title>User Login</title>
    </head>
    <body>
    	<?php echo $display_block; ?>
    </body>
    </html>
    Or would I set a session? And what would be the syntax for doing such. I am trying to self-teach this PHP/MySQL stuff, and I'm having a rough time with this part. If anyone could just point me toward a good tutorial, that would be great. Thanks!

  2. #2
    Join Date
    Jan 2015
    Posts
    78
    Thanks
    0
    Thanked 19 Times in 19 Posts

    Default

    Starting from the bottom and working back to the top.

    If what you are doing is recording reviews of something, the data being recorded should just be the logged in user's id and the unique information about the review. If you are thinking of storing a bunch of the user's information in with the review data, don't. That is just making more work for you and would require updating all the review data if the user ever needed to change any of his information. You can display the logged in user's information on any page, but if you want to store data related to the user, just store the user's id in with the related data.

    When a user successfully logs in, you need to store the user's id in a session variable. You can then check on any page request if the user is logged in, by checking if the session variable is set, and you can retrieve the user's data from wherever it is stored, whenever you need it, by using the user's id. You would not store the rest of the user's data in session variables, since this will make it harder for the data to be edited by an administrator/moderator on your site.

    Your current code using a cookie as two problems - 1) it is all static data and anyone or a bot script can create a cookie once they learn what the values need to be, and they can appear to be logged in, and 2) it doesn't identify who the user is, so you would not be able to associate any of the user data with the actual user. If you would be tempted to store the user's id in the cookie, this would then let anyone or a bot script try all the possible user ids, and eventually find one that allows them to impersonate an administrator/moderator on your site. To successfully use a cookie, you need to generate a random unique identifier when the user logs in, store this in the cookie and store it in a column in your user data table. You would use this unique identifier from the cookie to identify who the user is, by querying for the matching value in the user data table. I recommend that you start with just the user's id in a session variable.

    Your form processing code should just deal with processing the form data. It should not be responsible for producing any actual output for the page. The end result of the form processing code should be, either - set the session variable with the user's id, set error messages in a php array variable, and possibly set a success message in a session variable. If you want to produce any content that is specific to having a logged in user, you should test if the session variable is set.

    When your form processing code successfully finishes (no errors), you should do a header() redirect to the exact same url of the page. This causes a get request for the page. This will prevent most browsers from trying to re-submit the form data, which will make for a better user experience (UX.) Your form should also be on the same page. This will simplify the overall coding and allow you to display any validation errors and re-display the form with the form fields populated with previously submitted data, so that the user only has to correct the fields with problems, not re-enter data in all the fields.

    Don't use a loop if you are fetching at most one row of data, just fetch the data, and there's no good reason to use stripslashes() on data being retrieved from a query, this would mean that the data was inserted incorrectly into the database table or it would prevent using a \ as a character in the data.

    The passwords should be hashed when stored. See php's password_hash() and password_verify() functions.

    You should not display the mysqli_error(...) information on a live site. To handle database statement errors, you should use exceptions. Then all you have to do is enable exceptions for the php database extenstion you are using and let php catch any exception (you would eliminate all the or die(...) logic that is there now.) Php will use it's error_reporting/display_errors/log_errors settings to control what happens with the actual error information. Error_reporting should always be set to E_ALL. When learning, developing, and debugging code, display_errors should be set to ON. When on a live server, display_errors should be OFF and log_errors should be ON.

    The ...escape_string() functions are not fool-proof. If the character set that php is using is not the same as what your database tables are using, it is still possible to inject sql. The surest way of preventing sql injection is to use prepared queries, with place-holders in the sql query statement for data values, then supply the data when you execute the query. This actually simplifies the sql query syntax and will simplify the overall amount of code, since the ...escape_string() call can be removed. Basically, a prepared query will replace any value and the quotes around the value in the sql query statement with a ? place-holder. Instead of calling a query() statement, you would call the prepare() statement, for mysqli you would make a call to bind the place-holders with the variables holding the data, then you would call an execute() statement. Unfortunately, the php mysqli extension is not very well designed, especially when dealing with prepared queries, and it takes more php statements to actually fetch the data from a prepared query. If you can, switch to the php PDO extension. It is much simpler. You can eliminate the binding of the place-holders with the variable and fetching data using PDO is simple and is the same if you use a prepared query or not.

    I hope the database connection credentials in the post are not the actual values. If you are using a publicly accessible server, you should change your username and password ASAP. In general, you should store configuration values in a separate .php file and require them into any main code that needs them.

    Your form processing code needs to detect that a post method form has been submitted and if the code on any page will handle more than one form, you need to further detect a field name or a field value that identifies which form was submitted.

    Your form processing code needs to validate the input data and only use the data if it passes validation. If either of the two form fields are empty, there's no point in running the rest of the form processing code and you should set up and display unique and specific validation error messages to tell the visitor what is wrong with the submitted data, short of exposing information that helps a hacker. For a failed login, if either the email or password doesn't match, the message should just tell the visitor that the login information didn't match. If you tell them that it is the email or the password that doesn't match, and if you don't have any sort of brute-force detection and reporting, your code can be used to find valid email addresses, then to eventually find matching passwords. If you add the validation errors to a php array, you can then test if that array is empty or is not empty to determine if there are no errors or if there are errors. You would display the contents of the errors array when you re-display the form.

    If the current visitor is already logged in, you should not display the login form or run the login form processing code.

    This looks like a lot of information, but work through them one item at a time. Several of these points will actually reduce the amount of code/clutter. If I/someone has time, they will post an example showing these points.
    Last edited by DyDr; 07-27-2017 at 03:01 PM. Reason: typos

  3. #3
    Join Date
    Jan 2015
    Posts
    78
    Thanks
    0
    Thanked 19 Times in 19 Posts

    Default

    Here is an example showing the suggestions above. Note: I have changed the database table name, so that it indicates the meaning of the data, this example uses the php PDO database extension, not the mysqli extension, and since this code expects the passwords to be hashed, your registration code needs to be modified to use the password_hash() function and then delete and re-register any users.

    PHP Code:
    <?php
    // start/resume any session
    session_start();


    // helper functions - either define these in a file and require the file or define them in-line in the main code

    // user login/authentication will use a session variable to indicate/identify who the logged in user is
    // test/get the logged in user's id - the user id is a true value, so this function returns a true value, the id, for a logged in user, or a false value, if the user is not logged in
    function logged_in()
    {
        return isset(
    $_SESSION['user_id']) ? $_SESSION['user_id'] : false;
    }

    // the dynamic values being output in the html document need to be converted to html entities in case they contain any characters that have meaning in html markup
    // apply htmlentities to a general value
    function _ent($val)
    {
        return 
    htmlentities($val,ENT_QUOTES,CHAR_ENCODING);
    }

    // return an element of a supplied array - used for both the $data and $errors arrays
    function _data($idx,$data)
    {
        return isset(
    $data[$idx]) ? $data[$idx] : '';
    }


    // require either configuration values (the connection credentials) or the whole connection code
    // this example uses the php PDO extension, not the msyqli extension
    require 'pdo_connection.php'

    $errors = []; // define an array to hold errors
    $data = []; // define an array to hold a working/trimmed copy of the submitted form data. for this example, of submitting new data, this is not absolutely necessary, but if you were editing existing data, you would need this. to make the code general purpose, just go ahead and define and use a variable for this.

    // from processing code - since this is the only form processing in this example, for logging in, it will only be executed if the visitor is not already logged in
    if(!logged_in() && $_SERVER['REQUEST_METHOD'] == 'POST')
    {
        
    $data array_map('trim',$_POST); // get a trimmed copy of all 1st level (non-array) data
        
        // validate the inputs
        
    if($data['email'] == '')
        {
            
    $errors['email'] = "Email is required.";
        }
        if(
    $data['password'] == '')
        {
            
    $errors['password'] = "Password is required.";
        }
        
        
    // if no errors, use the submitted data
        
    if(empty($errors))
        {
            
    //create and issue the query 
            
    $sql "SELECT id, password FROM users WHERE email = ?"// your table should be named to indicate the meaning of the data stored in it
            
    $stmt $pdo->prepare($sql);
            
    $stmt->execute([$data['email']]);
            
    // attempt to fetch the data from the query - for a single row of data, this accomplishes the same as checking the number of rows, followed by a fetch statement
            
    if(!$row $stmt->fetch())
            {
                
    // no row found, the email doesn't match
                
    $errors['login'] = "The email/password isn't valid.";
            }
            else
            {
                
    // found the email, check the password
                
    if(!password_verify($data['password'],$row['password']))
                {
                    
    // password doesn't match
                    
    $errors['login'] = "The email/password isn't valid.";
                }
                else
                {
                    
    // password matched - set the session variable with the user's id
                    
    $_SESSION['user_id'] = $row['id'];
                }
            }
        }

        
    // if no errors, the form processing successfully ran
        
    if(empty($errors))
        {
            
    // you can redirect to the exact same url of this page to improve the UX...
            
        
    }
        
    // if there are any errors, continue to display the page
    }

    // get/produce the content for the page

    // get user's data
    $user false;
    if(
    $user_id logged_in())
    {
        
    $sql "SELECT username FROM users WHERE id = ?";
        
    $stmt $pdo->prepare($sql);
        
    $stmt->execute([$user_id]);
        
    $user $stmt->fetch();
    }

    // the main content
    $display_block '';
    if(
    logged_in())
    {
        
    $display_block "
        <p>"
    _ent($user['username']) ." is authorized! </p>
        <p>Authorized Users' Menu: </p>
        <ul>
        <li><a href='submitReview.php'>Click here to submit a review! </a></li>
        </ul>
        "
    ;
    }

    if(!
    logged_in())
    {
        
    $display_block "
        <form method='post'>
        Email: <input type='email' name='email' value='"
    _ent(_data('email',$data)) ."'><br>
        Password: <input type='password' name='password' value='"
    _ent(_data('password',$data)) ."'><br>
        <input type='submit'></form>
        "
    ;
    }

    // the html document
    ?>
    <!DOCTYPE html>
    <html>
    <head>
        <title>User Login</title>
    </head>
    <body>
        <?php
        
    // display any errors
        
    if(!empty($errors))
        {
            echo 
    "<p>".implode('<br>',$errors)."</p>";
        }

        
    // display the main content
        
    echo $display_block;
        
    ?>
    </body>
    </html>
    An example of the pdo_connection.php code -
    PHP Code:
    <?php
    define
    ('DB_HOST','localhost');
    define('DB_NAME','your database name');
    define('DB_USER','your database username');
    define('DB_PASS','your database password');
    define('DB_ENCODING''utf8'); // db character encoding
    define('CHAR_ENCODING','UTF-8'); // document/page character encoding

    $pdo = new pdo("mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_ENCODING,DB_USER,DB_PASS);
    $pdo->setAttribute(PDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION); // set the error mode to exceptions
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); // run real prepared queries
    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC); // set default fetch mode to assoc
    Last edited by DyDr; 07-27-2017 at 03:05 PM. Reason: added to the notes:

Similar Threads

  1. php to self populate existing form
    By theremotedr in forum PHP
    Replies: 88
    Last Post: 02-19-2017, 02:15 PM
  2. Replies: 4
    Last Post: 11-21-2014, 02:58 AM
  3. Populate form form MySQL data
    By Rob (SA) in forum MySQL and other databases
    Replies: 13
    Last Post: 04-18-2009, 10:48 AM
  4. Cookies instead of session cookies?
    By DisturbedRoach in forum JavaScript
    Replies: 1
    Last Post: 10-21-2008, 09:12 PM
  5. Permanent and Session-Only Cookies
    By tech_support in forum JavaScript
    Replies: 2
    Last Post: 07-08-2006, 07:57 AM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •