How should I design and use an User class? - php

When I worked in procedural PHP programming, I would have a login page, where user's session would be created, and stored. Then, on every page, I just displayed the name of the user and retrieved the information I needed.
But I am helpless, how would you achieve this in object programming?
So, procedural (login.php):
if ( $_POST['password'] != '' && $_POST['username'] != '' ) {
// check if password&username combination exists in database etc.
$_SESSION['user_id'] = $user_id;
$_SESSION['username'] = $username;
}
I assume it would be done like this in OOP:
// include user class
if ( $_POST['password'] != '' && $_POST['username'] != '' ) {
// check if password&username combination exists in database etc.
$user = new User();
$user->id = $userId;
$user->username = $username;
But here is the problem: Where do I create session? And this object is not going to exist outside of this "login.php" page, since I create it there. How do I make this information accessible everywhere?
And how would you get information from the database, using a special class ( let's say PDO ) without putting the queries into the user class?
Thank you very much, I just cannot understand the structure

You would do something along the lines:
class User{
private $id;
private $username;
function __construct($userId, $username) {
$this->$id = $userId;
$this->$username = $username;
}
}
if ( $_POST['password'] != '' && $_POST['username'] != '' ) {
// check if password&username combination exists in database etc.
//......
//Store your session
$_SESSION['user_id'] = $user_id;
$_SESSION['username'] = $username;
//Create user instance
$user = new User($user_id, $username );
}
You can also put your data access layer in the user constructor, that way you just need to worry about storing the id session.
User.php:
class User{
private $id;
private $username, $first_name, $last_name;
function __construct($userId) {
$this->$id = $userId;
//get user data from db using $id
$this->$username = $row['username'];
$this->$first_name = $row['first_name'];
$this->$last_name = $row['last_name'];
}
}
Login.php:
function get_userId($username, $password)
// check if password&username combination exists in database etc.
//then return Id
//......
return $userId
}
Then use the function like the following:
if ( $_POST['password'] != '' && $_POST['username'] != '' ) {
$username = $_POST['username'];
$password = $_POST['password'];
$user_id = get_userId($username, $password);
$_SESSION['user_id'] = $user_id;
}
then you would create the user instance using the id like this:
session_start();
$user_id = $_SESSION['user_id'];
$user = new User($user_id);

Try this you are nearly there
// include user class
session_start();
if ( $_POST['password'] != '' && $_POST['username'] != '' ) {
// check if password&username combination exists in database etc.
$user = new User();
$user->id = $userId;
$user->username = $username;
$_SESSION['user_obj'] = serialize($user);
Then when you want to access it again in another page:
// include user class
session_start();
$user = new User();
if ( isset( $_SESSION['user_obj'] ) {
$user = unserialize($_SESSION['user_obj'];
}

At first you need to use official documentation
For all my experiance I can tell you that only you are decide how to use classes and OOP at all. There are many models and stadarts that gives you some structure but it is personal choices.
But in your case i can suggest to you using an regulary class that will check and store information.
class User {
private $id = null;
private $username = null;
private $isLoggedIn = false;
public function __construct() {
if (isset($_SESSION['userData']) && !empty($_SESSION['userData'])) {
// I want to think that you have more complex check for user session
$this->id = $_SESSION['userData']['userId'];
$this->username = $_SESSION['userData']['username'];
$this->isLoggedIn = true;
}
}
public function auth() {
$_SESSION['userData'] = array()
$result = false;
// Here can be an password check
if ($this->id && $this->username) {
$_SESSION['userData']['userId'] = $this->id;
$_SESSION['userData']['username'] = $this->username ;
$this->isLoggedIn = true;
$result = true;
}
return $result;
}
public function isLoggedIn() {
return $this->isLoggedIn;
}
public function userId($id = null) {
if ($id != null) {
$this->id = $id;
}
return $this->id;
}
public function userName($name = null) {
if ($name != null) {
$this->name = $name;
}
return $this->name;
}
}
And usage for this class will be short and easy
// include user class
session_start();
$user = new User();
if ($user->isLoggedIn()) {
// user is Logged In
} elseif ( $_POST['password'] != '' && $_POST['username'] != '' ) {
// check if password&username combination exists in database etc.
$user->userId($userId);
$user->userName($username);
$user->auth();
} else {
echo 'Auth failed';
die();
}
echo 'Hello, ' . $user->userName();

Related

Building a Login model using PHP PDO and MVC

could use help with a simple code with both PHP and SQL (PDO) :)
Trying to access a table, withdraw 1 row from 1 column with specific details using MVC and then verifying said info, building it and then entering that info into Session storage so that I can validate what "role" and "user" is present at a certain time.
That's my controller
<?php
class PagesController {
public function home() {
$first_name = 'Qwerty';
$last_name = 'Qwerty';
require_once('views/pages/home.php');
}
public $admin_model;
public function __construct() {
$this->admin_model = new Admin();
}
public function login() {
session_start();
$log = $this->admin_model->LoginModel();
if($log == true){
$admin= $this->admin_model->findAdmin($_POST['user'],$_POST['pass']);
if($admin == true){
$_SESSION['user'] = $admin['user'];
print_r($_SESSION);
}
require_once('views/pages/login.php');
}else if($log == false){
echo "There is no existing account with that information. Please try a different account.";
require_once('views/pages/home.php');
}
}
?>
And this is my Admin Model.
<?php
require_once 'connection.php';
class Admin{
public $name;
public $role;
public $phone;
public $email;
public $password;
public $img;
public $id;
public function __construct() {
}
public function LoginModel(){
if(isset($_POST['user'])&&($_POST['pass'])){
$name= $_POST['user'];
$password=$_POST['pass'];
}
else{
$name='NULL#NULL';
$password='NULL';
}
$db = Db::getInstance();
$sql = $db->prepare('SELECT * FROM `admin` WHERE "Name" = "'.$name.'" AND Password = ' . $password .' ');
$sql->execute();
$result = $sql->setFetchMode(PDO::FETCH_ASSOC);
if($result >= 1){
return true;
}else{
return false;
}
}
public function findAdmin($name, $password){
$db = Db::getInstance();
$sql = $db->prepare('SELECT * FROM `admin` WHERE "Name" = "'.$name.'" AND Password = ' . $password .' ');
$sql->execute();
$result = $sql->setFetchMode(PDO::FETCH_ASSOC);
if($result > 0){
return $result;
}
}
}
Now, the first one, the Login() model works, BUT it doesn't matter what $_POST['user'] or $_POST['pass'] I input it always works :/... so it seems my SQL query always returns a true (i'm inputting the same into as found in the table, username "admin" and password "12345" but no matter what information I put in? it works. which is odd..
Second of all I want to "Find" the admin after login in and putting that info into a session that I can verify on every view... any help?...
I think your specific problem is that you're using the return of setFetchMode() as an indicator of whether or not rows were found by the execution. Since its return value is TRUE simply by virtue of it succeeding in setting the fetch mode, you're probably always going to see TRUE returned.
You probably need to do fetchAll() and count the records in the array, if all you want to do as verify that at least one row was returned.

Call to member data on userdata() on a non object

I am getting error
Call to member data on userdata() on a non object
when i am setting the Session $this->session->userdata('userName', $userName);
Login Controller
<?php
class loginController extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->library('session');
}
public function login() {
$this->load->View("template/header");
$this->load->View("login_view");
}
public function AuthenticateUser() {
//Is the UserName and Password values retrieved?
if( isset( $_POST['userName'] ) && isset( $_POST['password'] ) ) {
$this->load->library("UserFactory");
$userName = addslashes($_POST['userName']);
$password = addslashes($_POST['password']);
//Get User details based on UserName and Password
$data = array(
"users" => $this->userfactory->checkLogin($userName, $password)
);
if($data["users"] != null) {
$this->session->userdata('userName', $userName);
}
header('Content-Type: application/json');
echo json_encode( $data["users"] );
}
}
}
?>
Any Idea why this is happening ?
$this->session->userdata()
this use to retrieve data from session.
to set session use this
$this->session->set_userdata('some_name', 'some_value');
Wrong Argument on here
if($data["users"] != null) {
$this->session->userdata('userName', $userName); # retrieving data
}
You trying to access data from session without setting it
Make sure you have loaded $this->load->library('session');
change
if($data["users"] != null) {
$this->session->userdata('userName', $userName);
}
to
if($data["users"] != null) {
$this->session->set_userdata('userName', $userName);
}
More on session read this http://w3code.in/2015/10/session-handling-in-codeigniter/

PHP won't set session to TRUE

I'm trying to create a login system but it doesn't seem to set "Session=true". Please help I'm stuck with this for too long now.
Session starts
Checked all my code
No PHP errors
and No database Errors
Login Page:
if($session->is_logged_in()) {
redirect_to("index.php");
}
if (isset($_POST['submit'])) { // Form has been submitted.
$user_name = trim($_POST['user_name']);
$password = trim($_POST['password']);
// Check database to see if username/password exist.
$found_user = User::authenticate($user_name, $password);
if ($found_user) {
$session->login($found_user);
redirect_to("index.php");
} else {
// username/password combo was not found in the database
$message = "Username/password combination incorrect.";
}
} else { // Form has not been submitted.
$user_name = "";
$password = "";
}
Session Class:
class Session {
private $logged_in=false;
public $user_id;
function __construct() {
session_start();
$this->check_login();
if($this->logged_in) {
// actions to take right away if user is logged in
} else {
// actions to take right away if user is not logged in
}
}
public function is_logged_in() {
return $this->logged_in;
}
public function login($user) {
// database should find user based on username/password
if($user){
$this->user_id = $_SESSION['user_id'] = $user->id;
$this->logged_in = true;
}
}
public function logout() {
unset($_SESSION['user_id']);
unset($this->user_id);
$this->logged_in = false;
}
private function check_login() {
if(isset($_SESSION['user_id'])) {
$this->user_id = $_SESSION['user_id'];
$this->logged_in = true;
} else {
unset($this->user_id);
$this->logged_in = false;
}
}
}
$session = new Session();
index page:
if (!$session->is_logged_in()) { redirect_to("login.php");
Authorize Method:
public static function authenticate($user_name="", $password="") {
global $database;
$user_name = $database->escape_value($user_name);
$password = $database->escape_value($password);
$sql="SELECT * FROM users WHERE user_name='{$user_name}' AND password ='{$password}' LIMIT 1";
$result_array = self::find_by_sql($sql);
return !empty($result_array) ? array_shift($result_array) : false;
}
Change your is_logged_in() function to:
public function is_logged_in() {
$this->check_login();
return $this->logged_in;
}
Otherwise is_logged_in() will always return false on each new request (such as redirecting between pages). By calling check_login() first, it will set the logged_in variable with the value (true or false, dependent on if $_SESSION['user_id'] is set.
EDIT:
I'm sorry, I've overlooked the line in the constructor where you already call $this->check_login();
Another thing is that the authenticate function returns an Array instead of an object. So, change the following:
$this->user_id = $_SESSION['user_id'] = $user->id;
To
$this->user_id = $_SESSION['user_id'] = $user['id'];
Finally I have found the solution to this.
Guess what? It wasn't my codes fault but it was my servers(WAMP 2) fault. So, I uninstalled WAMP 2 and updated to the newer version WAMP 2.5. Solved my problem and no more getting redirect to login page!

PHP OOP - Passing object to function is not working

I have a problem here on PHP OOP. I try to do something that I always do in .NET - pass the whole object to the function. Unfortunately, the script didn't appear to work and when I try to debug (using Netbeans) it stopped here:
$ud = new userdetails($fullname, $email, $contact, $username, $password, $password2);
Can somebody tell me what did I do wrongly? Thanks in advance!
My script:
<?php
include 'class/registration.php';
$fullname = $_POST['fullname'];
$email = $_POST['email'];
$contact = $_POST['contact'];
$username = $_POST['username'];
$password = $_POST['password'];
$password2 = $_POST['password2'];
$ud = new userdetails($fullname, $email, $contact, $username, $password, $password2);
if (registration::checkEmptyField($ud)==true){
$error = "Please don't leave any field empty";
}
userdetail class:
<?php
class userdetails {
protected $_fullname;
protected $_email;
protected $_contact;
protected $_username;
protected $_password;
protected $_password2;
public function __construct($fullname,$email,$contact,$username,$password,$password2) {
$this->_fullname = $fullname;
$this->_email = $email;
$this->_contact = $contact;
$this->_username = $username;
$this->_password = $password;
$this->_password2 = $password2;
}
public function get_fullname() {
return $this->_fullname;
}
public function get_email() {
return $this->_email;
}
public function get_contact() {
return $this->_contact;
}
public function get_username() {
return $this->_username;
}
public function get_password() {
return $this->_password;
}
public function get_password2() {
return $this->_password2;
}
}
registration class:
<?php
class registration {
function checkEmptyField(&$userdetails){
if ($userdetails-> get_fullname == ''){
return true;
}
elseif ($userdetails->get_email == ''){
return true;
}
elseif ($userdetails->get_contact == ''){
return true;
}
elseif ($userdetails->get_username == ''){
return true;
}
elseif ($userdetails->get_password == ''){
return true;
}
elseif ($userdetails->get_password2 == ''){
return true;
}
}
}
You ask for a property, not a method here: $userdetails-> get_fullname
Correct way: $userdetails-> get_fullname()
You should always turn on the error reporting, because this should have been reported by php.
The way you call registration::checkEmptyField() requires it to be declared as static.
<?php
class registration {
static function checkEmptyField(userdetails $userdetails) {
...
}
}
There is no need to prepend $userdetails with &, in PHP the objects are always passed by reference. It's better to use type hinting: prepend the parameter name ($userdetails) with its expected type (class userdetails in this case).

PHP OOP unable to edit class properties

New to PHP and especially OOP.
I have a class User.php which I am using in login.php.
$vars = $user->login($email, $pass)
At the moment I am calling the login method as the above, eventually I am going to call an if statment to validate, etc.
At the moment however, I am trying to connect to the DB, pull some information out and add that information to the properties in my class. I can pull the information out (verified by var_dumps of the objects in method login() (vardump of $results), yet for some reason with my current code I cannot update my class properties.
Here is my code
User.php
<?php
class User {
public $id, $password, $first_name, $last_name;
private $user_level;
protected static $db_fields = array('id', 'first_name', 'last_name', 'pass');
protected static $table_name="users";
public function login($email, $pass) {
global $database;
$sql = "SELECT user_id, first_name, last_name, user_level FROM users WHERE (email='$email' AND pass=SHA1('$pass')) AND active IS NULL LIMIT 1";
$results = self::find_by_sql($sql);
if (!empty($results)) {
$this->setuservars($results);
return array_shift($results);
} else {
return false;
}
// return !empty($results) ? array_shift($results) : false;
}
private function setuservars($uservariables) {
$this->id = $uservariables->id;
$this->first_name = $uservariables->first_name;
$this->last_name = $uservariables->last_name;
$this->user_level = $uservariables->user_level;
}
public static function find_by_sql($sql="") {
global $database;
$results_array = $database->query($sql);
$object_array = array();
while ($row = $results_array->fetch_assoc()) {
$object_array[] = self::instantiate($row);
}
return $object_array;
}
public function mysqli_array_escape($arg1){
global $database;
foreach ($arg1 as $key => $value) {
$arg1[$key] = $database->real_escape_string($value);
}
return $arg1;
}
private static function instantiate($record) {
// Could check that $record exists and is an array
$object = new self;
foreach($record as $attribute=>$value){
if($object->has_attribute($attribute)) {
$object->$attribute = $value;
}
}
return $object;
}
private function has_attribute($attribute) {
return array_key_exists($attribute, $this->attributes());
}
protected function attributes() {
// return an array of attribute names and their values
$attributes = array();
foreach(self::$db_fields as $field) {
if(property_exists($this, $field)) {
$attributes[$field] = $this->$field;
}
}
return $attributes;
}
}
$user = new User();
?>
and here is my login.php (I have edited the if statement with to verify the user logged in successfully, i have replaced with "if (1 == 1) {" statement just to help with debugging code.
if (isset($_POST['submitted'])) {
$postdata = $user->mysqli_array_escape($_POST);
//var_dump($user->results);
if (((!isset($_POST['email'])) || ($_POST['email']) == '') || (!isset($_POST['pass']) || ($_POST['pass']) == '') ) {
//error handling eventually
} else {
$email = $_POST['email'];
$pass = $_POST['pass'];
$vars = $user->login($email, $pass);
echo $vars->first_name;
if (1 == 1) {
echo "you have successfully logged in";
var_dump($user->id);
} else {
echo "not logged in";
}
}
}
Oh and the current error I am receiving is "An error occurred in script 'F:\internet\www\htdocs\blissoop\classes\User.php' on line 26: Trying to get property of non-object
Date/Time: 4-13-2012 05:01:09"
I have resolved this issue with help from this question
here was the code that helped : Get value from Multidimentional Array containing an Object.
I have +1'd the answer which helped.
foreach ($array as $item) {
$userId = $item->user_id;
//do something with the userId for this item
}
I had to loop through the array to be able to get the object's properties.

Categories