我正在构建一个小应用程序,因为我学习了PhP和SQL。现在,我不得不保留我的一个类的实例化,而不必在每次页面加载时都保持实例化。我有两个表Users
和Representatives
。登录功能找出他们的表并将其登录,然后创建该类的新实例。当构造该类时,它会执行一些操作并将它们重定向到适当的模块。似乎我能够实例化该类,但是第二次我改为新文件,$current_user
变为空。我不想继续恢复它,因为最终在__construct()
上我想将一些用户信息存储为私有变量,所以我只想设置一次$current_user
并在整个项目中使用它。再一次,对此有点新意,所以我希望我措辞正确。现在我只是建立了Administrator
类(但是当我解决这个问题时,我现在只为该表构建)。这是我的类和登录功能所在的位置(此文件在我的所有页面上都是require_once()
)。
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() . " ) ");
}
}
}
答案 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();
对项目采用更多OOP方法,您可以在整个项目中使用相同的数据,而无需
define
或global
。以一个人为例,每个人都有一个名字。在Object中,您可以通过为其指定属性来指定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;
编辑:另请注意,您的目录设置很重要,应该在每个页面上以相同的方式加载该状态,即使用每个文件中的上述初始化文件。
答案 1 :(得分:1)
要保留对象的状态或任何变量,您需要将其保存在$_SESSION
数组中。您存储在其中的值将在整个会话中可用,直到用户注销或会话超时。
session_start();
$_SESSION['current_user'] = serialize($current_user);
您可能已经注意到serialize
。要在会话中存储对象,需要对它们进行序列化,因为它们是复杂的数据结构而不是原始值。
要访问对象的先前状态,您需要执行相反的操作:
session_start();
$current_user = unserialize($_SESSION['current_user']);
我建议在PHP文档中阅读有关sessions的一些信息。