unable to use session variable - php

I'm using a codeigniter and i have 3 controller, i use the session to store username from the 1st controller and i use this to determine from the other controller if someone is logged in.
Here is a the constructor of the first controller, in this class, i also use the statement where i give a value to $_SESSION['username'] so the other controller use it:
class Login extends CI_Controller {
public function __construct()
{
session_start();
parent::__construct();
}
public function index()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username');
$this->form_validation->set_rules('password', 'Password', 'required|min_length[4]');
if ( $this->form_validation->run() !== false ) {
// then validation passed. Get from db
$this->load->model('Login_Model');
$res = $this->Login_Model->verify_user(
$this->input->post('userName'),
$this->input->post('password')
);
if ( $res !== false ) {
$tempuser = $this->input->post('username');
$_SESSION['username'] = $tempuser;
redirect(base_url());
}
}
$this->load->view('login_view');
}
This is the 2nd controller, on he constructor, i created a conditional statement to determine if someone is logged in, i tested this and it's still ok:
class Pagination extends CI_Controller {
public function __construct() {
parent:: __construct();
$this->load->helper("url");
session_start();
if(!isset($_SESSION['username'])){
redirect(base_url().'index.php/login');
}
}
In the 3rd controller, this is where i encounter the problem, i cannot access the variable where i stored the username, here is the code:
class Blood_Controller extends CI_Controller {
public function __construct()
{
session_start();
parent::__construct();
if(!isset($_SESSION['username'])){
redirect(base_url().'index.php/login');
}
}
It always go inside the if statement even if i enter a rightusername on the 1st controller.
can anyone help?

load this "$this->load->library('session'); " in the constructor ie in here
public function __construct()
{
session_start();
parent::__construct();
}
and remove the session_start() and use
`$this->session->set_userdata('username', $tempuser);`

It's always good idea to check if session is already exists.
Try:
if (!session_id())
session_start();
And try to var_dump($_SESSION); in 3rd controller after session_start() to check what is inside.

Need to set session data using $_SESSION array in this case instead of CI session library ie. replace $this->session->set_userdata('username', $tempuser); with $_SESSION['username'] = $tempuser

remove all the session_start(); and set it in the config -> autoload.php
change '!=='to "!=' and check the session variable value

You can initialize the Session class manually in your controller constructor, use the $this->load->library function:
$this->load->library('session');
Don't need to use session_start() in codeigniter.
Once loaded, the Sessions library object will be available using: $this->session
On the other hand if you don't want to initialize the Session class manually in your every controller constructor, then you can autoload it from your application/config/autoload.php file,just add session class name in $autoload['libraries'] array like this:
$autoload['libraries'] = array('database', 'form_validation', 'session');
Now you can set your session data like this way:
$this->session->set_userdata('user_name', $user_name);
And you can retrieve your session data like this way:
$user_name = $this->session->userdata('user_name');
Go here to learn more about CI session : http://ellislab.com/codeigniter/user-guide/libraries/sessions.html

Related

How to fix Codeigniter error: Call to a member function on null?

It's my first time exploring codeigniter and I've been trying to create a login where if users are not found in the database, it will redirect back to the login screen. I have not been successful because I've been getting this error:
first error message
Followed by
second error message
I've tried loading the database and session inside function verify() using
$this->load->database();
$this->load->session();
but even so, I didn't think it would work since I already declared database and session in autoload.php
$autoload['libraries'] = array('database', 'session');
Here's the controllers/Login.php
class Login extends CI_Controller{
function index(){
$this->load->view("templates/_header");
$this->load->view("login");
$this->load->view("templates/_footer");
$this->load->view("templates/_scripts");
}
function verify(){
$this->load->model('user');
$check = $this->model->validate();
if($check){
} else {
redirect('login');
}
}
}
Here's the models/User.php
<?php
class User extends CI_Model{
function validate(){
$arr['username'] = $this->input->post('username');
$arr['password'] = password_hash($this->input->post('password', PASSWORD_DEFAULT));
return $this->db->get_where('users', $arr)->row();
}
}
What do you guys think is the problem with it?
you have load your model true way but to use it you have to call its class name (here is User) to work work correctly.
note: if you want to code in a clean way and don't conflict them try to name your models like User_model or User_m, so if you have a controller with name of User its not conflict with your model.
:-)

Is it allowed to load multiple models in single Controller in CI3?

Is it allowed to load multiple models in single Controller ? And my each model is loading same database in their controller. Thanks
function __construct()
{
parent::__construct();
$this->load->database() or die("Cannot open database");
$this->load->model("Admin/Product_model");
$this->load->model("Admin/Category_model");
$this->load->model("Admin/Attribute_model");
$this->load->model("Admin/Attribute_value_model");
}
This is my controler constuctor. And in constuctors of all models I am loading same database. Like these,...
Class Attribute_value_model extends CI_Model
{
Name : function __construct
Returns : NULL
Use : This is the constructor of project, loads the database on every times page is called
function __construct()
{
parent::__construct();
$this->load->database("default") or die("Cannot open");
}
Issue resolved
Insted of loading database from each model, I directly loadaed
default database from autoload.php.
So it prevents loading same
database again
//In autoload.php
$autoload['libraries'] = array('mailchimp','session','form_validation','database');
Yes, you can load multiple models in a single controller.You can tell the model loading method to auto-connect by passing TRUE (boolean) via the third parameter, and connectivity settings, as defined in your database config file.
for example:
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
//session_start(); //we need to call PHP's session object to access it through CI
class Home extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->model('user', 'guru', TRUE);
$this->load->model('student', 'santosh', TRUE);
}
function index() {
//echo $this->session->userdata('validuser');
// die('here');
if ($this->session->userdata('logged_in')) {
$session_data = $this->session->userdata('logged_in');
$data['username'] = $session_data['username'];
$pankaj = $this->guru->userinfo(1);
var_dump($pankaj);
$santosh = $this->santosh->studentinfo(1);
var_dump($santosh);
$this->load->view('home_view', $data);
} else {
//If no session, redirect to login page
redirect('login', 'refresh');
}
}
function logout() {
$this->session->unset_userdata('logged_in');
session_destroy();
redirect('home', 'refresh');
}
}

Cannot use a scalar value as an array in codeigniter?

I am getting this very strange error "Cannot use a scalar value as an array"
neither google god nor stuffs on SOF helped me this what i am trying to do is i have already created user session[with session data username and password] now after user login on my_profile page i am appending some session data like user_id then i start getting this error??? Any help or Hints
//controller
<?php
class My_profile extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->library('session');
$this->load->helper('form');
$this->load->helper('url');
$this->load->helper('html');
$this->load->database();
$this->load->library('form_validation');
// $this->is_login();
}
public function index () {
if($this->session->userdata('is_login')) {
$session_data = $this->session->userdata('is_login');
$session_data['user_id'] = $this->session->userdata('user_id');
$this->session->set_userdata("is_login", $session_data);
$this->load->model('My_profilee');
$data['query']=$this->My_profilee->view_data();
$this->load->helper('url');
$this->load->view('header2');
$this->load->view('my_profile');
// $this->load->view('footer');
}else {
echo "you don't have permission to access this page <a href=../Homecontroller/index/>Login</a>";
die();
}
}
}
?>
//model
<?php
class My_profilee extends CI_Model {
function __construct()
{
// Call the Model constructor
parent::__construct();
$this->load->database();
}
public function view_data() {
//echo $this->session->userdata('user_id');
$query=$this->db->get('tbl_usrs');
return $query->result();
}
}
?>
what i am really trying to do is to add user id [from databse] of user after login into session data and then display user information according to user id??
This is pretty straight forward.
You have an assignment wherein a single value, be it an integer or string, is assigned to a variable:
$session_data = $this->session->userdata('is_login');
This is now a scalar value. it is unmutable unless redefined in context. You cannot apply an array value to an existing scalar value, you must instantiate a new array, and apply the value as an index, then add the new item as an index to the new array.
$session_array['session_data'] = $this->session->userdata('is_login');
And continue assigning variables to this array and so forth.

check session in another controller in Codeigniter

After the user logs in, I set the variable is_logged_in=true, but in some other controller how can I check is_logged_in is true in codeigniter?
Here is my login code:
public login_con extends CI_Controller
{
public function login()
{
is_logged_in=true;
}
}
I want to check this is_logged_in in another controller so how can i write code for that?
Session is best solution for this. You can read codeignitor session
// set value in session
$this->session->set_userdata('is_logged_in', true);
To get in other controller
$is_logged_in = $this->session->userdata('is_logged_in');
Please also make sure you have loaded session library.
$this->load->library('session');
First thing autoload applications/config/autoload.php, to add session library
$autoload['libraries'] = array('session');
This will include session on every page.
Now your controller file
controller1
public login_con extends CI_Controller
{
public function login()
{
//here you set session like that
$data['is_logged_in'] = TRUE;
$this->session->set_userdata($data);
}
}
Here you get your is_logged_in session on other controller
controller2
public your_con extends CI_Controller
{
public function your_function()
{
//here you get session like that
if($this->session->userdata("is_logged_in"))
{
// your code here
}
}
}

How to exit codeigniter without die() in __construct() function of controller?

I have a controller where in the constructor function, I want to check if the user is logged in or not. If not, I want an error message to be displayed, and for the script to exit without running any other function in the controller. This controller will only be called by ajax so the error would be displayed via JSON and then the javascript on the client will display it to the user.
How can I do this? If I did this:
function __construct()
{
if (! $this->loggedIn() )
{
echo json_encode( array('error'=> true) );
die;
}
}
I don't think the message would be displayed because codeigniter uses output buffering. Any ideas?
i understood that your problem is the client expects for a json type of response, so two options to use:
public function __construct(){
$_bad_login_msg = 'please try again' ;
parent::__construct();
if(!userLoggedIn()){
$this->output
->set_content_type('application/json')
->set_output(json_encode($_bad_login_msg));
//or just use
// echo json_encode($_bad_login_msg);
die;
}
}
http://codeigniter.com/user_guide/libraries/output.html
you won't have any buffering problems, the buffer contents will be sent to the client after the die...
The best way is to redirect the user to login page.
As mentioned here : https://stackoverflow.com/a/10399199/876117
public function __construct(){
parent::__construct();
if(!userLoggedIn())
$this->load->view('promptlogin');
$this->output->_display();
exit();
}
public function index(){
// one will never reach here unless he is logged in
$this->load->view('actualcontent');
}
I'm pretty sure you can just use something like this:
function __construct()
{
if (! $this->loggedIn() )
{
exit('Please login before visiting this page');
}
}
MY_Controller is your top level/parent controller so its all done in there because every other controller will extend it. So if you have an auth controller(which extends MY_Controller) you will have access to its logic.
So MY_Controller
class MY_Controller extends CI_Controller{
protected $_user;
public function __construct(){
parent::__construct();
$this->_user = $this->session->userdata('uid')
? find_a_user : NULL;
// if a session of user_id exists and is found in DB
// we have a live user
}
}
Auth
class Auth extends MY_Controller{
public function __construct(){
parent::__construct();
// we now have access to $this->_user
if($this->_user !== NULL) // we have active user
}
}
I think you should use flashdata and redirect to a controller with it. Then you can control if any flashdata comes in session, after that write it in view.

Categories