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.
Related
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
This question already has answers here:
Reference - What does this error mean in PHP?
(38 answers)
Closed 5 years ago.
I get the above error even though the data() method is defined in my user class. I want to be able to echo the user's details on the index page.
The index.php code below where I instantiated the user class
<?php
$user = new User();
echo $user->data()->email;
The user class below: User.php
<?php
class User {
private $_db,
$_data,
$_sessionName,
$_details,
$_isLoggedIn;
public function __construct($user = null) {
$this->_db = DB::getInstance();
$this->_sessionName = Config::get('session/session_name');
if (!$user) {
if (Session::exists($this->_sessionName)) {
$user = Session::get($this->_sessionName);
if ($this->find($user)) {
$this->_isLoggedIn = true;
} else {
// process logout
}
}
} else {
$this->find($user);
}
}
public function create($fields = array()) {
if (!$this->_db->query("INSERT INTO users (firstname, othernames, surname, email, grup, password, salt, hash, joined) VALUES (?,?,?,?,?,?,?,?,?)", $fields)) {
throw new Exception('Could not register user');
}
}
public function find($user=null) {
if ($user) {
$field = (is_numeric($user)) ? 'id' : 'email';
$data = $this->_db->query("SELECT * FROM users WHERE email=?", array($user));
}
if ($data->count()) {
$this->_data = $data->first();
return true;
}
return false;
}
public function login($email = null, $password = null) {
$user = $this->find($email);
if ($user) {
//print_r($this->_data);
if ($this->data()->password === Hash::make($password, $this->data()->salt)) {
if (!is_object($this->data())) {
die('ooo not objj');
} else {
echo "its obj";
}
Session::put($this->_sessionName, $this->data()->id);
return true;
}
}
return false;
}
public function data() {
return $this->_data;
}
public function isLoggedIn() {
return $this->_isLoggedIn;
}
public function details() {
return $this->_details;
}
}
The data() method is defined in the user class. Can figure where the error is coming from...
Try this in the constructor function
$this->_data = $this->_db->query(.....);
or
$this->_data = []; //empty array if you are expection an array
Its because data is not an instance of User object
The constructor function is the to initialize all the instance variables
A constructor creates an Object of the class that it is in by initializing all the instance variables and creating a place in memory to hold the Object.
EDIT I've updated the question with actual code. Turns out it was not a scope issue but a stupid mistake on my part. While testing that all value were good I was really setting them to empty.
After reading the answer below I realized I have the scope figured out but had a typo in the code.
Sorry
<?php
abstract class PHPFoo_XYZ
{
protected $_postData = array();
public function processXYZ(array $postData)
{
$this->_postData = $postData;
}
protected function _checkProcessId()
{
// doing nothing
}
}
?>
<?php
require_once dirname(__FILE__) . '/../PHPFoo/XYZ.php';
class App_XYZ extends PHPFoo_XYZ
{
protected $_UserData = array();
protected $_UserId = 'notset';
protected $_UserName = '';
public $_msg = '';
public function processXYZ(array $postData)
{
$this->_postData = $postData;
$this->_getUserData();
$this->_checkProcessId();
}
protected function _checkProcessId()
{
$this->_writeLog("User Name ".$this->_UserName);
$this->_writeLog("User Id ".$this->_UserId);
// These show empty
}
public function _getUserData() {
$UserData = array();
$UserId = array();
$User_Name = array();
$msg = '';
// Get data from database
$this->_UserId = $UserId[0]['item_id'];
// Get data from database
$this->_UserName = $User_Name[0]['title'];
// Get full data
// $results = Array of values from database
foreach ($results as $key => $value) {
$UserData[$results[$key]['fielddef_id']] = $results[$key]['value'];
}
$this->_UserData = $UserData;
$this->_writeLog("USER DATA FULL");
$this->_writeLog("User Name ".$this->_UserName);
$this->_writeLog("User Id ".$this->_UserId);
$msg = '';
foreach ($this->_UserData as $k => $v) {
$msg .= "\n".$k." == ".$v;
}
$this->_writeLog("User Data\n".$msg);
// The above output is good
if($this->_UserData = '' || $this->_UserId = '' || $his->_UserName = '') {
$this->_writeLog("There was an error getting User Data.");
return false;
}else{
return true;
}
}
}
There is something wrong from beginning, you should write "public function" when you declare a function, not "public functions", and there must be the word "function" declaring a method, not just the name.
Also you are calling a method myfunc1, when it doesn't exists and you have made another mistake when you call func2 (you wrote fucn2).
So, if you fix your code, it works as you want.
Here I fixed it for you:
<?php
abstract class foo {
protected $_var1 = '';
protected $_var2 = '';
public function func1() {
#code...
}
public function func2() {
#code..
}
}
class bar extends foo {
protected $myvar1 = '';
protected $myvar2 = '';
public function myfunc() {
// do some code to fill myvar1 to be used in other functions
$this->myvar1 = 'some data';
echo "my var " . $this->myvar1;
}
public function func2() {
// do some code that uses myvar1 data
// but $this->myvarf1 is empty here why?
echo $this->myvar1;
}
public function runit() {
$this->myfunc();
$this->func2();
}
}
//requre file
$callclass = new bar;
$callclass->runit();
?>
So please be careful before asking and if you can/want use an ide like netbeans for php to avoid this mistakes.
Have a good night.
<?php
require_once (realpath(dirname(__FILE__) . '/../includes/database.php'));
class User {
public $email;
public $password;
public function find_email($email, $password) {
global $database;
$pswd = substr(md5($password), 0, 25);
$results_array = self::find_by_sql("SELECT * FROM tbl_users where email_id='".$email."' AND password='".$pswd."'");
return !empty($results_array)? array_shift($results_array) : false;
}
public static function find_by_sql($sql){
global $database;
$results = $database -> query($sql);
$object_array = array();
while($row = $database -> fetch_array($results)){
$object_array[] = self::instantiate($row);
}
return $object_array;
}
public static function instantiate($row) {
$event = new self;
foreach($row as $attribute => $value) {
if($event -> has_attribute($attribute)) {
$event -> $attribute = $value;
}
}
return $event;
}
private function has_attribute($attribute) {
$object_vars = get_object_vars($this);
return array_key_exists($attribute, $object_vars);
}
}
if (isset($_GET['email']) && isset($_GET['password'])) {
$result = new User();
$result->find_email($_GET['email'], $_GET['password']);
echo json_encode($result);
}
?>
This is the login.php which is supposed to print out the json for the required user, but whenever I try to get the json, this is getting returned.
{"email":null,"password":null}
Any help would be appreciated. Thanks.
You don't do anything with the result of find_email. Your class doesn't update it's own properties when find_email is called. Instead, it returns a new instance of the class with the email and password properties set, so you need to capture the return value and encode that.
Change to:
$result = new User();
$user = $result->find_email($_GET['email'], $_GET['password']);
echo json_encode($user);
Side note: have a look at SOLID and Dependency Injection. DI would be preferred over having a global $Database.
I have a DB class that I've created several functions in to return various values. One of the functions returns (or is supposed to) a "user" class object that represents a logged in user for the application.
class user {
public $guid = '';
public $fname = '';
public $lname = '';
public function __construct() {}
public function print_option() {
return "<option value='$this->guid'>$this->name</option>";
}
}
In the DB class I have the following 2 functions:
public function get_user($uid) {
$sql = '';
$usr = new user();
$sql = "SELECT guid, fname, lname FROM ms.users WHERE guid=?";
if($sth = $this->conn->prepare($sql)) {
$sth->bind_param('s', $uid);
if($sth->execute()) {
$sth->bind_result($usr->guid, $usr->fname, $usr->lname);
$sth->fetch();
print_r($usr); // PRINTS OUT CORRECTLY
return $usr;
}
else {return null;}
}
else {return null;}
}
public function get_practice_user_list($pguid) {
$ret = '';
$sql = "SELECT user_guid FROM ms.perm WHERE p_guid=?";
if($sth = $this->conn->prepare($sql)) {
$sth->bind_param('s', $pguid);
if($sth->execute()) {
$usr = new user();
$guid = '';
$sth->bind_result($guid);
while($sth->fetch()) {
print_r($guid); // PRINTS GUID correctly
$usr = $this->get_user($guid);
print_r($usr); // PRINTS NOTHING object is null so prints "error" two lines later.
if($usr != null) $ret .= $usr->print_option();
else print "error";
}
return $ret;
}
else {return null;}
}
else {return null;}
}
I'm just not understanding why the "user" object is not returning in this instance. Others calls to the get_user function work just fine and return the user class object pertaining to that user.
TIA
I guess you guid may be an integer so
$sth->bind_param('s', $uid);
bind_param's first param should be 'i' not 's';
http://www.php.net/manual/en/mysqli-stmt.bind-param.php
The problem was with the query. Since the code was just looping through one query (get_practice_user_list), then calling the get_user function and attempting a second query MySQL came back with an error of out of sync message. When I looked that up, I was able to fix it by doing a fetch_all on the first query then looping through that array to get the users.