MYARGS = $MYARGS; // foreach ($this->MYARGS as $k => $v) { // echo $k." ".$v."
"; // } if ($this->performMinimumRequirementsCheck()) { $this->runApplication(); } } /** * Performs a check for minimum requirements to run this application. * Does not run the further application when PHP version is lower than 5.3.7 * Does include the PHP password compatibility library when PHP version lower than 5.5.0 * (this library adds the PHP 5.5 password hashing functions to older versions of PHP) * @return bool Success status of minimum requirements check, default is false */ private function performMinimumRequirementsCheck() { if (version_compare(PHP_VERSION, '5.3.7', '<')) { echo "Sorry, Simple PHP Login does not run on a PHP version older than 5.3.7 !"; } elseif (version_compare(PHP_VERSION, '5.5.0', '<')) { require_once("libraries/password_compatibility_library.php"); return true; } elseif (version_compare(PHP_VERSION, '5.5.0', '>=')) { return true; } // default return return false; } /** * This is basically the controller that handles the entire flow of the application. */ public function runApplication() { // // start the session, always needed! // $this->doStartSession(); /* MOVED TO index.php: session_start() must run before any other text output.*/ // check for possible user interactions (login with session/post data or logout) $this->performUserLoginAction(); // show "page", according to user's login status if ($this->getUserLoginStatus()) { $this->showPageLoggedIn(); } else { $this->showPageLoginForm(); } // } } /** * Creates a PDO database connection (in this case to a SQLite flat-file database) * @return bool Database creation success status, false by default */ private function createDatabaseConnection() { try { $this->db_connection = new PDO($this->db_type . ':' . $this->db_sqlite_path); return true; } catch (PDOException $e) { $this->feedback = "PDO database connection problem: " . $e->getMessage(); } catch (Exception $e) { $this->feedback = "General problem: " . $e->getMessage(); } return false; } /** * Handles the flow of the login/logout process. According to the circumstances, a logout, a login with session * data or a login with post data will be performed */ private function performUserLoginAction() { if (isset($_POST["action"]) && $_POST["action"] == "logout") { $this->doLogout(); } elseif (!empty($_SESSION['user_name']) && ($_SESSION['user_is_logged_in'])) { $this->doLoginWithSessionData(); } elseif (isset($_POST["login"])) { $this->doLoginWithPostData(); } } /** * Simply starts the session. * It's cleaner to put this into a method than writing it directly into runApplication() */ private function doStartSession() { session_start(); } /** * Set a marker (NOTE: is this method necessary ?) */ private function doLoginWithSessionData() { $this->user_is_logged_in = true; // ? } /** * Process flow of login with POST data */ private function doLoginWithPostData() { if ($this->checkLoginFormDataNotEmpty()) { if ($this->createDatabaseConnection()) { $this->checkPasswordCorrectnessAndLogin(); } } } /** * Logs the user out */ private function doLogout() { $_SESSION = array(); session_destroy(); $this->user_is_logged_in = false; $this->feedback = "You were just logged out."; } /** * Validates the login form data, checks if username and password are provided * @return bool Login form data check success state */ private function checkLoginFormDataNotEmpty() { if (!empty($_POST['user_name']) && !empty($_POST['user_password'])) { return true; } elseif (empty($_POST['user_name'])) { $this->feedback = "Username field was empty."; } elseif (empty($_POST['user_password'])) { $this->feedback = "Password field was empty."; } // default return return false; } /** * Checks if user exits, if so: check if provided password matches the one in the database * @return bool User login success status */ private function checkPasswordCorrectnessAndLogin() { // remember: the user can log in with username or email address $sql = 'SELECT user_name, user_email, user_password_hash FROM users WHERE user_name = :user_name OR user_email = :user_name LIMIT 1'; $query = $this->db_connection->prepare($sql); $query->bindValue(':user_name', $_POST['user_name']); $query->execute(); // Btw that's the weird way to get num_rows in PDO with SQLite: // if (count($query->fetchAll(PDO::FETCH_NUM)) == 1) { // Holy! But that's how it is. $result->numRows() works with SQLite pure, but not with SQLite PDO. // This is so crappy, but that's how PDO works. // As there is no numRows() in SQLite/PDO (!!) we have to do it this way: // If you meet the inventor of PDO, punch him. Seriously. $result_row = $query->fetchObject(); if ($result_row) { // using PHP 5.5's password_verify() function to check password if (password_verify($_POST['user_password'], $result_row->user_password_hash)) { // write user data into PHP SESSION [a file on your server] $_SESSION['user_name'] = $result_row->user_name; $_SESSION['user_email'] = $result_row->user_email; $_SESSION['user_is_logged_in'] = true; $this->user_is_logged_in = true; $this->feedback = 'Hello ' . $_SESSION['user_name'] . ', you are logged in.'; return true; } else { $this->feedback = "Wrong password."; } } else { $this->feedback = "This user does not exist."; } // default return return false; } /** * Simply returns the current status of the user's login * @return bool User's login status */ public function getUserLoginStatus() { return $this->user_is_logged_in; } /** * Simple demo-"page" that will be shown when the user is logged in. * In a real application you would probably include an html-template here, but for this extremely simple * demo the "echo" statements are totally okay. */ private function showPageLoggedIn() { if ($this->feedback) { echo $this->feedback . "
"; } // echo 'Hello ' . $_SESSION['user_name'] . ', you are logged in.

'; // echo 'Log out'; echo '
'; echo ''; echo ''; echo ''; echo '
'; } /** * Simple demo-"page" with the login form. * In a real application you would probably include an html-template here, but for this extremely simple * demo the "echo" statements are totally okay. */ private function showPageLoginForm() { // echo '

Login

'; echo '
'; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo '
'; if ($this->feedback) { echo $this->feedback; } echo ''; echo ''; echo ''; echo '
'; echo ' '; echo ''; echo ''; echo '
'; echo ' '; echo ''; echo ''; echo '
'; echo '
'; } } // run the application $application = new OneFileLoginApplication($MYARGS);