Fatal error: Call to undefined method stdClass::_setSession() on line 58 - php

I am relatively new to PHP and am building the log-in portion of my website. I have attempted to get the code to work for to no avail and have become extremely frusturated. When I submit a valid username & password I get the error above
Fatal Error: Call to undefined method stdClass::_setSession() on line 58
I have tested the query separately from the rest of the code and fed the variables as they would be fed from the form (i.e. $User= "..." & $Pass="...") and the auth passes. Also, data not present in the database does not find a user (verified by the php logs).
I have done extensive searches on this error and I can't seem to make any of the answers I've found fit this instance (See additional info below for a few of the things I've tried that made sense to me). I have included the relevant file below. Thank you in advance for any help you provide!
Additional Info:
I have tried to remove the "new stdClass" definition for $This which creates the following error: "Warning: Creating default object from empty value" referring to the first $This encountered.
I have tried to change the stdClass definition to "User" and receive the following error: "Fatal error: Maximum function nesting level of '100' reached, aborting!" referring to the "new User" line.
Relevant File:
class User {
public $Id;
public $Email;
public $FirstName;
public $LastName;
public $Address;
public $City;
public $State;
public $Zip;
public $Phone;
public $PhoneType;
public $IsLoggedIn = false;
function __construct() {
if (session_id() == "" || !isset($_SESSION)) {
session_start();
}
$_SESSION['IsLoggedIn'] = false;
if (!isset($This)) {$This = new stdClass();}
$This->IsLoggedIn = false;
if (isset($_SESSION['IsLoggedIn']) && $_SESSION['IsLoggedIn']== true) {
$This->_initUser();
}
} //end __construct
public function authenticate($User,$Pass) {
$mysqli = new mysqli(DBHOST,DBUSER,DBPASS,DB);
if ($mysqli->connect_errno){
error_log("Cannot connect to MySQL: " .$mysqli->connect_error);
return false;
}
$hasher= new PasswordHash(8, false);
$SafeUser = $mysqli->real_escape_string($User);
$SafeUser = strtolower($SafeUser);
$IncomingPassword = $mysqli->real_escape_string($Pass);
$Stored_hash= "*";
$Query = "SELECT * FROM donors";
$QueryUser = $mysqli->query($Query);
while ($FindUserRow = $QueryUser->fetch_array()){
if ($FindUserRow['Email']== $SafeUser){
$Stored_hash = $FindUserRow['Password'];
if ($hasher->CheckPassword($IncomingPassword, $Stored_hash)) {
$Check = 'Authentication succeeded';}
else { error_log("Passwords for {$User} don't match");
$Check = 'Authentication failed';
return false;}
if (!isset($This)) {$This = new stdClass();}
$This->Id = $FindUserRow['Id'];
$This->Email = $FindUserRow['Email'];
$This->FirstName = $FindUserRow['First_Name'];
$This->LastName = $FindUserRow['Last_Name'];
$This->Address = $FindUserRow['Street'];
$This->City = $FindUserRow['City'];
$This->Zip = $FindUserRow['Zip'];
$This->State = $FindUserRow['State'];
$This->Phone = $FindUserRow['Phone'];
$This->PhoneType = $FindUserRow['Phone_Type'];
$This->IsLoggedIn = true;
$This->_setSession();
return true;}
else{
error_log("Cannot retrieve account for {$User}");
return false;}}
} //end function authenticate
private function _setSession() {
if (session_id() == '' || !isset($_SESSION)) {
session_start();
}
$_SESSION['Id'] = $This->Id;
$_SESSION['Email'] = $This->Email;
$_SESSION['FirstName'] = $This->FirstName;
$_SESSION['LastName'] = $This->LastName;
$_SESSION['Address'] = $This->Address;
$_SESSION['City'] = $This->City;
$_SESSION['Zip'] = $This->Zip;
$_SESSION['State'] = $This->State;
$_SESSION['Phone'] = $This->Phone;
$_SESSION['PhoneType'] = $This->PhoneType;
$_SESSION['IsLoggedIn'] = $This->IsLoggedIn;
} //end function setSession
private function _initUser() {
if (session_id() == '' || !isset($_SESSION)) {
session_start();
}
$This->Id = $_SESSION['Id'];
$This->Email = $_SESSION['Email'];
$This->FirstName = $_SESSION['FirstName'];
$This->LastName = $_SESSION['LastName'];
$This->Address = $_SESSION['Address'];
$This->City = $_SESSION['City'];
$This->Zip = $_SESSION['Zip'];
$This->State = $_SESSION['State'];
$This->Phone = $_SESSION['Phone'];
$This->PhoneType = $_SESSION['PhoneType'];
$This->IsLoggedIn = $_SESSION['IsLoggedIn'];
} //end function initUser

You have made it extra complicated. bad syntax if (!isset($This)) {$This = new stdClass();} this one is wrong practice. $this with lowercase t is something i.e. default object of the current class.
You are trying to overwrite object of User ($this) with stdClass, so parser is taking _setSession() a member method of stdClass instead of User and hence it is undefined by obvious. Try removing the bad syntax and use $this->_setSession() and replace $This to $this for better understanding.

Related

session store only one item in array

I'm a new in php, I have a sign up form and I want to store users registered in an array or JSON,
I built user class and when I register a new user I want to add it into this array or JSON, but session array accept only one user in it and when I adding new user session removing the old one and store the new one!
This is my code:
class User
{
private $id;
private $first_name;
private $last_name;
private $email;
private $password;
public function register($id, $firstName, $lastName, $email, $password)
{
$this->id = $id;
$this->first_name = stripslashes($firstName);
$this->last_name = stripslashes($lastName);
$this->email = $email;
$this->password = password_hash($password, PASSWORD_DEFAULT);
}
}
class DB
{
public $users;
public function __construct()
{
$this->users = [];
}
}
<?php
$counter = 0;
$_SESSION['usersDB'] = new DB;
if (isset($_POST['submit'])) {
$firstName = $_POST['firstName'];
$lastName = $_POST['lastName'];
$email = $_POST['email'];
$password = $_POST['password'];
$user = new User;
$user->register(++$counter, $firstName, $lastName, $email, $password);
array_push($_SESSION['usersDB']->users, $user);
}
echo '<pre>';
var_dump($_SESSION['usersDB']);
echo '</pre>';
?>
What I should do to sole this and store all users in one place?
You're replacing the session variable with new DB each time you run the script. You shouldn't do that if the session variable is already set.
if (!isset($_SESSION['userdDB'])) {
$_SESSION['usersDB'] = new DB;
}
Also, $counter will always be 1, since you're setting $counter = 0; at the beginning of the script. You could save this in a session variable, but there isn't really a need. You can just use:
$counter = count($_SESSION['usersDB']->users);
I'm not really sure this will do what you really want. Every browser session has its own session variables, so each user will just have a list of users that they have registered. Session variables are also temporary, so it's not a good way to keep a permanent list of registered users.
The right way to keep a permanent list of users is in a database on the server.
using cookies with serialize and unserialize function
user.php
<?php
class User
{
public static $cnt = 0;
private $id;
private $name;
public function __construct($name='')
{
self::$cnt++;
$this->id = self::$cnt;
$this->name = stripslashes($name);
}
public function __get($name){
return $this->$name;
}
public function __set($name,$val){
$this->$name = stripslashes($val);
}
public function __toString(){
return 'user('.$this->id.", ".$this->name.")";
}
}
?>
db.php
<?php
class DB
{
public $users = [];
public function __construct()
{
$this->users = [];
}
public function __toString()
{
$str = "<ul>";
foreach ($this->users as $user)
$str .="<li>".$user."</li>";
$str .= "</ul>";
return $str;
}
}
?>
index.php
<?php
require_once('user.php');
$user1 = new User('Steve');
$user2 = new User('Everst');
require_once('db.php');
$databse = new DB();
$databse->users[] = $user1;
$databse->users[] = $user2;
setcookie('users', serialize($databse),time() + 3600,"/","",0);
echo $_COOKIE['users'];
?>
users.php
<?php
require_once('db.php');
require_once('user.php');
$databse = unserialize($_COOKIE['users']);
echo $databse;
?>
using session with JSON
implements the interface JsonSerializable
override the method jsonSerialize
user.php
<?php
class User implements JsonSerializable
{
public static $cnt = 0;
private $id;
private $name;
public function __construct($name='')
{
self::$cnt++;
$this->id = self::$cnt;
$this->name = stripslashes($name);
}
public function __get($name){
return $this->$name;
}
public function __set($name,$val){
$this->$name = stripslashes($val);
}
public function __toString(){
return 'user('.$this->id.", ".$this->name.")";
}
public function jsonSerialize() {
return array(
'id' => $this->id,
'name' => $this->name
);
}
}
?>
index.php
<?php
session_start();
include('user.php');
include('db.php');
$user1 = new User('Steve');
$user2 = new User('Everst');
$databse = new DB();
$databse->users[] = $user1;
$databse->users[] = $user2;
$_SESSION['database'] = JSON_encode($databse);//{"users":[{"id":1,"name":"Steve"},{"id":2,"name":"Everst"}]}
?>
users.php
<?php
session_start();
$databse = json_decode($_SESSION['database']);
foreach ($databse->users as $user)
echo $user->id." - ".$user->name."<BR>";
?>

How to dynamically display user name from the database after log in?

I need to dynamically display user name from logged in user in my OOP PHP project. I can display it when I type right id from the database but it shows error when I try to define property $user_id in my function find_by_id. I need help on how to define $user_id variable. Here is my code:
index.php
<?php $user = User::find_by_id($user_id); ?>
<h1>Hello, <?php echo $user->username; ?></h1>
user.php
<?php
class User
{
protected static $db_table = "users";
public $id;
public $username;
public $password;
public $first_name;
public $last_name;
private function has_the_attribute($the_attribute)
{
$object_properties = get_object_vars($this);
return array_key_exists($the_attribute, $object_properties);
}
public static function instantation($the_record)
{
$the_object = new self;
foreach ($the_record as $the_attribute => $value) {
if ($the_object->has_the_attribute($the_attribute)) {
$the_object->$the_attribute = $value;
}
}
return $the_object;
}
public static function find_this_query($sql)
{
global $database;
$result_set = $database->query($sql);
$the_object_array = [];
while ($row = mysqli_fetch_array($result_set)) {
$the_object_array[] = self::instantation($row);
}
return $the_object_array;
}
public static function find_all()
{
return self::find_this_query("SELECT * FROM " . static::$db_table . " ");
}
public static function find_by_id($user_id)
{
global $database;
$the_result_array = self::find_this_query("SELECT * FROM " . self::$db_table . " WHERE id = $user_id");
return !empty($the_result_array) ? array_shift($the_result_array) : false;
}
public static function verify_user($username, $password)
{
global $database;
$username = $database->escape_string($username);
$password = $database->escape_string($password);
$sql = "SELECT * FROM " . self::$db_table . " WHERE ";
$sql .= "username = '{$username}' ";
$sql .= "AND password = '{$password}'";
$the_result_array = self::find_this_query($sql);
return !empty($the_result_array) ? array_shift($the_result_array) : false;
}
}
$user = new User();
session.php
<?php
class Session
{
private $signed_in = false;
public $user_id;
public $message;
public function __construct()
{
session_start();
$this->check_the_login();
$this->check_message();
}
public function login($user)
{
if ($user) {
$this->user_id = $_SESSION['user_id'] = $user->id;
$this->signed_in = true;
}
}
public function logout()
{
unset($_SESSION['user_id']);
unset($this->user_id);
$this->signed_in = false;
}
private function check_the_login()
{
if (isset($_SESSION['user_id'])) {
$this->user_id = $_SESSION['user_id'];
$this->signed_in = true;
} else {
unset($this->user_id);
$this->signed_in = false;
}
}
public function is_signed_in()
{
return $this->signed_in;
}
public function message($msg="")
{
if (!empty($msg)) {
$_SESSION['message'] = $msg;
} else {
return $this->message;
}
}
public function check_message()
{
if (isset($_SESSION['message'])) {
$this->message = $_SESSION['message'];
unset($_SESSION['message']);
} else {
$this->message = "";
}
}
}
$session = new Session();
For the sake of marking this as accepted, what you need to do is actually pass the user ID of the and not just an uninitialised variable, if your instance you are storing it in the session so I presume it would be:
<?php $user = User::find_by_id($_SESSION['user_id']); ?>
Note: To make your templating cleaner, you can use the shorthand syntax for echo:
<h1>Hello, <?= $user->username; ?></h1>
Another thing to note is that you have built a Session class, however you are still for some reason accessing the data through $_SESSION which doesn't make sense, make some setters / getters for it. Finally, sessions are something that you'll be using a lot therefore it would be worth making that class static.
Reading Material
echo

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 Construct Usage

I'm learning how to use classes properly... I'm looking at usercake and most of it makes sense, however I'm not sure what the __construct function is doing. I understand it gets called when you create the class... i.e. $loggedInUser = new loggedInUser();
What does the stuff below do and why do I need it?
function __construct($user, $display, $title, $pass, $email)
{
//Used for display only
$this->displayname = $display;
//Sanitize
$this->clean_email = sanitize($email);
$this->clean_password = trim($pass);
$this->username = sanitize($user);
$this->title = sanitize($title);
if(usernameExists($this->username))
{
$this->username_taken = true;
}
else if(displayNameExists($this->displayname))
{
$this->displayname_taken = true;
}
else if(emailExists($this->clean_email))
{
$this->email_taken = true;
}
else
{
//No problems have been found.
$this->status = true;
}
}
Edit: Here is how the class gets called:
$loggedInUser = new loggedInUser();
$loggedInUser->email = $userdetails["email"];
$loggedInUser->user_id = $userdetails["id"];
$loggedInUser->hash_pw = $userdetails["password"];
$loggedInUser->title = $userdetails["title"];
$loggedInUser->displayname = $userdetails["display_name"];
$loggedInUser->username = $userdetails["user_name"];
$loggedInUser->alerts = array();
It is the constructor function. When you create an instance of that class your constructor function is run.
For example, with your constructor (I don't know your class name).
$class = new MyClass("jdoe", "John Doe", "Standard User", "Passw0rd!","jdoe#example.com");`
This will create a new MyClass and store it in $class.
As for its purpose, it lets you initialize the object to a starting state of some kind. You can populate properties, set default values, or just do nothing. It is really application specific.
EDIT (in response to OP's edit)
I would really suggest keeping your object properties either protected or private and use setter/getters to access that data. You are giving public access to your objects properties, which isn't bad, but it can lead to accidentally changing something you didn't mean to change. Maybe you should consider something like this:
<?php
class LoggedInUser
{
private $id;
private $username;
private $password;
private $displayname;
private $email;
private $title;
public function __construct($id, $username, $password, $displayname, $email, $title)
{
$this->setID($id);
$this->setUsername($username);
$this->setPassword($password);
$this->setDisplayName($displayname);
$this->setEmail($email);
$this->title($title);
}
public function sanitize($var)
{
//Sanitize $var and then...
return $var;
}
public function setID($num)
{
$this->id = $this->sanitize($num);
}
public function setUsername($string)
{
$this->username = $this->sanitize($string);
}
//Keep adding other "set" methods.
}
?>
Then to use this you would do something like:
$loggedin = new LoggedInUser( "arg1", "arg2", "etc..." );
Now your object is setup with the starting state. If you need to change a property later you can always do:
$loggedin->setTitle("Correct Title");
Make sure you create functions to return your properties as well. In the example above your properties are private so a call to $loggedin->title would generate an error in PHP
// Set construct function which will run when your class is called
function __construct($user, $display, $title, $pass, $email)
{
// Sets display name
$this->displayname = $display;
// Sanitizing user inputted data (See SQL injection/XSS attacks)
$this->clean_email = sanitize($email);
$this->clean_password = trim($pass);
$this->username = sanitize($user);
$this->title = sanitize($title);
// Check if any duplicates of the user inputted data exist already in the database
// If any of these checks return true, the status wont be set to true, and further code wont be ran
if(usernameExists($this->username))
{
$this->username_taken = true;
}
else if(displayNameExists($this->displayname))
{
$this->displayname_taken = true;
}
else if(emailExists($this->clean_email))
{
$this->email_taken = true;
}
else
{
// No duplicate information has been found, set status and continue registration
$this->status = true;
}
}
You need it because initialize the object you create.

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