PHP Demo Program


Ron Fredericks writes: I am LectureMaker’s video platform technologist. So I thought I would demonstrate some of my sample code in building a simple website demo.

The demo consists of three pages that feature the following code

  • PHP programming with OO and model-view-controller (MVC) architecture
  • SQL file to create a new table and load some sample user data
  • PHP sessions and OO MySQL Data Manager
  • Use of CSS style sheet and tags for web page layout and forms management
  • Use of JavaScript and jQuery functions and project library
  • A RESTful API allowing users to move data between the three pages

Visit the running project’s website here:
www.lecturemaker.com/test/HP_login.php

Download a copy of the project’s source code from GitHub:
https://github.com/RonFredericks/PHP_Demo_Project

Overview

Build a 2-3 page website with a single page view concept with JavaScript mvc and REST service. The concept of the site is to choose your background. After login the user can select a file to upload and that becomes the background image of the landing page. Page 1 is login with at least 3 different users who can login. Page 2 is landing page which will show the image uploaded and page 3 is upload the background image you like. Page 2 and 3 should have a logout button.

Overview of the Project

Overview of the Project

FAQ

What is OOP?
Object Oriented Programming, or OOP, invokes the use of classes to organize the data and structure of an application:

  • Objects: instances of a class
  • Inheritance: ability to pass characteristics and behaviors from a base class
  • Access Modifiers: ability to protect data and methods
  • Interfaces: a form of abstract class that acts as a model for creating a derived class
  • PHP 5 Built-in Classes: Standard PHP Library (SPL), mysqli, PDO, SQLite, XML support, relfection, Iterator interface, magic methods, objects passed by reference
  • Design Patterns: a reusable set of solutions that solve practical problems

What is MVC?
Model–View–Controller (MVC) is an architectural pattern used in software engineering:

  • Model handles database logic. Code in the model connects to the database and provides an abstraction layer.
  • Controller represents the business (application) logic i.e. all our ifs and else.
  • View provides the presentation logic i.e our HTML/XML/JSON code.

What is REST?
Representational state transfer (REST) is a predominant web API design model for distributed systems. PHP examples include:

  • Use FORM tag with GET or POST to send data to another web page.
  • Use cURL to set the URL, create array of POST data, set options such as return XML data, and make request.
  • Create a POST request by opening a TCP connection to the host using fsockopen(), then use fwrite() on the handler returned from fsockopen().

Design Methodology

See the figure above “Overview of the Project” where each web page is shown, along with the MySQL database supporting privileged access to the main project’s feature: to upload a new background image.

To start the project code I started with a basic development environment:

  • WampServer: a Windows, Apache, MySQL, and PHP development environment. I chose this platform to run my test code because I can development the code directly within the Apache Localhost service without the delay of a repeated ftp style upload.
  • Adobe’s DreamWeaver code editor: I use this code editing tool to highlight, format, and check my CSS, HTML, PHP, and JavaScript code. Because I save my files directly into the WampServer, the workflow is fairly efficient.

With this flexible coding environment I create three documents initially: the PHP login page, the CSS file, and a sql field definitions file using a tool called phpmyadmin hosted on my WampServer. I work back and forth between the login page, the CSS file, and the SQL definitions to get the look and feel I have visualized within my wireframe design. I add user fields into my SQL table to manage login storage. And as I start to see a pattern to the JavaScript and PHP support needs for this project: I prepare to add PHP classes, PHP support functions, and JavaScript code into new files as the code is development.

Create Login Page, CSS Stylesheet and SQL file

Create Landing Page

Create Image Upload Page

Create PHP Initialize File

Create Database Class

Create User Class

Create User Manager Class

Code (php)
  1.  
  2. //////////////////////////////////  Create Login Page  ///////////////////////
  3.  
  4. < ?php
  5. // File: HP_login.php
  6. // Purpose: Initialize and start PHP session
  7. // Author: Ron Fredericks, LectureMaker LLC
  8. // Last Updated: 7/10/2013
  9.  
  10.     require_once ‘./HP_assets/HP_initialize.php’;
  11. ?>   
  12. < !doctype html>
  13. "utf-8"/>
  14. Login Page
  15. "stylesheet" type="text/css" href="./HP_assets/HP_main.css"/>
  16. < ?php
  17.     // Insure that prior users are logged out of this web service
  18.     $um->logout();
  19.     // Initiate page div layout and display heading
  20.     PutHeader(HEADING);
  21.     // Initiate login
  22.     LoginForm("HP_uploadImage.php");
  23.     SelectValidUser();
  24.     // Complete page div layout and display footer
  25.     PutFooter(FOOTER);
  26.     exit();     
  27. ?>
  28.  
  29. //////////////////////////////////  Create Landing Page  ///////////////////////
  30.  
  31. < ?php
  32. // File: HP_landingPage.php
  33. // Purpose: Initialize and start PHP session
  34. // Author: Ron Fredericks, LectureMaker LLC
  35. // Last Updated: 7/10/2013
  36.  
  37.     require_once ‘./HP_assets/HP_initialize.php’;
  38. ?>   
  39. < !doctype html>
  40. "utf-8"/>
  41. Landing Page
  42. "stylesheet" type="text/css" href="./HP_assets/HP_main.css"/>
  43. < ?php
  44.  
  45.     PutHeader(HEADING);
  46.    
  47.     if (!isset($user)) {
  48.         PutErrorMessage("You must log in to view this page: ".basename($_SERVER[‘PHP_SELF’]));
  49.         Redirect(‘HP_login.php’, 5);
  50.         exit();
  51.     }
  52. ?>
  53.     < ?php   
  54.     PutErrorMessage(ProcessUploadForm());
  55.     PutFooter(FOOTER);
  56.     ?>
  57.  
  58. //////////////////////////////////  Create Image Upload Page  ///////////////////////
  59.  
  60. < ?php
  61. // File: HP_uploadImage.php
  62. // Purpose: Initialize and start PHP session
  63. // Author: Ron Fredericks, LectureMaker LLC
  64. // Last Updated: 7/10/2013
  65.  
  66.     require_once ‘./HP_assets/HP_initialize.php’;
  67. ?>   
  68. < !doctype html>
  69. "utf-8"/>
  70. Upload Image
  71. "stylesheet" type="text/css" href="./HP_assets/HP_main.css"/>
  72. < ?php
  73.     // Attempt to process user login form $_POST 
  74.     if (ProcessLoginForm($um)) {
  75.         // update user info on successful new login
  76.         $user = $um->getSession();
  77.     }
  78.     PutHeader(HEADING);   
  79.     // Test for valid user, return to login page if user not valid
  80.     if (!isset($user)) {
  81.         PutErrorMessage("You must log in to view this page: ".basename($_SERVER[‘PHP_SELF’]));
  82.         Redirect(‘HP_login.php’, 5);
  83.         die();
  84.     }   
  85.     ?>
  86.    
  87.    
  88.    
  89.     < ?php
  90.     // Initiate image upload form   
  91.     GetImageForm("HP_landingPage.php");
  92.     DisplayValidImageTypes();
  93.     PutFooter(FOOTER);
  94. ?>
  95.  
  96. //////////////////////////////////  Create PHP Initialize File  ///////////////////////
  97.  
  98. < ?php
  99. // File: HP_initialize.php
  100. // Initialize PHP environment
  101. // Author: Ron Fredericks, LectureMaker LLC
  102. // Last Updated: 7/10/2013
  103.  
  104.     define("HEADING", "Select Background Image Project");
  105.     define("IMAGE_DIR", "./HP_images/");
  106.     define("DEBUG", false);    // set to true for more display messages
  107.     error_reporting(-1)// set to (-1) to display all errors, (0) for no errors and (E_ALL ^ E_NOTICE) for default production
  108.     global $validext;   // define valid background image types as global
  109.     $validext = array(".gif"=>"GIF image", ".jpeg"=>"JPEG image", ".jpg"=>"JPG image"".png"=>"PNG image");
  110.     // include the mySQL data management system
  111.     require_once ‘./HP_assets/HP_UserManager.php’;
  112.     require_once ‘./HP_assets/HP_miscFunctions.php’;
  113.     //
  114.     //session_start();
  115.     $um = new UserManager();
  116.     $user = $um->getSession();
  117.  
  118. //////////////////////////////////  Create Database Class ///////////////////////
  119.  
  120. < ?php
  121. // File: HP_Database.php
  122. // Purpose: Define a class to MySQL database connection class
  123. // Author: Ron Fredericks, LectureMaker LLC
  124. // Last Updated: 7/10/2013
  125. // References:
  126. //        http://forum.zonehacks.com/threads/10-PHP-User-Management-System-using-Object-Oriented-Programming-and-MySQL
  127. //        Object-Oriented PHP by Peter Lavin, No Starch Press, 2006
  128. class Database {
  129.    
  130.     private static $instances = 0// make sure db connection is made only once, RDF
  131.     /**
  132.      * =============================================================
  133.      * Change these values to work with your mysql database settings
  134.      * =============================================================
  135.      */
  136.     private $db_host = ‘localhost’;
  137.     private $db_user = ‘xxx’// fill in these values with your credentials
  138.     private $db_pass = ‘xxx’;
  139.     private $db_name = ‘xxx’// fill in your mySQL atabase name here
  140.    
  141.  
  142.     private $where = array();
  143.     private $variables = array();
  144.     private $link;
  145.  
  146.     // see __call method below for implementaiton, RDF
  147.     private $functions = array(
  148.     ‘affected_rows’ => ‘mysql_affected_rows’,
  149.     ‘client_encoding’ => ‘mysql_client_encoding’,
  150.     ‘close’    =>    ‘mysql_close’,
  151.     ‘connect’ => ‘mysql_connect’,
  152.     ‘create_db’ => ‘mysql_create_db’,
  153.     ‘data_seek’ => ‘mysql_data_seek’,
  154.     ‘db_name’    =>    ‘mysql_db_name’,
  155.     ‘db_query’    =>    ‘mysql_db_query’,
  156.     ‘drop_db’    =>    ‘mysql_drop_db’,
  157.     ‘errno’        =>    ‘mysql_errno’,
  158.     ‘error’        =>    ‘mysql_error’,
  159.     ‘escape_string’    =>    ‘mysql_escape_string’,
  160.     ‘fetch_array’    =>    ‘mysql_fetch_array’,
  161.     ‘fetch_assoc’    =>    ‘mysql_fetch_assoc’,
  162.     ‘fetch_field’    =>    ‘mysql_fetch_field’,
  163.     ‘fetch_lengths’    =>    ‘mysql_fetch_lengths’,
  164.     ‘fetch_object’    =>    ‘mysql_fetch_object’,
  165.     ‘fetch_row’        =>    ‘mysql_fetch_row’,
  166.     ‘field_flags’    =>    ‘mysql_field_flags’,
  167.     ‘field_len’        =>    ‘mysql_field_len’,
  168.     ‘field_name’    =>    ‘mysql_field_name’,
  169.     ‘field_seek’    =>    ‘mysql_field_seek’,
  170.     ‘field_table’    =>    ‘mysql_field_table’,
  171.     ‘field_type’    =>    ‘mysql_field_type’,
  172.     ‘free_result’    =>    ‘mysql_free_result’,
  173.     ‘get_client_info’    =>    ‘mysql_get_client_info’,
  174.     ‘get_host_info’        =>    ‘mysql_get_host_info’,
  175.     ‘get_proto_info’    =>    ‘mysql_get_proto_info’,
  176.     ‘get_server_info’    =>    ‘mysql_get_server_info’,
  177.     ‘info’                =>    ‘mysql_info’,
  178.     ‘insert_id’            =>    ‘mysql_insert_id’,
  179.     ‘list_dbs’            =>    ‘mysql_list_dbs’,
  180.     ‘list_fields’        =>    ‘mysql_list_fields’,
  181.     ‘list_processes’    =>    ‘mysql_list_processes’,
  182.     ‘list_tables’        =>    ‘mysql_list_tables’,
  183.     ‘num_fields’        =>    ‘mysql_num_fields’,
  184.     ‘num_rows’            =>    ‘mysql_num_rows’,
  185.     ‘pconnect’            =>    ‘mysql_pconnect’,
  186.     ‘ping’                =>    ‘mysql_ping’,
  187.     ‘query’                =>    ‘mysql_query’,
  188.     ‘real_escape_string’    =>    ‘mysql_real_escape_string’,
  189.     ‘result’            =>    ‘mysql_result’,
  190.     ‘select_db’            =>     ‘mysql_select_db’,
  191.     ‘set_charset’        =>    ‘mysql_set_charset’,
  192.     ‘stat’                =>    ‘mysql_stat’,
  193.     ‘tablename’            =>    ‘mysql_tablename’,
  194.     ‘thread_id’            =>    ‘mysql_thread_id’,
  195.     ‘unbuffered_query’    =>    ‘mysql_unbuffered_query’
  196.     );
  197.  
  198.     function __construct()
  199.     {
  200.         if (Database::$instances == 0) {
  201.             $this->link = @$this->connect($this->db_host, $this->db_user, $this->db_pass)// catch and hide error messages using "@", RDF
  202.             if(!$this->link) {
  203.                 die("Database class: ".mysql_error(). " Error no: ".mysql_errno())// Include all possible error messages in display, RDF
  204.             }
  205.            
  206.             $this->select_db($this->db_name);
  207.             Database::$instances = 1;
  208.         }
  209.     }
  210.    
  211.     function __destruct()
  212.     {
  213.         if($this->link) {
  214.             Database::$instances == 0;
  215.             mysql_close($this->link);
  216.             unset($this->link); // Clear from memory, RDF
  217.         }
  218.     }
  219.    
  220.     // Manage undeclared functions
  221.     public function __call($name, $arguments) {
  222.         if(isset($this->functions[$name])) {
  223.             return call_user_func_array($this->functions[$name], $arguments);
  224.         }
  225.         return FALSE;
  226.     }
  227.    
  228. }
  229.  
  230. //////////////////////////////////  Create User Class ///////////////////////
  231.  
  232. < ?php
  233. // File: HP_User.php
  234. // Purpose: User class to manage undefined data members
  235. // Author: Ron Fredericks, LectureMaker LLC
  236. // Last Updated: 7/10/2013
  237. // References:
  238. //        http://forum.zonehacks.com/threads/10-PHP-User-Management-System-using-Object-Oriented-Programming-and-MySQL
  239. //        Object-Oriented PHP by Peter Lavin, No Starch Press, 2006
  240. class User
  241. {
  242.    
  243.     private $userdata = array();
  244.    
  245.     public function checkPassword($pass)
  246.     {
  247.         if(isset($this->userdata[‘password’]) && $this->userdata[‘password’] == md5($pass)) {
  248.             return true;
  249.         }
  250.         return false;
  251.     }
  252.    
  253.     public function set($var, $value)
  254.     {
  255.         $this->userdata[$var] = $value;
  256.     }
  257.    
  258.     public function get($var)
  259.     {
  260.         if(isset($this->userdata[$var])) {
  261.             return $this->userdata[$var];
  262.         }
  263.         return NULL;
  264.     }
  265. }
  266.  
  267. //////////////////////////////////  Create User Manager Class ///////////////////////
  268.  
  269. < ?php
  270. // File: HP_UserManager.php
  271. // Purpose: Create a class to manage user functions using a MySQL database
  272. // Author: Ron Fredericks, LectureMaker LLC
  273. // Last Updated: 7/10/2013
  274. // References:
  275. //         http://forum.zonehacks.com/threads/10-PHP-User-Management-System-using-Object-Oriented-Programming-and-MySQL
  276. //        Object-Oriented PHP by Peter Lavin, No Starch Press, 2006
  277.  
  278. // Include the User and Database class files
  279. require_once "./HP_assets/HP_User.php";
  280. require_once "./HP_assets/HP_Database.php";
  281.  
  282. class UserManager
  283. {
  284.     private $db;
  285.    
  286.     // Create an instance of the database class and store it into a private variable
  287.     public function UserManager()
  288.     {
  289.         $this->db = new Database();
  290.     }
  291.  
  292.      public  function createUser($username, $password, $email, $is_adminFALSE)
  293.      {
  294.          if (isset($username) && isset($password) && isset($email)) { // Check for invalid function call, RDF
  295.              $stmt = sprintf("INSERT INTO users (`id`, `username`,  `password`,  `email`, `is_admin`) VALUES (NULL, ‘%s’, ‘%s’, ‘%s’,  ‘%d’)",
  296.                     $this->db->real_escape_string($username),
  297.                      md5($this->db->real_escape_string($password)),     // A  md5 hash of the user’s password will be stored in the database.
  298.                      $this->db->real_escape_string($email),             //  always escape data from public before storing in database
  299.                     $this->db->real_escape_string($is_admin));
  300.             $result = $this->db->query($stmt);
  301.    
  302.             if ($result) return true;
  303.          }
  304.         return false;
  305.     } 
  306.  
  307.     public function updateUser($user)
  308.     {
  309.         // Normally I wouldn’t store session data in the database, but
  310.         // it can be changed to track cookies if you plan to go that
  311.         // route.
  312.         $session = $user->get(‘session’);
  313.         if (!$session) $session = 0;
  314.          $stmt = sprintf("UPDATE users SET `username` = ‘%s’, `password`  =  ‘%s’, `email` = ‘%s’, `is_admin` = ‘%d’, `session` = ‘%s’ WHERE `id`  =  ‘%d’",
  315.                 $this->db->real_escape_string($user->get(‘username’)),
  316.                 $this->db->real_escape_string($user->get(‘password’)),
  317.                 $this->db->real_escape_string($user->get(’email’)),
  318.                 $this->db->real_escape_string($user->get(‘is_admin’)),
  319.                 $this->db->real_escape_string($session),
  320.                 $this->db->real_escape_string($user->get(‘id’)));
  321.         return $this->db->query($stmt);               
  322.     } 
  323.  
  324.     public function deleteUser($user)
  325.     {
  326.         $userID = $this->db->real_escape_string($user->get(‘id’));
  327.         return $this->db->query("DELETE FROM users WHERE `id` = ‘$userID’");
  328.      } 
  329.  
  330.     // Get users from the database and return a user object by id or username
  331.     public function getUserByID($id)
  332.     {
  333.         if (isset($id)) {     // Check for invalid function call, RDF
  334.        
  335.             // get the user by id from database
  336.             $stmt = sprintf("SELECT * FROM users WHERE id = ‘%s’", $this->db->real_escape_string($id));
  337.             $result = $this->db->query($stmt);
  338.             if($result) {
  339.                 $user = new User();                            // create a new user object
  340.                 $row = $this->db->fetch_assoc($result);
  341.                 foreach($row as $key => $value) {              // loop through user table values
  342.                     $user->set($key, $value);                // store them in the user object
  343.                 }
  344.                 return $user;                                // and return it
  345.             }
  346.         }
  347.         return NULL;
  348.     }
  349.    
  350.     public function getUserByName($name)
  351.     {
  352.  
  353.         if (isset($name)) {    // Check for invalid function call, RDF
  354.             $stmt = sprintf("SELECT * FROM users WHERE username = ‘%s’", $this->db->real_escape_string($name));
  355.             $result = $this->db->query($stmt) or trigger_error(mysql_error()." ".$stmt);
  356.             if ($result && $this->db->num_rows($result) > 0) {
  357.                 $user = new User();
  358.                 $row = $this->db->fetch_assoc($result);
  359.                 foreach($row as $key => $value) {
  360.                     $user->set($key, $value);
  361.                 }
  362.                 return $user;
  363.             }
  364.         }
  365.         return NULL;
  366.     }
  367.  
  368.     // Get user by name, check the password, updates session info in the database, and return the user object
  369.     public function login($username$password)
  370.     {
  371.         if (isset($username) && isset($password)) {    // Check for invalid function call, RDF
  372.             $user = $this->getUserByName($username);
  373.             if (isset($user) && $user->checkPassword($password)) {               
  374.                 // start PHP session, RDF
  375.                 if(!isset($_SESSION)) session_start();
  376.                 $_SESSION[‘zhuser’] = $user->get(‘username’);            // I normally use these for cookies
  377.                 $_SESSION[‘zhsess’] = md5($username.microtime());        // calculate md5 of username + current unix time
  378.                 $user->set(‘session’, $_SESSION[‘zhsess’]);              // set the session in user object
  379.                 $this->updateUser($user);                                // update the user
  380.                 return $user;                                            // and return the user object if we’re good
  381.             }
  382.         }
  383.         return NULL;
  384.     }
  385.        
  386.     public function logout()
  387.     {
  388.         if (isset($_SESSION)) {
  389.             unset($_SESSION);
  390.             session_destroy();
  391.         }
  392.     } 
  393.  
  394.     //  Check if a session exists and against what we have stored in the database, if they match we’re good
  395.     public  function getSession() 
  396.     {
  397.         // start PHP session, RDF
  398.         if (!isset($_SESSION)) session_start();
  399.  
  400.         if (isset($_SESSION[‘zhuser’]) && isset($_SESSION[‘zhsess’])) {
  401.             $user = $this->getUserByName($_SESSION[‘zhuser’]);
  402.             if (!$user) $this->logout();
  403.             if ($user->get(‘session’) == $_SESSION[‘zhsess’]) {
  404.                 return $user;
  405.             }
  406.         }
  407.         return NULL;
  408.     }
  409. }
  410.  

Create PHP Functions Page

Code (php)
  1. < ?php
  2. // File: HP_miscFunctions.php
  3. // Purpose: PHP Visual display and support functions
  4. // Author: Ron Fredericks, LectureMaker LLC
  5. // Last Updated: 7/11/2013
  6.  
  7.  
  8. //////////////////////////////////////////////////////////////////
  9. // Login Support Functions                                      //
  10. //////////////////////////////////////////////////////////////////
  11.  
  12. function LoginForm($url)
  13. // Present a login form
  14. {
  15.     // Reference: http://designikx.wordpress.com/2010/04/07/pure-css-div-based-form-design-form-layout/
  16.     $myArray[0] = array("test" => "", "message" => "Username must be entered");
  17.     ?>
  18.    
  19.    
  20.    
    "myform">
  21.    
    "loginForm" action="" onsubmit="return login_form(this)" method="post">
  22.    

    Login Window

  23.    

    Welcome to the background image selector website

  24.    
  25.    
  26.     Its Your Name
  27.    
  28.     "username" type="text" name="username"/>
  29.  
  30.    
  31.     Enter Your Password
  32.    
  33.     "password" type="text" name="password"/>
  34.    
  35.    
  36.    
  •     < ?php
  • }
  •  
  • function SelectValidUser()
  • // Present list of valid users for login
  • {
  • ?>
  •    
    "myformsupport">
  •    

    Login List

  •    

    Load one of these valid user credentials into login window

  •    
    •    
    • Ron Fredericks
    •    
    • Tommy Tuba
    •    
    • Admin