2016-04-12 63 views
0

我在學習PhP和SQL時只是構建一個小應用程序。現在,我被困在讓我的一個類的實例化被保留下來,而不必在每次頁面加載時都保持實例化。我有兩個表UsersRepresentatives。登錄函數找出他們的表並記錄它們,然後創建該類的新實例。當構建這個類時,它會執行一些操作並將它們重定向到適當的模塊。看起來我能夠實例化類,但是第二個我更改爲新文件,$current_user變爲空。我不想保持恢復它,因爲最終在__construct()我想存儲一些用戶信息作爲私有變量,所以我只想安置$current_user一次,並在整個項目中使用它。再次,這種新的,所以我希望我措辭這個正確的。現在我只有Administrator這個課程建成了(但我現在只是爲了解決這個問題而建立的)。這裏是我的課程和登錄功能所在的地方(我的所有網頁上這個文件是require_once())。PHP - 在整個目錄中保留類的實例化

require_once('functions.php'); 
// Define Database Constants 
define("DB_SERVER", "localhost"); 
define("DB_USER", "root"); 
define("DB_PASS", "root"); 
define("DB_NAME", "livelab"); 
if(empty($current_user)){ 
    $current_user; 
} 
function login_user($username, $password){ 
    global $current_user; 
    $connection = mysqli_connect(DB_SERVER, DB_USER, DB_PASS, DB_NAME); 
    $sql="SELECT 'Users' AS tableName, userId as id, username as username, password as password FROM Users WHERE username='{$username}' UNION SELECT 'Representatives' as tableName, repId as id, username as username, password as password FROM Representatives WHERE username='{$username}'"; 
    $result = mysqli_query($connection, $sql); 
    $user = mysqli_fetch_array($result); 
    if(!$user){ 
    header('Location:' . './index.php'); 
    }else{ 
    if($password == $user["password"]){ 
     mysqli_close($connection); 
     switch($user["tableName"]) { 
     case 'Users': 
      $current_user = new Administrator(); 
      break; 
     case 'Representatives': 
      $current_user = new Representative(); 
      break; 
     } 
    } 
    } 
} 

class Administrator{ 
    private $connection; 
    private $user_table = 'Users'; 
    private $user_id = 2; // I have this as a set value for test purposes right now 
    private $module = './mod-administrator/'; 
    private $current_cookie; 

//public vars 
public $test = "hello world"; 

    function __construct(){ 
    $this->open_connection(); 
    if(!session_id()) : session_start(); endif; 
    $this->current_cookie = mysqli_real_escape_string($this->connection, hash_password(uniqid())); 
    setcookie('login_token', $this->current_cookie, time() + 60, "/"); 
    mysqli_query($this->connection, "UPDATE " . $this->user_table . " SET cookieHash='" . $this->current_cookie . "' WHERE userId='" . $this->user_id . "'"); 
    header('Location:' . $this->module); 
    } 
    // The function that opens our connection to our DB 
    private function open_connection(){ 
    $this->connection = mysqli_connect(DB_SERVER, DB_USER, DB_PASS, DB_NAME); 
    if(mysqli_connect_errno()){ 
     die("Database connection failed: " . mysqli_connect_error() . " (" . mysqli_connect_errno() . ") "); 
    } 
    } 
} 
+4

每個*請求*是獨立處理的;當你「改變文件」(即加載*新的URL *)時,以前的所有狀態都消失了。 – deceze

+2

您可以在SESSION中的請求之間維護數據;如果你有類中的db連接資源之類的東西,這些不能被維護,並且需要重新建立每個請求 –

+0

或使用像Symfony這樣的框架並將你的類聲明爲服務。 – DevDonkey

回答

1

要保留的對象,或與此有關的任何變量的狀態,你需要把它保存$_SESSION陣列英寸存儲在那裏的值將在整個會話中可用,直到用戶註銷或會話超時。

session_start(); 
$_SESSION['current_user'] = serialize($current_user); 

您或許已經註冊serialize。要將對象存儲在會話中,需要序列化它們,因爲它們是複雜的數據結構而不是原始值。

要訪問你需要做相反的對象以前的狀態:

session_start(); 
$current_user = unserialize($_SESSION['current_user']); 

我建議閱讀的PHP文件中的一些相關信息sessions

+0

存儲在會話中的值將被自動序列化/非序列化 –

2

基本概述:您目前對軟件使用了更爲程序化的編程方法,這會降低流暢移動數據的能力。我建議在這個項目中採用更加面向對象的方法,並首先設計一些代表用戶的東西。

數據庫層次:

Users 
    - User_Id (int) Primary Key 
    - Username (varchar) Primary Key 
    - Salt (varchar) Primary Key 
    - Password (varchar) 
    - Login_Key (varchar) Primary Key 
    - Group_Id (int) 
    - Ect... 

Usergroups 
    - Group_Id (int) Primary Key 
    - Admin_Access (bool) 
    - Ect... 

程序的體系結構:

Object 
    - Database 
    - User 
    - Group Enumeration 

您的基礎架構的一個例子:

class User 
{ 
    public $Username; 
    public $Email; 
    public $Group; 
    public function __construct($u,$e,$g = "Registered") 
    { 
     $this->Group = (new UserEnum($g))->GetValue(); 
     $this->Email = $e; 
     $this->Username = $u; 
    } 
    public function GenerateUser() 
    { 
     // Connect to the Database 
     // See if the user exist 
     // Handle it and upload the user 
    } 
} 

class UserEnum 
{ 
    public function __construct($c) 
    { 
     private $Value; 
     switch ($c) 
     { 
      case "Admin": $this->Value = 1; break; 
      case "Moderator": $this->Value = 2; break; 
      default: $this->Value = 3; break; 
     } 
    } 
    public function GetValue() { return $this->Value; } 
} 

用法可能是這樣的:

(new User($_POST['name'],$_POST['email'],$_POST['group']))->GenerateUser(); 

採取更面向對象的方法來項目允許您使用通過出您的項目相同的數據,而不必defineglobal大部分東西。以一個人爲例,每個人都有一個名字。在Object內部,您可以通過爲對象指定一個屬性,然後使用Object作爲Person來指定對象。即:$People = array(new Person('Bob'), new Person('Jimmy')); - 這允許更動態的方法,您可以通過構造函數方法傳遞名稱,並輕鬆地向人員添加更多屬性,而無需編輯大量代碼。

編輯:我會建議增加某種軟件的初始化,以確定用戶是否登錄或沒有,像這樣:

// TODO: Create a Settings Object and Controls Object 
session_start(); 
if (!isset ($_SESSION[$Settings->CookieName])): 
    $Settings->UserControls->CanPost = false; 
    // Ect... 
endif; 

編輯:另外請注意,您的目錄設置很重要,應該在每個頁面上以相同的方式加載狀態,即在每個文件中使用上述初始化文件。