PHP类,在另一个PHP文件中使用Query函数

时间:2016-12-02 05:59:49

标签: php mysql

我有两个类文件:一个名为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函数吗?这就是我目前正在玩的部分。

3 个答案:

答案 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);