phpcodeignitermediatorcodeigniter-hmvc

Codeigniter Model Fatal error: Using $this when not in object context


I have a little issue with some code that works on development but not on production. It is weird, because all the other code works (or seems to).

The entire error is the following:

Fatal error: Using $this when not in object context in /[snip]/application/modules/manage_plugins/models/Manage_plugins.php on line 6 A PHP Error was encountered

Severity: Error

Message: Using $this when not in object context

Filename: models/Manage_plugins.php

Line Number: 6

Backtrace:

From the other similar issues I could find, it was due to people attempting to use "$this" in a static context - I don't believe that is the case for me.

Here is the manage_plugins constructor, with line 6 (error line) being the first in the constructor:

class Manage_plugins extends CI_Model {

    public function __construct() {
        $this->mediator->attach("manage_load", function($name, $data) { $this->on_manage_load(); });

        $this->load->model("automediator");
    }

}

It is being loaded by the following code (and never called explicitly):

$CI =& get_instance();

$CI->load->model("manage_plugins/manage_plugins");

Does anyone know why this is happening?


Solution

  • Thanks to rexmarc, I was able to workaround the issue and make a similar structure work on PHP 5.3 by use-ing a copy of the object $this in the anonymous function.

    I changed the following:

    class Manage_plugins extends CI_Model {
        public function __construct() {
            $this->mediator->attach("manage_load", function($name, $data) { $this->on_manage_load(); });
    
            $this->load->model("automediator");
        }
    
    }
    

    into:

    class Manage_plugins extends CI_Model {
        public function __construct() {
            $me =& $this;
            $this->mediator->attach("manage_load", function($name, $data) use($me) { $me->on_manage_load(); });
    
            $this->load->model("automediator");
        }
    
    }
    

    Another solution for this could have been:

    class Manage_plugins extends CI_Model {
        public function __construct() {
            $this->mediator->attach("manage_load", [$this, 'on_manage_load']);
    
            $this->load->model("automediator");
        }
    
    }
    

    The issue was occurring because in PHP versions prior to 5.4, $this was not available in anonymous functions.

    5.4.0 - Anonymous functions may use $this, as well as be declared statically

    Source: http://php.net/manual/en/functions.anonymous.php

    The issue went unnoticed because of differing PHP versions on development (5.5) and production (5.3).

    See also: https://stackoverflow.com/a/19432335/3649573