我想你會發現,人們會建議對這種事情的框架,但是,如果你要嘗試登錄,您可能希望將腳本更徹底地分離出來,以適應更清晰和更可擴展的代碼。此外,確保在測試站點時(在關閉實時環境中的錯誤報告時),使用ini_set("display_errors",1); error_reporting(E_ALL);
以上的session_start()
來警告頁面上發生的任何錯誤/警告。
這是一個比你有更復雜的代碼,但它應該保護你免受注射。請注意,每個文件的所有文件夾都應與域根相關。另請注意,您需要使用password_hash()
函數將所有密碼存儲在數據庫中。你可以使用其中的一部分,所有這些,都不是這樣,但是如果你確實使用它,請確保查看PHP手冊以瞭解所有這些功能:
/core.processor/classes/ class.DatabaseConfig。PHP
// This is your database. Fill out the credentials in the connect() method
// I use PDO because I think personally it's easier to use
class DatabaseConfig
{
private static $singleton;
public function __construct()
{
if(empty(self::$singleton))
self::$singleton = $this->connect();
return self::$singleton;
}
// This is the method that creates the database connection
public function connect($host = "localhost", $username = "username", $password = "password", $database = "database")
{
// Create connection options
// 1) Make PDO Exception errors, 2) Do real binding 3) By default prefer fetching associative arrays
$opts = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC);
$conn = new PDO('mysql:host='.$host.';dbname='.$database, $username, $password,$opts);
// Send back the database connection. You can use a "utf-8" character setting here as well...
return $conn;
}
}
/core.processor/classes/class.QueryEngine.php
// This is a simple query engine. It allows for binding (or not binding)
class QueryEngine
{
private $results;
private static $singleton;
public function __construct()
{
if(empty(self::$singleton))
self::$singleton = $this;
return self::$singleton;
}
// This method sends queries to your database
public function query($sql = false,$bind = false)
{
$this->results = 0;
// Create database connection
$db = new DatabaseConfig();
// Attempt to connect and fetch data
try {
// Bind or not bind, provided there is a bind array
// This is important to look up!
if(!empty($bind)) {
$query = $db ->connect()
->prepare($sql);
$query->execute($bind);
}
else {
$query = $db ->connect()
->query($sql);
}
$this->results = $query;
}
catch (PDOException $e)
{
die($e->getMessage());
}
return $this;
}
// This method will fetch an the associative array if used with select statement
public function fetch()
{
while($row = $this->results->fetch())
$result[] = $row;
return (!empty($result))? $result : 0;
}
}
/core.processor/classes/class.HeaderProcessor.php
// This class deals with functions that should happen before the page outputs to the browswer
class HeaderProcessor
{
private static $userData;
// This method just sits and waits for actions to happen
// This method should expand with whatever you plan to do in the future
public static function eventListener($array = array())
{
if(isset($array['action'])) {
if($array['action'] == 'login') {
if(self::getLogin($array['username'],$array['password'])) {
if(self::setSession(self::$userData)) {
$_SESSION['password'] = NULL;
}
header("Location: home.php");
exit;
}
}
elseif($array['action'] == 'logout') {
session_destroy();
header("Location: loggedout.php");
exit;
}
}
}
// Process login
private static function getLogin($user,$pass)
{
$query = new QueryEngine();
$getUser = $query ->query("SELECT * FROM `users` WHERE `username` = :0",array($user))
->fetch();
if($getUser == 0)
return false;
self::$userData = $getUser[0];
// Verify the password hash (this is why you need to store your passwords differently in your db
return password_verify($pass,$getUser[0]['password']);
}
// Assign session variables
private static function setSession($userData)
{
$_SESSION = array_filter(array_merge($userData,$_SESSION));
return true;
}
// This can set options for your site, I just threw in timezone
// as well as the class autoloader
public static function initApp($settings = false)
{
$timezone = (!empty($settings['timezone']))? $settings['timezone'] : 'America/Los_Angeles';
include_once(FUNCTIONS_DIR."/function.autoLoader.php");
date_default_timezone_set($timezone);
}
}
/core.processor/functions/function.autoLoader.php
// This function will auto load your classes so you don't have to always
// include files. You could make a similar function to autoload functions
function autoLoader($class)
{
if(class_exists($class))
return true;
if(is_file($include = CLASS_DIR.'/class.'.$class.'.php'))
include_once($include);
}
/config.php
/*** This config is located in the root folder and goes on every page ***/
// Start session
session_start();
// Define common places
define("ROOT_DIR",__DIR__);
define("CLASS_DIR",ROOT_DIR.'/core.processor/classes');
define("FUNCTIONS_DIR",ROOT_DIR.'/core.processor/functions');
// Require the page initializer class
require_once(CLASS_DIR."/class.HeaderProcessor.php");
// Initialize the autoloader for classes
// Load timezone
// You can put any other preset in this method
HeaderProcessor::initApp();
// Here is where you put in events like login, logout, etc...
HeaderProcessor::eventListener($_POST);
// Use this function to help load up classes
spl_autoload_register('autoLoader');
/login.php
<?php
// add in the config file
require(__DIR__."/config.php");
?><!DOCTYPE html>
<html>
<meta charset="UTF-8">
<title>My Login</title>
<head>
</head>
<body>
<form id="loginForm" method="post" action="">
<input name="username" type="text" />
<input name="password" type="password" />
<input name="action" type="hidden" value="login" />
<input type="submit" value="LOGIN" />
</form>
</body>
</html>
你的代碼真的很糟糕,容易受到sql注入 –
你有沒有在所有的瀏覽器嘗試..? –
使用'>'?出於好奇,你從中得到什麼好處? – Rasclatt