我有两个类文件:一个名为class.database.php,它仅用于必须在数据库上完成的任何函数(连接,断开连接,查询等)
这是class.database.php:
<?php
class DATABASE
{
public function __construct() {
$this->getConnected();
}
public function getConnected() {
$dbHost = "localhost";
$dbUser = "tysonmoyes";
$dbPassword = "F!lmtrepid";
$db = "tysonmoyes";
$dbConn = new mysqli($dbHost, $dbUser, $dbPassword, $db);
$this->dbConn = $dbConn;
}
function queryDB($queryString) {
return mysqli_query($this->getConnected(), $queryString);
}
public function close() {
mysqli_close($this->connection);
}
}
?>
我的第二个类文件名为class.users.php,它处理用户帐户的所有信息。它看起来像这样:
<?php
include_once('config.php');
class USER
{
private $conn;
// All the variables needed for the user profile.
public $username;
public $userID;
public $password;
public $firstName;
public $lastName;
public $emailAddress;
public $address;
public $city;
public $province;
public $country;
var $myConn;
function __construct($conn){
$this->myConn = $conn;
}
function createNewUser($username, $password) {
// Clean inputs
$username = trim($username);
$password = trim($password);
// Encrypt password
$password = md5($password);
// Check if username already exists
$checkSQL = "SELECT * FROM users WHERE username = '$username'";
$checkResult = $this->myConn->queryDB($checkSQL);
if($checkResult->num_rows > 0) {
$error = "true";
$errorMessage = "This username has already been taken. Please try again";
}
else {
$insertSQL = "INSERT INTO users(username, password) VALUES('$username', '$password')";
//$insertResult = $this->callDB()->query($insertSQL);
// Get the user ID
$userID = $this->insert_id;
// Set the SESSION globals
$_SESSION['username'] = $username;
$_SESSION['userID'] = $userID;
}
}
function login($username, $password) {
$sql = "SELECT * FROM users WHERE username = '$username' && password = '$password'";
$result = $this->conn->query($sql);
$row = $this->conn->fetch_array($result, MYSQL_ASSOC);
$count = $this->conn->num_rows($result);
if ($count == 1) {
// Set Session Variables
$_SESSION['username'] = $username;
$_SESSION['userID'] = $row['userID'];
return true;
}
}
function isLoggedIn() {
if(isset($_SESSION['username'])) {
return true;
}
else {
return false;
}
}
function redirect($url) {
header("Location: $url");
}
function logout() {
session_destroy();
unset($_SESSION['username']);
}
}
?>
正如您所看到的,class.user.php调用&#34; config.php&#34; file,它只是创建一个新的DATABASE和一个新的USER,使用从创建新DATABASE创建的链接:
<?php
// Turn on all error reporting
ERROR_REPORTING(E_ALL);
ini_set('display_errors', 1);
// Start Session
session_start();
// Set error to false, and blank error message
$error = "false";
$errorMessage = "";
// Include Database info
require_once('class.database.php');
$link = new DATABASE();
// Include User info
require_once('class.user.php');
// Create instance for user class
$activeUser = new USER($link);
?>
现在,我想专注于我的查询,因为它们都没有工作,我理解为什么。查询函数位于DATABASE类中,但$ this指向USER类。
我的问题是:如何编写查询以便正确调用DATABASE类。
此外,在任何人提到它之前,是的,我知道md5是禁止的,但是这是针对将使用模拟用户数据的类项目,我们的教授说md5对于这个项目是足够的加密
编辑:为此,我们可以关注class.user.php中的createNewUser函数吗?这就是我目前正在玩的部分。
答案 0 :(得分:3)
为什么,不要建立数据库连接链接。不使用每次getConnected方法来建立与db的新连接?
在DATABASE类的方法close中,$ this-&gt;连接是什么,也许它必须是连接链接。
class DATABASE
{
protected $dbConn; //connection link
protected static $dbHost = "localhost";
protected static $dbUser = "tysonmoyes";
protected static $dbPassword = "F!lmtrepid";
protected static $db = "tysonmoyes";
public function __construct() {
$this->getConnected();
}
public function getConnected() {
//if connection link allready exists return it;
if(isset($this->dbConn)) {
return $this->dbConn;
}
$this->dbConn = new mysqli(self::$dbHost, self::$dbUser, self::$dbPassword, self::$db);
return $this->dbConn;
}
function queryDB($queryString) {
return mysqli_query($this->getConnected(), $queryString);
}
public function close() {
mysqli_close($this->dbConn);
}
}
答案 1 :(得分:2)
我想你忘记了返回db连接链接。
数据库类:
<?php
class DATABASE
{
public function __construct() {
$this->getConnected();
}
public function getConnected() {
$dbHost = "localhost";
$dbUser = "tysonmoyes";
$dbPassword = "F!lmtrepid";
$db = "tysonmoyes";
$dbConn = new mysqli($dbHost, $dbUser, $dbPassword, $db);
$this->dbConn = $dbConn;
return $dbConn;
}
function queryDB($queryString) {
return mysqli_query($this->getConnected(), $queryString);
}
public function close() {
mysqli_close($this->connection);
}
}
?>
答案 2 :(得分:2)
正如我的评论中提到的那样,正如其他人所提到的,最重要的是返回连接。
我个人认为PDO会是一个更好的选择,因为参数设置非常简单,但你可能应该使用mysqli_
,所以我会稍微修改你的设置。这没有经过测试,只记下差异:
<强> /classes/Database.php 强>
<?php
class Database
{
private static $singleton,
$con;
# I LIKE TO RETURN THE SAME INSTANCE OF A CLASS HERE, OPTIONAL
public function __construct()
{
if(!(self::$singleton instanceof Database))
self::$singleton = $this;
return self::$singleton;
}
# I LIKE TO STORE THE CONNECTIONS AND RETURN IT INSTEAD OF POSSIBLY
# CREATING A NEW INSTANCE
public function getConnected()
{
# IF THIS STATIC IS NOT A CONNECTION, MAKE ONE
if(!(self::$con instanceof MySQLi))
self::$con = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
# RETURN THE CONNECTION
return self::$con;
}
public function query($sql)
{
return mysqli_query(self::$con, $sql);
}
public function close()
{
mysqli_close(self::$con);
}
}
<强> /config.php 强>
<?php
# I PERSONALLY LIKE TO USE A CONFIG (PREFS FILE) TO STORE MY DB INFO INCASE IT CHANGES
define('DB_HOST',"localhost");
define('DB_USER',"tysonmoyes");
define('DB_PASS',"F!lmtrepid");
define('DB_NAME',"tysonmoyes");
define('DS',DIRECTORY_SEPARATOR);
# I ALSO LIKE TO STORE PATH CONSTANTS SO IT'S AN EASY AND CONSISTANT WAY TO
# LOCATE/INCLUDE FILES
define('ROOT_DIR',__DIR__);
define('CLASS_DIR',ROOT_DIR.DS.'classes');
# START SESSION
session_start();
# USING AN AUTOLOADER IS A MUST ON CLASSES
spl_autoload_register(function($class) {
if(class_exists($class))
return;
# SHOULD RETURN A PATH LIKE:
# /var/www/domain/httpdocs/myproject/classes/Database.php
# WHEN CALLING $Database = new Database();
$path = str_replace(DS.DS,DS,CLASS_DIR.DS.str_replace("\\",DS,$class)).'.php';
# Presuming the file is named properly (and I have done the path right),
# it would add the class file for you without using include anywhere.
if(is_file($path))
include_once($path);
});
<强> /classes/User.php 强>
<?php
class User
{
private $conn;
# I WOULD SET ALL USER INFO TO AN ARRAY INSTEAD OF IN SEPARATE VARIABLES
private $userData = array();
# I MIGHT HINT AT TYPE HERE
public function __construct(\Database $conn)
{
$this->conn = $conn;
}
public function createNewUser($username, $password)
{
$username = trim($username);
$password = trim($password);
// Encrypt password
$password = password_hash($password);
// Check if username already exists
# SQL INJECTION ISSUE HERE, YOU NEED TO BIND PARAMS HERE
$checkSQL = "SELECT * FROM users WHERE username = '$username'";
$checkResult = $this->conn->query($checkSQL);
if($checkResult->num_rows > 0) {
$error = "true";
$errorMessage = "This username has already been taken. Please try again";
}
else {
# INJECTION ISSUE HERE
$insertSQL = "INSERT INTO users(username, password) VALUES('$username', '$password')";
//$insertResult = $this->conn->query($insertSQL);
// Get the user ID
$userID = $this->conn->getConnected()->insert_id;
// Set the SESSION globals
$_SESSION['username'] = $username;
$_SESSION['userID'] = $userID;
}
}
public function login($username, $password)
{
# YOU SHOULD NOT BE INJECTING HERE. I USE PDO, SO I WON'T
# ATTEMPT A GOOD FIX HERE...BUT A FIX IS REQUIRED
# YOU SHOULD ALSO NOT MATCH PASSWORD HERE, JUST USERNAME
# USE password_verify() TO MATCH HASH
$sql = "SELECT * FROM users WHERE username = '$username'";
$result = $this->conn->query($sql);
$row = $this->conn->getConnected()->fetch_array($result, MYSQL_ASSOC);
# DO A CHECK FIRST THAT THERE IS A ROW RETURNED FOR USERNAME (NOT SHOWN IN MY EXAMPLE...)
# DO THE MATCH HERE
$valid = password_verify($_POST['password'],$row['password']);
if($valid) {
// Set Session Variables
$_SESSION['username'] = $username;
$_SESSION['userID'] = $row['userID'];
return true;
}
}
public function isLoggedIn()
{
if(isset($_SESSION['username'])) {
return true;
}
else {
return false;
}
}
public function redirect($url)
{
header("Location: $url");
# YOU SHOULD EXIT HERE
exit;
}
public function logout()
{
session_destroy();
unset($_SESSION['username']);
# YOU SHOULD PROBABLY REDIRECT HERE TO REFRESH THE SESSION
}
}
<强>的index.php 强>
# INCLUDE THE CONFIG ON ALL PAGES
include(__DIR__.DIRECTORY_SEPARATOR.'config.php');
$Database = new Database();
$User = new User($Database);