0

I'm using Object Oriented Programming to store User values to be used throughout a website. However i'm getting stuck on one particular issue. I'm trying to create a feature within a class that gets the User's values (after they login) to be stored to the Class instantiated. So far all the methods in the Class executes and the session becomes 'Logged-in' which is great. But the values I've tried to obtain from the User is not storing to the attributes within the Class.

class Users {

public $User_ID;     
public $Password;
public $First_name;
public $Surname;
public $Email;
public $User_lvl;

public static function authenticate($Email, $Password) {
global $database;
$sql  = "SELECT * FROM Users ";
$sql .= "WHERE Email = '{$Email}' ";
$sql .= "AND Password = '{$Password}' ";
$sql .= "LIMIT 1";
self::find_by_sql($sql);
$result_array = self::find_by_sql($sql);
    return !empty($result_array) ? array_shift($result_array) : false;
  }


public static function find_by_sql($sql="") {
global $database;
$result_set = $database->query($sql);
$object_array = array();
while ($row = $database->fetch_array($result_set)) {
  $object_array[] = self::instantiate($row);
    }
 return $object_array;
}

public function fetch_array($result_set) {
return mysqli_fetch_array($result_set);
 }

private static function instantiate($row) {
$object = new self;
    foreach($row as $attribute=>$value){
      if($object->has_attribute($attribute)) {
        $object->$attribute = $value;
      }
    }
return $object; 
}

private function has_attribute($attribute) {
  $object_vars = get_object_vars($this);
  return array_key_exists($attribute, $object_vars);
}

Also the class does not seem to become instantiated as a trying to call a non-static function from the Class does not work. So the values aren't being obtained and the class isn't being instantiated. Please could anyone help me with this issue I'd appreciate it very much.

  • Your code is vulnerable to [**SQL injection**](https://en.wikipedia.org/wiki/SQL_injection) attacks. You should use prepared statements with bound parameters, via either [**mysqli**](https://secure.php.net/manual/en/mysqli.prepare.php) or [**PDO**](https://secure.php.net/manual/en/pdo.prepared-statements.php). [**This post**](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) has some good examples. – Alex Howansky Apr 19 '18 at 19:45
  • **Never** store plain text passwords. Instead use [`password_hash()`](http://us3.php.net/manual/en/function.password-hash.php) and [`password_verify()`](http://us3.php.net/manual/en/function.password-verify.php). – Alex Howansky Apr 19 '18 at 19:45
  • Format (indent, for starters) your code properly, ffs. You'll end up with a mess if you don't. – Smuuf Apr 19 '18 at 19:45
  • @AlexH thank you for a quick response. I do store a hash version of passwords with salts stored on a desperate database for security. I just simplified this for the sake of the post. There are sanitations and validations on all user inputed data before it is stored into the database. Does it benefit to also mysqli_escape user values inputted even though all these checks where done before hand? – HarrisonWD Apr 19 '18 at 20:14

2 Answers2

1

I prepare for you OOP classes that you can work with.

  1. Move the global to DBService base class.

  2. Change the self call to user instance.

    class User {
    
        private $userId;
        private $password;
        private $firstName;
        private $surname;
        private $email;
        private $userLevel;
    
        function __construct($userId, $password, $firstName, $surname, $email, $userLevel) {
            $this->userId = $userId;
            $this->password = $password;
            $this->firstName = $firstName;
            $this->surname = $surname;
            $this->email = $email;
            $this->userLevel = $userLevel;
        }
    
        function getUserId() {
            return $this->userId;
        }
    
        function getPassword() {
            return $this->password;
        }
    
        function getFirstName() {
            return $this->firstName;
        }
    
        function getSurname() {
            return $this->surname;
        }
    
        function getEmail() {
            return $this->email;
        }
    
        function getUserLevel() {
            return $this->userLevel;
        }
    
        function setUserId($userId) {
            $this->userId = $userId;
        }
    
        function setPassword($password) {
            $this->password = $password;
        }
    
        function setFirstName($firstName) {
            $this->firstName = $firstName;
        }
    
        function setSurname($surname) {
            $this->surname = $surname;
        }
    
        function setEmail($email) {
            $this->email = $email;
        }
    
        function setUserLevel($userLevel) {
            $this->userLevel = $userLevel;
        }
    
    }
    
    class UserDBServiceImpl extends DBService implements UserDBService {
    
        public function authenticate($Email, $Password) {
            global $database;
            $sql = "SELECT * FROM Users ";
            $sql .= "WHERE Email = '{$Email}' ";
            $sql .= "AND Password = '{$Password}' ";
            $sql .= "LIMIT 1";
            self::find_by_sql($sql);
            $result_array = self::find_by_sql($sql);
            return !empty($result_array) ? array_shift($result_array) : false;
        }
    
        public function find_by_sql($sql = "") {
    
            $result_set = $database->query($sql);
            $object_array = array();
            while ($row = $database->fetch_array($result_set)) {
                $object_array[] = self::instantiate($row);
            }
            return $object_array;
        }
    
        public function fetch_array($result_set) {
            return mysqli_fetch_array($result_set);
        }
    
        private function instantiate($row) {
            $object = new self;
            foreach ($row as $attribute => $value) {
                if ($object->has_attribute($attribute)) {
                    $object->$attribute = $value;
                }
            }
            return $object;
        }
    
        private function has_attribute($attribute) {
            $object_vars = get_object_vars($this);
            return array_key_exists($attribute, $object_vars);
        }
    
    }
    
    class DBService {
    
        private $database = null;
    
        private function init() {
            $this->database = ""; // Create connection to database
        }
    
        protected static function getInstance() {
            if ($database == null)
                init();
            return $database;
        }
    
    }
    
    interface UserDBService {
    
        public function authenticate($Email, $Password);
    
        public function find_by_sql($sql = "");
    
        public function fetch_array($result_set);
    
        function instantiate($row);
    
        function has_attribute($attribute);
    }
    
4EACH
  • 2,132
  • 4
  • 20
  • 28
  • array ( 0 => '1', 'User_ID' => '1', 1 => 'storedpassword', 'Password' => 'storedpassword', 2 => 'Survivor', 'First_name' => 'Survivor', 3 => '28', 'Surname' => '28', 4 => 'Survivor28@gmail.com', 'Email' => 'Survivor28@gmail.com', 5 => 'User', 'User_lvl' => 'User', )array ( 0 => '1', 'User_ID' => '1', 1 => 'storedpassword', 'Password' => 'storedpassword', 2 => 'Survivor', 'First_name' => 'Survivor', 3 => '28', 'Surname' => '28', 4 => 'Survivor28@gmail.com', 'Email' => 'Survivor28@gmail.com', 5 => 'User', 'User_lvl' => 'User', ) – HarrisonWD Apr 19 '18 at 23:15
  • private static function instantiate($row) { $object = new self; // var_export($row); foreach($row as $attribute=>$value){ if($object->property_exists($object, $attribute)) { $object->$attribute = $value; } } return $object; } – HarrisonWD Apr 19 '18 at 23:37
-1

Use the standard property_exists() instead of has_attribute(). Also, use mysqli_fetch_assoc insted of mysqli_fetch_array to prevent getting mixed numeric/associative keys.

Samvel Aleqsanyan
  • 2,812
  • 4
  • 20
  • 28