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
Related
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>";
?>
When I try to display a username from my logged in user in my project, I get this error Undefined variable: user_id in C:\xampp\htdocs\login1\index.php on line 2
Query Failed!!!You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 . Here is my code:
index.php:
<?php require_once("includes/header.php"); ?>
<?php $user = User::find_user_by_id($user_id); ?>
<?php
if (!$session->is_signed_in()) {
redirect("login.php");
}
?>
<div class="row">
<div class="col-md-12">
<h1>Home</h1>
<h1>Hello, <?php echo $user->username; ?></h1>
</div>
<?php require_once("includes/footer.php"); ?>
user.php:
class User
{
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_users()
{
return self::find_this_query("SELECT * FROM users");
}
public static function find_user_by_id($user_id)
{
global $database;
$the_result_array = self::find_this_query("SELECT * FROM users 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 users 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();
The method -- initially called in index.php -- redirects to another page. The problem here is that variable $logged_in isn't getting assigned a new value... which means that when the variable is used in the other page, it is read as false.
NOTE: The assignment of session 'id' and session 'type' is correct.
class Session {
public $logged_in = false;
public function login($data) {
if ($data) {
$_SESSION['id'] = $data['id'];
$_SESSION['type'] = $data['type'];
$this->logged_in = true;
}
}
}
This is a class and therefore is lost (its properties are lost) at the end of the first scripts execution and then recreated in the second in its initial state.
Classes do not live across executions of the same script or any other script.
If you wish to maintain the objects state, you will have to save the state to a file or maybe the real SESSION so you can re-hydrate the data when the second script starts
session_start();
class Session {
public function login($data) {
if ($data) {
$_SESSION['id'] = $data['id'];
$_SESSION['type'] = $data['type'];
$_SESSION['logged_in'] = true;
}
}
// getter function
public function is_logged_in()
{
// just in case check
if ( isset($_SESSION['logged_in']) ) {
return $_SESSION['logged_in'] == true;
} else {
return false;
}
}
}
Called like this
$s = new Session();
if ( ! $s->is_logged_in() ) {
header('Location: index.php');
exit;
}
To keep it away from the SESSION completely you could
class Session {
public $id;
public $type;
public $logged_in;
public function __construct()
{
if ( file_exists('my_session.txt')) {
$obj = json_decode(file_get_contents('my_session.txt'));
foreach($obj as $prop => $val) {
$this->{$prop} = $val;
}
}
}
public function __destruct()
{
file_put_contents('my_session.txt', json_encode($this));
}
public function login($data) {
if ($data) {
$this->id = $data['id'];
$this->type = $data['type'];
$this->logged_in = true;
}
}
}
$obj = new Session();
$obj->login(array('id'=>99, 'type'=>'TEST'));
print_r($obj);
$obj = null;
echo 'object nulled' . PHP_EOL;
print_r($obj);
echo ' NOTHING should be printed' . PHP_EOL;
echo 'object rehydrated' . PHP_EOL;
$obj = new Session();
print_r($obj);
create another method check_login() to re-assign the values in the new page and call it within __construct()
function __construct(){
$this->check_login();
}
public function check_login(){
if(isset($_SESSION['id']) && isset($_SESSION['type']){
$this->logged_in = true;
} else {
$this->logged_in = false;
}
}
I just can't figure it out.. but i got a feeling the problem is around there when im throwing the exception messages. I got almost the same code in my registration class. There is just give the errors array the messages normaly like $this->errors[] = "some error".
<?php
class class_login
{
private $id;
private $username;
private $password;
private $passmd5;
private $errors;
private $access;
private $login;
private $ltoken;
public function __cunstruct()
{
$this->errors = array();
$this->login = isset($_POST['login'])? 1:0;
$this->access = 0;
$this->ltoken = $_POST['ltoken'];
$this->id = 0;
$this->username = ($this->login)? $this->filter($_POST['lusername']) : $_SESSION['username'];
$this->password = ($this->login)? $this->filter($_POST['lpassword']) : '';
$this->passmd5 = ($this->login)? md5($this->password) : $_SESSION['password'];
}
public function isLoggedIn()
{
($this->login)? $this->verifyPost() : $this->verifySession();
return $this->access;
}
public function filter($var)
{
return preg_replace('/[^a-zA-Z0-9]/','',$var);
}
public function verifyPost()
{
try
{
if(!$this->tokenValid())
throw new Exception('Invalid Form Submission!');
if(!$this->isDataValid())
throw new Exception('Ivalid Form Data!');
if(!$this->verifyDatabase())
throw new Exception('Invalid Username/Password!');
$this->access = 1;
$this->registerSession();
}
catch(Exception $e)
{
$this->errors[] = $e->getMessage();
}
}
public function verifySession()
{
if($this->sessionExist() && $this->verifyDatabase())
$this->access = 1;
}
public function verifyDatabase()
{
include('db_connect.php');
$data = mysql_query("SELECT ID FROM users WHERE username = '($this->username)' AND password = '($this->passmd5)'");
if (mysql_num_rows($data))
{
list($this->id) = #array_values(mysql_fetch_assoc($data));
return true;
}
else
return false;
}
public function isDataValid()
{
return (preg_match('/[^a-zA-Z0-9](5,12)$/', $this->username) && preg_match('/[^a-zA-Z0-9](5,12)$/', $this->password))? 1:0;
}
public function tokenValid()
{
return (!isset($_SESSION['ltoken']) || $this->ltoken != $_SESSION['ltoken'])? 0 : 1;
}
public function registerSession()
{
$_SESSION['ID'] = $this->id;
$_SESSION['username'] = $this->username;
$_SESSION['password'] = $this->passmd5;
}
public function sessionExist()
{
return (isset($_SESSION['username']) && isset($_SESSION['password']))? 1 : 0;
}
public function show_errors()
{
foreach($this->errors as $key=>$value)
echo $value."</br>";
}
}
?>
The constructor is called __construct, not __cunstruct.
I see you are setting $this->errors to an array in your __cunstruct function, but since it is not __construct it may never be set.
You need a associative array for
foreach($this->errors as $key=>$value)
But you have no one. ($this->errors[] = $e->getMessage();)
With out an associative array you must use:
foreach($this->errors as $value)
public function __cunstruct() <------ The error is probably here. It is __construct
{
$this->errors = array();
$this->login = isset($_POST['login'])? 1:0;
$this->access = 0;
$this->ltoken = $_POST['ltoken'];
$this->id = 0;
$this->username = ($this->login)? $this->filter($_POST['lusername']) : $_SESSION['username'];
$this->password = ($this->login)? $this->filter($_POST['lpassword']) : '';
$this->passmd5 = ($this->login)? md5($this->password) : $_SESSION['password'];
}
You have a typo.... _construct and not _construct
I'm having problems with accessing variables from my classes...
class getuser {
public function __construct($id) {
$userquery = "SELECT * FROM users WHERE id = ".$id."";
$userresult = mysql_query($userquery);
$this->user = array();
$idx = 0;
while($user = mysql_fetch_object($userresult)){
$this->user[$idx] = $user;
++$idx;
}
}
}
I'm setting this class in a global 'classes' file, and later on I pass through a user id into the following script:
$u = new getuser($userid);
foreach($u->user as $user){
echo $user->username;
}
I'm hoping that this will give me the name of the user but it's not, where am I going wrong?!
Thanks
please define your users member as public in your class like this
class getuser {
public $user = null;
//...
}
in order to access a class property, you have to declare it public or implement getters and setters (second solution is preferable)
class A {
public $foo;
//class methods
}
$a = new A();
$a->foo = 'whatever';
with getters and setters, one per property
class B {
private $foo2;
public function getFoo2() {
return $this->foo2;
}
public function setFoo2($value) {
$this->foo2 = $value;
}
}
$b = new B();
$b->setFoo2('whatever');
echo $b->getFoo2();
in your example:
class getuser {
private $user;
public function __construct($id) {
$userquery = "SELECT * FROM users WHERE id = ".$id."";
$userresult = mysql_query($userquery);
$this->user = array();
$idx = 0;
while($user = mysql_fetch_object($userresult)){
$this->user[$idx] = $user;
++$idx;
}
}
/* returns the property value */
public function getUser() {
return $this->user;
}
/* sets the property value */
public function setUser($value) {
$this->user = $value;
}
}
$u = new getuser($userid);
$users_list = $u->getUser();
foreach($users_list as $user) {
echo $user->username;
}