PHP MySQL login system

Taken from TutorialRepublic.

User Authentication Mechanism

The Registration System

This section will demonstrate how to build a registration system that allows users to create a new account.

Step 1: Creating the Database Table

First build a users table by executing the following SQL code:

CREATE TABLE users (
 id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
 username VARCHAR(50) NOT NULL UNIQUE,
 password VARCHAR(255) NOT NULL,
 created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

Step 2: Creating the Config File

Create this Object Orientated PHP include file that will be called when a connection to the MySQL database is required.

<?php /* Database credentials. Assuming you are running MySQL server with default setting (user 'root' with no password) */

define('DB_SERVER', 'localhost'); 

define('DB_USERNAME', 'root'); 

define('DB_PASSWORD', '');

 define('DB_NAME', 'demo'); 

/* Attempt to connect to MySQL database */

$mysqli = new mysqli(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
 
// Check connection
if($mysqli === false){
die("ERROR: Could not connect. " . $mysqli->connect_error);
}
?>

Step 3: Creating the Registration Form

Create a new include file in the root called register.php to create new users and their password hash

<?php
// Include config file
require_once "config.php";
 
// Define variables and initialize with empty values
$username = $password = $confirm_password = "";
$username_err = $password_err = $confirm_password_err = "";
 
// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){
 
    // Validate username
    if(empty(trim($_POST["username"]))){
        $username_err = "Please enter a username.";
    } else{
        // Prepare a select statement
        $sql = "SELECT id FROM users WHERE username = ?";
        
        if($stmt = $mysqli->prepare($sql)){
            // Bind variables to the prepared statement as parameters
            $stmt->bind_param("s", $param_username);
            
            // Set parameters
            $param_username = trim($_POST["username"]);
            
            // Attempt to execute the prepared statement
            if($stmt->execute()){
                // store result
                $stmt->store_result();
                
                if($stmt->num_rows == 1){
                    $username_err = "This username is already taken.";
                } else{
                    $username = trim($_POST["username"]);
                }
            } else{
                echo "Oops! Something went wrong. Please try again later.";
            }
        }
         
        // Close statement
        $stmt->close();
    }
    
    // Validate password
    if(empty(trim($_POST["password"]))){
        $password_err = "Please enter a password.";     
    } elseif(strlen(trim($_POST["password"])) < 6){
        $password_err = "Password must have atleast 6 characters.";
    } else{
        $password = trim($_POST["password"]);
    }
    
    // Validate confirm password
    if(empty(trim($_POST["confirm_password"]))){
        $confirm_password_err = "Please confirm password.";     
    } else{
        $confirm_password = trim($_POST["confirm_password"]);
        if(empty($password_err) && ($password != $confirm_password)){
            $confirm_password_err = "Password did not match.";
        }
    }
    
    // Check input errors before inserting in database
    if(empty($username_err) && empty($password_err) && empty($confirm_password_err)){
        
        // Prepare an insert statement
        $sql = "INSERT INTO users (username, password) VALUES (?, ?)";
         
        if($stmt = $mysqli->prepare($sql)){
            // Bind variables to the prepared statement as parameters
            $stmt->bind_param("ss", $param_username, $param_password);
            
            // Set parameters
            $param_username = $username;
            $param_password = password_hash($password, PASSWORD_DEFAULT); // Creates a password hash
            
            // Attempt to execute the prepared statement
            if($stmt->execute()){
                // Redirect to login page
                header("location: login.php");
            } else{
                echo "Something went wrong. Please try again later.";
            }
        }
         
        // Close statement
        $stmt->close();
    }
    
    // Close connection
    $mysqli->close();
}
?>
 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Sign Up</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css">
    <style type="text/css">
        body{ font: 14px sans-serif; }
        .wrapper{ width: 350px; padding: 20px; }
    </style>
</head>
<body>
    <div class="wrapper">
        <h2>Sign Up</h2>
        <p>Please fill this form to create an account.</p>
        <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
            <div class="form-group <?php echo (!empty($username_err)) ? 'has-error' : ''; ?>">
                <label>Username</label>
                <input type="text" name="username" class="form-control" value="<?php echo $username; ?>">
                <span class="help-block"><?php echo $username_err; ?></span>
            </div>    
            <div class="form-group <?php echo (!empty($password_err)) ? 'has-error' : ''; ?>">
                <label>Password</label>
                <input type="password" name="password" class="form-control" value="<?php echo $password; ?>">
                <span class="help-block"><?php echo $password_err; ?></span>
            </div>
            <div class="form-group <?php echo (!empty($confirm_password_err)) ? 'has-error' : ''; ?>">
                <label>Confirm Password</label>
                <input type="password" name="confirm_password" class="form-control" value="<?php echo $confirm_password; ?>">
                <span class="help-block"><?php echo $confirm_password_err; ?></span>
            </div>
            <div class="form-group">
                <input type="submit" class="btn btn-primary" value="Submit">
                <input type="reset" class="btn btn-default" value="Reset">
            </div>
            <p>Already have an account? <a href="login.php">Login here</a>.</p>
        </form>
    </div>    
</body>
</html>

Setting up Sass

Install Sass in local environment

Create a folder called sass and a file within that called main.scss

(You can use terminal commands (mkdir, touch))

Configuring package.json

Determine how to compile sass by setting scripts in package.json

"scripts": {
 "compile:sass": "node-sass sass/main.scss css/style.css -w"
},

To compile Sass, open terminal and type:  npm run compile:sass

The -w tag will watch for changes within the source file and auto compile.

Live Server

Install using npm

npm install live-server -save

or install globally

sudo npm install live-server -g

type live-server in command prompt and cmd will auto launch

Installing Sass locally using NPM

NPM & the Node Ecosytem

node.js

An open source JavaScript runtime, allows developers write and run JS app on the server. Can also be used to write tools to help with local web development.

NPM

Node Package Manager. Command line interface to allow installation and management of packages on local systems.

Make sure the latest version of node.js is installed (download from node.js website).

node -v on the command line will inform you what version of node.js is on the system.

package.json

First thing to create when creating a new project. Will contain the definitions of the project and where NPM will install the tools and packages its required.

npm init will help you create a package.json file.

You can use pakage.json file to install all the dependencies if you need to work on the project elsewhere, just type npm install

Install Sass

$ npm install node-sass --save-dev

Use NPM to install other dependencies such as jquery (include –save)

npm install jquery --save

This will show in the dependencies (not the devdependencies.

When setting up GIT, make sure to ignore all node_modules so as not to include all the dependencies

Sass – the basics

Features

  • Variables: for reusable values such as colours, font-sizes, spacing, etc;
  • Nesting: To nest selectors inside of one another, allowing us to write less code;
  • Operators: For mathematical operations right inside of CSS;
  • Partials & Imports: To write CSS in different files and importing them all into one single file;
  • Mixins: To write reusable pieces of CSS code;
  • Functions: similar to mixins, with the difference that they produce a value that can then be used; ie darken(color, i%)
  • Extends: To make different selectors inherit declarations that are common to all of them;
  • Control Directives: for writing complex code using conditionals and loops;

Sass syntax vs SCSS syntax

Sass: no requirement for brackets or semi-colons

SCSS similar to traditional CSS, clearer to follow and easier to convert old CSS projects.

Mixins, Functions & Extends

Mixins

ie Clearfix mixin:

@mixin clearfix {
 &::after {
  content: "";
  clear: both;
  display: table;
 }
}

nav {
 @include clearfix;
}

Mixins are groups of CSS that can be reused. Use @include to insert the mixin.

You can also pass arguments through mixins:

@mixin style-link-text($colour) {
 text-decoration: none;
 text-transform: uppercase;
 color: $colour;
}

@include style-link-text(#FFF);

Functions

Functions are like mixins but you can perform mathematical action using arguments passed in parenthesis:

@function divide($a, $b) {
 return $a / $b;
}

Sass has a number of built in functions such as darken() and lighten().

Extends

 

%btn-placeholder {
 styling
}

extend %btn-placeholder

Like mixins, this allows you to reuse code, however instead of copying the code to each element, when compiled it will group all the elements together and apply the style. Use instead of mixins when the elements are related to each other.

WordPress Migration

  1. Install and activate All-in-One WP Migration plug in on local / test environment
  2. Go to destination site and install and activate the plug in.
  3. Go back to source site and Click on All-in-One WP Migration -> Export, save and download as file.
  4. Go to destination site.Click on All-in-One WP Migration -> Import. Select File and select downloaded source file.
  5. Save Permalinks on destination site.

Moving a WordPress site from a subdomain to the root

  1. Back up both sites to a file using All-in-One WP Migration
  2. Import dev site to live site using the same plug in
  3. Save Permalinks on destination site.

CSS Animations

Two Types of animation

@Keyfrees

Create a keyframes function:

 
@keyframes animationLabel {
0% {
opacity: 0;
transform: translateX(-100px); // this element will be reposition 100px to the left
}
100% {
opacity: 1;
transform: translate(0);
}
 
Use the following CSS tags to call the animation
.movingElement {
animation-name: moveInLeft;
animation-delay: 3s
animation-duration: 1s
animation-iteration-count: 3;
animation-timing-function: ease | ease-in | ease-out | ...
backface-visibility: hidden;
animation-fill-mode: backwards; //will automatically apply keyframe 0 before animation starts
}

Refer to online documentation for all the animation properties.

If animation is shakey use backface-visibility property on element.

Transition Property

button:hover {
 transform: translateY(-3px);
 box-shadow: 0 10px 20px rgba(0,0,0,.2);
}

button:active {
 transform: translateY(-1px);
 box-shadow: 0 5px 10px rgba(0,0,0,.2);
}

button:link, button:visited {
 transition: all .2s;
}

transition:  property | duration;

 

CSS Tips

3 Pillars of writing HTML & CSS

Responsive Design, Maintainable & Scalable Code, Web Performance

Reset CSS

*,
a::before,
a::after {
 margin: 0;
 padding: 0;
 box-sizing: inherit;
}

body {
 box-sizing: border-box; // padding are not added to width of box, width size is set at border level
}

Font Sizing, REMs and Responsive text sizing

Bad practice to declare font-size as pixels (prevents users from changing font-size in their browsers). Declaring font-size in REM sizes font to a multiple of the root font size (set by the browser, usually 16px).

If you wish to change the root font size, do so under the html element and as a percentage of the browser root:

html {
 font-size: 87.5%; // 14px if browser root is 16px
}

You can then use media queries to resize all fonts proportionately by changing the size declared in html.

Not supported in IE9.

Scaling divs in relation to Viewport Height:

Use [int]vh; (Integer is percentage of viewport height.

header : 95vh // Header is 95% of height of viewport

Clearfix

<nav class="clearfix">

.clearfix::after {
 content: "";
 clear: both;
 display: table;
}

Gradient

background-image: linear-gradient(to right bottom, rgba1, rgba2), url(../img/hero.jpg);

The above CSS puts an opaque gradient from top left to right bottom over a hero image.

Clip-Path / Polygon

clip-path: polygon(x y, x y, x y, x y, x y)

Creates a clipping mask over the element. Use polygon to create a shape. Parameters are Top-right, top-left, bottom-left, bottom-right.

Use Clippy to generate polygon

Translate (transform)

Reposition the elements top/left co-ordinates. Useful when using absolute position to centre an element:

.element {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
}

g

jQuery Basics

The document ready function

$(document).ready(function(){
// jQuery programming goes here
}); // end ready

This is only required when you include your javaScript in the head of your document before html – because you often use JS to manipulate existing HTML on the page, you’ll need to wait until all the elements have loaded before executing any JS commands.