Jump to content

Please Critique This Php Mvc Login Code


DeX

Recommended Posts

This is my very first MVC style PHP scripting so I'm wondering if I've done it the very best I can. I've done a lot of reading and this is what I just got working. First I'll explain how it works:

 

- User goes to www.example.com/mvctest.php and gets a login prompt.

- User tries to skip that and go directly to the home2.php page to try and view the site without logging in first. He gets automatically redirected back to mvctest.php for login.

- User gives bad credentials, he gets routed back to mvctest.php for a bad login to try again

- User gives proper credentials and gets logged in, gets redirected to home2.php on successful login.

- User closes their browser window, then opens another and goes back to the homepage at mvctest.php. Instead of getting the login prompts again, he gets redirected straight to home2.php because he's already logged in (cookies remain until midnight).

- User clicks logout button. Their cookie is set to a time in the past and they are redirected back to mvctest.php and prompted for login credentials.

 

That's all the actions I could think of. Now on to the code. It all works except I commented out the disconnecting from the database because it was doing that prematurely and I wasn't able to log in using my mysql link because it had been closed before I got to use it. That's small stuff though, I'm wondering if people can comment on everything, I want this to be as good as it can be. Thanks.

 

mvctest.php:

<?php
   require_once('controller/login.php');
   require_once('model/database.php');
   require_once('view/login.php');
   include('includes/include.php');
?>

<form action="?action=login" method="post">
   Username: <input type="text" name="username">
   Password: <input type="password" name="password">
   <input type="submit">
</form>

 

include.php:

<?php
   $model = new DatabaseModel();
   //It is important that the controller and the view share the model 
   $controller = new LoginController($model);
   $view = new LoginView($controller, $model);

   if (isset($_GET['action']))
       $controller->{$_GET['action']}();
?>

 

home2.php:

<?php
   require_once('controller/login.php');
   require_once('model/database.php');
   require_once('view/login.php');
   include('includes/include.php');
?>

<button type ="button" onclick ="window.location = '<?php echo $_SERVER['PHP_SELF'] ?>?action=logout'" >Log Out</button>

 

controller/login.php:

<?php
   class LoginController //extends Controller
   {
       public $view;
public $databaseModel;
       public $loginModel;

       /**
        * Initializes the Vew and the Model.
        */
       public function __construct($model)
       {
           require_once('model/login.php');
           $this->connection = $model->connectToDatabase();
           $this->loginModel = new LoginModel($model);
           $this->view = new LoginView($this, $model);
           if (!$this->loginModel->checkLogin() && !$this->isLoginPage())
           {
               $this->view->showLoginPage();
               $model->disconnectDatabase();
           }
           else if ($this->loginModel->checkLogin() && $this->isLoginPage())// must wait for loginModel to return before disconnecting
           {
               $model->disconnectDatabase();
               $this->view->loginSuccess(); // go somewhere else if already logged in
           }
           else
               $model->disconnectDatabase();
       }
       /**
        * The "index" action.
        * Called by default if no action is defined.
        */
       public function index()
       {
           $this->show();
       }
       /**
        * The "show" action.
        * Simply instructs the View to display the form.
        */
       public function show()
       {
           $this->view->showForm();
       }

       public function isLoginPage()
       {
           $urlPath = explode("/", $_SERVER['PHP_SELF']);
           if ($urlPath[count($urlPath) - 1] == "mvctest.php")
               return true;
           else
               return false;
       }

       /**
        * The "process" action.
        * Processes the form data, either sending it to the model to be
        * saved into the database, or displays errors if the required
        * fields are not present.
        */
       public function login()
       {
           $requiredFields = array('username', 'password');
           $data = array();
           $error = false;
           foreach($requiredFields as $_field)
           {
               if(!isset($_POST[$_field]) || empty($_POST[$_field]))
               {
                   $error = true;
                   $this->view->showLoginError("Field '{$_field}' needs to be filled.");
               }
               else
               {
                   // Skipping any sort of validation, for the sake of
                   // simplicity.
                   $data[$_field] = trim($_POST[$_field]);
               }
           }
           if($error)
           {
               $this->view->showForm();
           }
           else
           {
               if($this->loginModel->login())
               {
                   $this->view->loginSuccess();
               }
               else
               {
                   $this->view->showLoginError("Username or password is invalud. Please try again.");
               }
           }


       }

       public function logout()
       {
           if ($this->loginModel->logout())
 $this->view->showLoginPage ();
       }
   }
?>

 

model/database.php:

<?php
   class DatabaseModel
   {
       public $connection;


       public function __construct()
       {
       }

       public function connectToDatabase()
       {
           require_once('includes/config/config.inc.php');
           $connection = mysql_connect(HOSTNAME, USERNAME, PASSWORD);
           if (!$connection)
               die('Could not connect: ' . mysql_error());
           $database = mysql_select_db(DATABASE, $connection);
           if (!$database)
               die('Could not select database: ' . mysql_error());
           $this->connection = $connection;
           return $connection;
       }

       public function disconnectDatabase()
       {
//            mysql_close($this->connection);
       }

public function getConnection()
{
    return $this->connection;
}
   }
?>

 

model/login.php:

<?php
   class LoginModel
   {
public $connection;

       public function __construct($databaseModel)
       {
    $this->connection = $databaseModel->getConnection();
       }


       public function checkLogin()
       {
           if (isset($_COOKIE['login']))
           {
               if ($_COOKIE['login'])
               {
                   return true;
               }
               else
               {
                   return false;
               }
           }
       }
/*        
       public function inputs($fieldNames, $data)
       {
    foreach ($fieldNames as $field)
    {
               echo "data: " . $data[$field] . ", field: " . $field . "<br />";
    }
       }
*/
       public function login()
       {
           $sql = mysql_query("select salt, password from user where username = '" . $_POST['username'] . "'", $this->connection);
           if (mysql_num_rows($sql) > 0)
           {
               $sqlRow = mysql_fetch_assoc($sql);
               if (sha1($_POST['password'] . $sqlRow['salt']) == $sqlRow['password'])
               {
                   setcookie("login", true, $this->getLoginCookieExpiry());
                   return true;
               }
               else
                   return false;
           }
           else
               return false;
       }

       public function logout()
       {
           setcookie("login",false,time()-10);
    return true;
       }

       public function getLoginCookieExpiry()
       {
           return mktime(23, 59, 59, date("m"), date("d"), date("y"));
       }
   }
?>

 

view/login.php:

<?php
   class LoginView
   { 
       protected $model; 
       protected $controller; 


       public function __construct(LoginController $controller, DatabaseModel $model)
       { 
           $this->controller = $controller; 
           $this->model = $model;
       } 


       public function showLoginError($error)
       {
           return $error;
       }

       public function loginSuccess()
       {
           header("location: home2.php");
       }

       public function showLoginPage()
       {
           header("location: mvctest.php");
       }
   }
?>

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.