$_SESSION gets unset before accessing value - php

Code for setting the session message
if($result === true) {
$session->message('The admin was updated successfully');
// $_SESSION['message'] = 'The admin was updated successfully';
redirect_to(url_for('/staff/admins/show.php?id=' . $id));
} else {
// show errors
}
This is the code for displaying the session message
function display_session_message() {
global $session;
$msg = $session->message();
if(isset($msg) && $msg != '') {
$session->clear_message();
return '<div id="message">' . $msg . '</div>';
}
}
Code for getting session message
public function message($msg="") {
if (!empty($msg)) {
$_SESSION['message'] = $msg;
return true;
} else {
return $_SESSION['message'] ?? '';
}
}
Session Class (also included in this class is public function message())
class Session
{
public function __construct() {
session_start();
$this->check_stored_login();
}
public function clear_message() {
unset($_SESSION['message']);
}
}

You have to use:
session_start();
in top of each file you are using for session to work

Related

variable won't change in PHP class

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;
}
}

PHP Session doesn't work on another page using an array

So I made a registration page and i'm also using sessions to flash messages.
The session is called 'flash' and I made an abstraction class for sessions to make it easier.
This is my Session class:
public static function exists($name)
{
return (isset($_SESSION[$name]) ? (true) : (false));
}
public static function set($name, $value)
{
return $_SESSION[$name] = $value;
}
public static function delete($name)
{
if(self::exists($name)) {
unset($_SESSION[$name]);
}
}
public static function get($name)
{
if(self::exists($name)) {
return $_SESSION[$name];
}
return '';
}
public static function hasFlash()
{
return (Session::exists('flash') ? (true) : (false));
}
public static function addFlash($message)
{
if(Session::exists('flash'))
{
$msgArray = (Array) Session::get('flash');
array_push($msgArray, $message);
Session::set('flash', (Array) $msgArray);
}
else
{
$msgArray = array();
array_push($msgArray, $message);
Session::set('flash', (Array) $msgArray);
}
}
public static function flash($message = null)
{
if(self::hasFlash()) {
$msgArray = (Array) Session::get('flash');
Session::delete('flash');
foreach($msgArray as $message) {
echo $message . "<br>";
}
}
return '';
}
And this is my registration page:
$hasError = false;
$username = Functions::escape(Input::get('user'));
$password = Functions::escape(Input::get('password'));
$email = Functions::escape(Input::get('email'));
$nick = Functions::escape(Input::get('nick'));
if(User::userExists($username, $db)) {
Session::addFlash("User $username is taken, try another one.");
$hasError = true;
}
if(User::emailExists($email, $db)) {
Session::addFlash("Email $email is taken, try another one.");
$hasError = true;
}
if(!$hasError)
{
User::addUser($username, $email, $password, $nick, $db);
Session::addFlash("You have successfully registered.");
Session::addFlash("You can now login with $username.");
Functions::location("index.php");
}
That's the code i'm using to display the flash messages:
<?php if(Session::hasFlash()) : ?>
<div class="form-group">
<?php Session::flash(); ?>
</div>
<?php endif; ?>
However it only works on the registration page for instance when a user types in a username/email that is taken, the code above will show the message though when I register the user and send him to the index page, the 2 success messages won't show up. I do have session_start at the top of the page.
The issues seemed to resolve by adding the following:
// server should keep session data for AT LEAST 1 hour
ini_set('session.gc_maxlifetime', 3600);
// each client should remember their session id for EXACTLY 1 hour
session_set_cookie_params(3600);

Error handling PHP function

So I want to make a function to display errors instead of saying echo "error message", I want something like $this->errorDisplay('error message');
I currently have this, but it's not doing the job.
function errorDisplay($msg) {
$this->errors[] = $msg;
foreach($this->errors as $error) {
echo $error;
}
}
public function checkFields($username,$password) {
if(!empty($username) && !empty($password)) {
//proceed to validation
} else {
$this->errorDisplay('All fields are required.');
}
}
Instead of trying to do everything in one method, split the process into 2. One method adds messages to an array, and the other shows all the previously saved up messages.
Class xxx
{
public $errors = array();
public function addError($msg) {
$this->errors[] = $msg;
}
public function showErrors() {
foreach($this->errors as $error) {
echo $error;
}
}
public function initErrors() {
$this->errors = array();
}
public function checkFields($username,$password) {
$this->initErrors();
if( empty($username) ) {
$this-addError('Username missing');
}
if ( empty($password) ) {
$this-addError('Password missing');
}
if ( count($this->errors) > 0 ) {
$this->showErrors();
}
}
} //end class

Serializable objects disappearing from session, but not on localhost

I have a shopping cart object that implements serializable, and it works fine on my localhost, but when I upload it to the live server it stops working correctly.
When I add a product to the shopping cart and print_r($_SESSION) I can see the products have been added successfully, but when I refresh the page they disappear. This only happens with objects that implement serializable. These same objects work perfectly on my localhost, which has IDENTICAL code, and it's driving me insane.
Could it be a difference in session handling between php version 5.5 and 5.6?
I am using spl_autoload_register to load my classes if that helps at all (none of them appear in the session as incomplete_class or anything like that).
I also noticed that the session save path is blank on the live version, but is set on my localhost - but the rest of the session functions perfectly - it's only when it contains serializable classes that everything disappears.
Please help before I murder someone...
OK here's the code:
shopping cart class:
class shoppingCart implements Serializable
{
private $products, $error;
function __construct()
{
}
function addProduct($productCode, $quantity = 1)
{
include_once ('include/requests.php');
$productInfo = requestPostData('getProductList');
if (in_array(strtoupper($productCode), $productInfo['results']) == true)
{
if (isset($this->products[strtoupper($productCode)]))
{
$this->products[strtoupper($productCode)] = $this->products[strtoupper($productCode)] + $quantity;
return true;
}
else
{
$this->products[strtoupper($productCode)] = $quantity;
return true;
}
}
else
{
$this->error = 'Product '.$productCode.' could not be found.';
}
}
function editProduct($productCode, $quantity)
{
if (isset($this->products[strtoupper($productCode)]))
{
$this->products[strtoupper($productCode)] = $quantity;
}
}
function removeProduct($productCode)
{
if (isset($this->products[strtoupper($productCode)]))
{
unset($this->products[strtoupper($productCode)]);
}
}
public function getProducts()
{
if (count($this->products) >= 1)
{
return $this->products;
}
else
{
return false;
}
}
public function isInCart($productCode)
{
if (isset($this->products[strtoupper($productCode)]))
{
return true;
}
else
{
return false;
}
}
public function getQuantity($productCode)
{
if (isset($this->products[strtoupper($productCode)]))
{
return $this->products[strtoupper($productCode)];
}
else
{
return 0;
}
}
public function getError()
{
$error = $this->error;
return $error;
}
public function resetError()
{
$this->error = '';
}
public function serialize()
{
$dataArray = array('products' => $this->products, 'error' => $this->error);
return serialize($dataArray);
}
public function unserialize($data)
{
$dataArray = unserialize($data);
$this->products = $dataArray['products'];
$this->error = $dataArray['error'];
}
}
And the code on the page:
if (session_status() !== PHP_SESSION_ACTIVE)
{
session_start();
}
if (!isset($_SESSION['shoppingCart']))
{
$_SESSION['shoppingCart'] = new shoppingCart;
}
if (isset($_POST['cart__add_to_cart']))
{
if (isset($_POST['cart__quantity']))
{
if ($_SESSION['shoppingCart']->addProduct($_POST['cart__add_to_cart'], $_POST['cart__quantity']))
{
header('Location: http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
}
}
else
{
if ($_SESSION['shoppingCart']->addProduct($_POST['cart__add_to_cart']))
{
header('Location: http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
}
}
}
If I print_r($_SESSION) right at the bottom of the page after a product has been added then it appears in the session as it should... But as soon as I refresh it disappears :'(

Fatal error: Call to a member function getUserID()

I am getting the following error when I check my site:
Fatal error: Call to a member function getUserID() on a non-object in /home/clientwo/public_html/main/registry/authenticate.php on line 104
This is the code:
<?php
class Authenticate {
private $user;
private $status;
private $loggedIn = false;
public function __construct(Registry $registry) {
$this->registry = $registry;
$this->status = 'User is logged out';
}
private function checkForAuthentication() {
if (isset($_SESSION['sn_auth_session_uid']) && $_SESSION['sn_auth_session_uid'] > 0) {
$this->sessionAuthenticate(intval($_SESSION['sn_auth_session_uid']));
}
}
private function sessionAuthenticate($id) {
//build a user model
require_once FRAMEWORK_PATH . 'model/user.php';
$this->user = new UserModel($this->registry, $id);
//check if user is valid etc
if ($this->user->isValid()) {
if (!$this->user->isActive()) {
$this->loggedIn = false;
$this->status = 'User has been deleted';
} else {
$this->loggedIn = true;
$this->status = 'User is logged in';
}
} else {
$this->loggedIn = false;
$this->status = 'User could not be found';
}
//make sure sessions are not set if user is not logged in
if (!$this->loggedIn) {
$this->logout();
}
}
public function login($username, $password) {
//first log out
$this->logout();
//execute query
$this->registry->getObject('mysql')->executeQuery("SELECT UserID FROM user WHERE Username='". $username . "' AND password='" . md5($password) . "'");
//check if query returned one row
if ($this->registry->getObject('mysql')->numRows() == 1) {
//get user row
$UserData = $this->registry->getObject('mysql')->getRow();
//build a user model
require_once FRAMEWORK_PATH . 'model/user.php';
$this->user = new UserModel($this->registry, $UserData['UserID']);
//check if user is valid and active etc
if ($this->user->isValid()) {
if ($this->user->isActive() == false) {
$this->loggedIn = false;
$this->status = 'User has been deleted';
} else {
$this->loggedIn = true;
$this->status = 'User is logged in';
$this->user->increaseLogins();
$this->user->update();
$_SESSION['sn_auth_session_uid'] = $this->user->getUserID();
}
} else {
$this->loggedIn = false;
$this->status = 'Authentication failed';
}
} else {
$this->loggedIn = false;
$this->status = 'Authentication failed';
}
}
function logout() {
//if such a session is set, unset it
if (isset($_SESSION['sn_auth_session_uid'])) {
unset($_SESSION['sn_auth_session_uid']);
}
//reset to logged out
$this->loggedIn = false;
//reset to null
$this->user = null;
}
public function isLoggedIn() {
$this->checkForAuthentication();
return $this->loggedIn;
}
public function isAdmin() {
$this->checkForAuthentication();
return $this->user->isAdmin();
}
public function getUser() {
$this->checkForAuthentication();
return $this->user;
}
public function getUserID() {
$this->checkForAuthentication();
return $this->user->getUserID();
}
public function getStatus() {
$this->checkForAuthentication();
return $this->status;
}
}
?>
This line is not returning the user object
$this->user = new UserModel($this->registry, $UserData['UserID']);

Categories