Hi,

Am working on hooks wit codeigniter, am getting an error after applying hooks like "This webpage has a redirect loop".

My hooks.php file :

$hook['post_controller_constructor'] = array(
                               'class'    => 'SessionData',
                               'function' => 'initializeData',
                               'filename' => 'auth.php',
                               'filepath' => 'hooks',
                               'params'   => array()
                               );

auth.php file:

<?php
class SessionData{
    var $CI;

    function __construct(){
        $this->CI =& get_instance();
        if(!isset($this->CI->session)) 
          $this->CI->load->library('session');
    }

    function initializeData() {
          if(!$this->CI->session->userdata('admin_id')){   
             redirect('admin');
          }
    }
}
?>

Why am getting this error? Please help.

Thanks

Dani AI

Generated

Short summary and cause (follow-up to ): the hook you installed runs for every controller instantiation, so redirecting to your admin controller from that hook will cause the hook to run again on the admin request and produce the infinite loop described. The hooks points and when they're executed are documented in the CodeIgniter user guide. (codeigniter.com)

A robust, simple fix: have the hook skip the auth check when the current request is already the admin/login page (or any public controller). Inspect the router or URI to decide whether to guard this request, rather than unconditionally redirecting. Example pattern (put this logic in your hook method — variable names below are different from the snippets already in the thread):

// inside your hook class
$ci =& get_instance();
// make sure session is available (prefer autoloading; see below)
if (! isset($ci->session)) $ci->load->library('session');

$controller = strtolower($ci->router->class);   // or use $ci->uri->segment(1)
$public = array('admin', 'public', 'assets');   // controllers that do not require auth

if (in_array($controller, $public, TRUE)) {
    return; // don't redirect when visiting admin/login or static assets
}

if (! $ci->session->userdata('user_logged')) {
    redirect('admin/login'); // send to login only when not already on it
}

Use the router/URI helpers shown in the docs to get controller/method or segments. That lets the hook decide whether to bypass the redirect for your login page. (codeigniter.com)

Cleaner alternative: move authentication checks into a base controller (MY_Controller) and have only controllers that need protection extend it. That avoids global hooks that apply to every single request and makes per-controller exceptions trivial. Also autoload the session library (application/config/autoload.php) so the session is always available when hooks or controllers run. See the controllers/core-classes and session docs for patterns and autoload guidance. (codeigniter.com)

Troubleshooting tips: enable logging and add log_message('debug', ...) inside the hook to record the current controller/URI and session state (do not echo before redirects). Logging is safer and preserves headers while you inspect behavior. Once the router/whitelist approach is in place the redirect loop should stop. (codeigniter.com)

Recommended Answers

All 3 Replies

I noticed you have

redirect('admin')

when there is no session admin_id, the user get redirected to the admin controller. on redirect, the hook gets triggered for the second time redirect the user again and the cycle goes on and on and on .

A probable solution is to create another session that can be use to evaluate if this particular user has been or already been redirected to the admin page.

for example, first redirect, the user landed on the admin. We can set a session like this

$this->session->set_userdata('already_been_here', TRUE);

You can then modify this method

function initializeData() {
if(!$this->CI->session->userdata('admin_id')){
redirect('admin');
}

to this method

function initializeData() {
    if(!$this->CI->session->userdata('admin_id') && (!$this->CI->session->userdata('already_been_here'))){

    redirect('admin');

    }
}

Now, what the new method will do is to check for the second condition if the the session already_been_here is NOT TRUE and if it is NOT TRUE, then redirect to the admin controller page.

don't leave this as an empty array

 'params'   => array()

you can either comment it or just replace it with ''.

depending on your CI version, it migh allows you to change this

redirect('admin');

to this

redirect('admin', 'refresh');

Hi Veedeoo,

I have tried the changes you have suggested, but it doesn't work.When i applied the changes, the page is continuously refreshing like a loop.Please help.

Thanks

May I see your admin controller? This should be the controller on redirect.

This should be added on the controller accepting the redirect

    $this->session->set_userdata('already_been_here', TRUE);

So that when the user is redirected for the first time, the session already_been_here will be set. When the user is set to go back again to the page where redirection was executed, script will not be redirected for the second time because the user is already been there.

Another concern I have is your statement on your constructor.

function __construct(){
    $this->CI =& get_instance();
    if(!isset($this->CI->session))
    $this->CI->load->library('session');
}

If we look at the statement line by line, it is checking if the session is set. If not, the constructor load the library. There is a problem with that though. How can we check if the session exists if the session library is to be loaded later?

So, I would suggest for you to try checking if the session library is loaded , if not load it and then check if the session exists.

It can be something like this

if (!class_exists('session')){

    $this->CI->load->library('session');
}

In CI, helpers are functions, libraries are classes and therefore session library is a class.

To make sure that it is loading properly, we can test it like this with modified constructor.

public function __construct(){

     if (!class_exists('session')){

    $this->CI->load->library('session');

    }
    ## remove or modify codes below to your requirements after successful testing
    echo (isset($this->CI->session) ? 'session is set': 'no session exists up to this point');

} 
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.