CodeIgniter Forums

Full Version: CI2 to CI3: Call to a member function helper() on a non-object in ...Session.php
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
While migrating from CI 2 to CI 3 I stucked with this error:
Code:
Call to a member function helper() on a non-object in \system\libraries\Session.php

The complete Call Stack:
Code:
# Time Memory Function Location
1 0.0007 377472 {main}( ) ..\index.php:0
2 0.0021 469352 require_once( 'E:\xampp\htdocs\girh_gt\system\core\CodeIgniter.php' ) ..\index.php:292
3 0.0482 4333336 call_user_func_array ( ) ..\CodeIgniter.php:514
4 0.0482 4333504 Controller_A->get_events( ) ..\CodeIgniter.php:514
5 0.0615 6551752 CI_Controller->__construct( ) ..\Controller_A.php:65
6 0.0616 6552504 load_class( ) ..\Controller.php:75
7 0.0617 6554192 CI_Session->__construct( ) ..\Common.php:196

The error is generated from a controller Controller_A like this:

PHP Code:
class Controller_A extends CI_Controller
{
 
 ...
 
 public function get_events()
 
 {
 
   ...
 
   require_once("Plan_Events.php");
 
   $pe = new Plan_Events(); // The line generating the error
 
   ...
 
 

And the Plan_Events class is defined like this (without own constructor):
PHP Code:
class Plan_Events extends CI_Controller { ... } 

¿Any idea? Huh
Yes, you must replace the system/ directory, not just copy-paste over it. That means delete the old one first and then put in the new one.
Thx, that solved the previous error but now I've a new one:

Code:
Unable to locate the specified class: Session.php

If I comment the new Plan_Events() line the error is gone, so the problem seems to be related to the own class extending CI_Controller.

As I quoted at the first post the Plan_Events class only extends the CI_Controller class and have some public functions using CI models. It doesn't use sessions.

Hints please...
A class extending CI_Controller can't load another class which also extends CI_Controller. You will probably need to replace the second controller with a library.
Idea

I tried to overwrite the CI_Controller construct method inside the Plan_Events class with an empty constructor and now it works!

PHP Code:
class Plan_Events extends CI_Controller {
    
    public function 
__construct()
    {
    } 

Is it a desired Behaviour?
(06-01-2015, 08:52 AM)mwhitney Wrote: [ -> ]A class extending CI_Controller can't load another class which also extends CI_Controller. You will probably need to replace the second controller with a library.

This is a CI 3.x change? It worked well with CI 2.x. I didn't see nothing at the CI 3 upgrade guide.
If it works, it never should have been a controller in the first place. If you remove the "extends CI_Controller" portion and move the file to /application/libraries/, you could load it using $this->load->library() instead of using require_once().

However, if you were using that file as a controller somewhere else on your site, you probably already broke it by removing the base constructor.
(06-01-2015, 09:02 AM)mwhitney Wrote: [ -> ]However, if you were using that file as a controller somewhere else on your site, you probably already broke it by removing the base constructor.
You are right, I went too fast, it doesn't work Sad

(06-01-2015, 09:02 AM)mwhitney Wrote: [ -> ]A class extending CI_Controller can't load another class which also extends CI_Controller. You will probably need to replace the second controller with a library.

It worked with CI2, in my opinion it should be noted in CI3 the upgrade guide.

I don't know how to transform this class to a library. I changed the Plan_Events class to not extend the CI_Controller but assigning a CI instance because I need to use the CI models, now it seems to work:

PHP Code:
class Plan_Events {
    public function 
__construct()

    {
        $this->CI =& get_instance();
    }
    public function 
beforeInsert($data)

    {
        $this->CI->load->model('example_model');
        $this->CI->example_model->scheduler_insert($data);
    }
    ...

Please tell me if it isn't a good practice. Note that I'm using Plan_Events to integrate the DHTMLX library like this:

PHP Code:
class Controller_A extends CI_Controller
{
 
 ...
 
 public function get_events()
 
 {
 
   ...
    require_once(
"assets/dhtmlx/dhtmlxConnector/codebase/scheduler_connector.php");
 
   require_once("Plan_Events.php");
    
$conn = new SchedulerConnector($this->db"PHPCI");
 
   $conn->event->attach(new Plan_Events()); // Update/Delete/...
 
   ...
 
 

Thx for the support
If you're using the controller elsewhere, I would just leave it as a controller, then extract the functionality that needs to be available in other locations into a library (to be called by all of the controllers which need it).

Storing the CI instance in a property as you've done is fairly common practice in CI libraries when the instance is needed for multiple calls. However, if you're using it to access data, you may want to consider creating a model instead of a library. As far as I know, calling a model within a model is not an issue.

Apparently being able to load a controller within a controller wasn't intended to work, and certainly wasn't a documented feature, which is why it's not mentioned in the upgrade guide. Besides, even though it appeared to work, there are some interesting bugs related to loading a controller from another controller in CI2 which are difficult to track down and nearly impossible to fix (without replacing the loader and/or controller).