Jethro Hazelhurst
Jethro Hazelhurst

Reputation: 3285

Codeigniter Controller name and Object name collision

I have encountered a problem and I am not sure how to resolve it.

I have a controller Pusher with a method Auth

class Pusher extends MX_Controller
{
    /**
     *
     */
    public function auth()
    {
        $this->load->model('pusher/Pusher_model');
        $p = $this->Pusher_model->newPusher();
        var_dump($p);die;
    }
}

I have a model Pusher_model with a method that instantiates a new Pusher() object

require 'vendor/autoload.php';

class Pusher_model extends CI_Model
{
    public $options;
    /**
     *
     */
    public function __construct()
    {
        $this->config->load('api_config');
        $this->options = array(
            $this->config->item('pusher_cluster'),
            $this->config->item('pusher_is_encrypted')
        );

    }

    /**
     *
     */
    public function newPusher()
    {
        return new Pusher(
            $this->config->item('pusher_public_key'),
            $this->config->item('pusher_secret_key'),
            $this->config->item('pusher_api_id'),
            $this->options
        );
    }
}

When I var_dump() the returned Pusher object in my controller...

var_dump($p)

I get the entire controller 'Pusher' as a result...

object(Pusher)#24 (2) {
  ["autoload"]=>
  array(0) {
  }
  ["load"]=>
  object(MY_Loader)#25 (13) {
    ["_module":protected]=>
    string(6) "pusher"
    ["_ci_plugins"]=>
    array(0) {
    }
    ["_ci_cached_vars"]=>
    &array(0) {
    }
    ["_ci_ob_level":protected]=>
    int(1)
    ["_ci_view_paths":protected]=>
    &array(1) {
      ["C:\xampp\htdocs\php\twocan\twocan_beta\App\views\"]=>
      bool(true)
    }
    ["_ci_library_paths":protected]=>
    &array(2) {
      [0]=>
      string(43) "C:\xampp\htdocs\php\twocan\twocan_beta\App\"
      [1]=>
      string(43) "C:\xampp\htdocs\php\twocan\twocan_beta\Sys\"
    }
    ["_ci_model_paths":protected]=>
    &array(2) {
      [0]=>
      string(58) "C:\xampp\htdocs\php\twocan\twocan_beta\App\modules/pusher/"
      [1]=>
      string(43) "C:\xampp\htdocs\php\twocan\twocan_beta\App\"
    }
    ["_ci_helper_paths":protected]=>
    &array(2) {
      [0]=>
      string(43) "C:\xampp\htdocs\php\twocan\twocan_beta\App\"
      [1]=>
      string(43) "C:\xampp\htdocs\php\twocan\twocan_beta\Sys\"
    }
    ["_ci_classes":protected]=>
    &array(15) {
      ["benchmark"]=>
      string(9) "Benchmark"
      ["hooks"]=>
      string(5) "Hooks"
      ["config"]=>
      string(6) "Config"
      ["log"]=>
      string(3) "Log"
      ["utf8"]=>
      string(4) "Utf8"
      ["uri"]=>
      string(3) "URI"
      ["router"]=>
      string(6) "Router"
      ["output"]=>
      string(6) "Output"
      ["security"]=>
      string(8) "Security"
      ["input"]=>
      string(5) "Input"
      ["lang"]=>
      string(4) "Lang"
      ["loader"]=>
      string(6) "Loader"
      ["session"]=>
      string(7) "Session"
      ["form_validation"]=>
      string(15) "Form_validation"
      ["model"]=>
      string(5) "Model"
    }
    ["_ci_models":protected]=>
    &array(1) {
      [0]=>
      string(12) "Pusher_model"
    }
    ["_ci_helpers":protected]=>
    &array(5) {
      ["url_helper"]=>
      bool(true)
      ["html_helper"]=>
      bool(true)
      ["security_helper"]=>
      bool(true)
      ["language_helper"]=>
      bool(true)
      ["form_helper"]=>
      bool(true)
    }
    ["_ci_varmap":protected]=>
    &array(2) {
      ["unit_test"]=>
      string(4) "unit"
      ["user_agent"]=>
      string(5) "agent"
    }
    ["controller"]=>
    *RECURSION*
  }
}

Which leads me to believe there is a name collision going on with the instantiated object and the controller itself.

Q:

How do I resolve this collision without renaming my controller or do I have to use a different controller name to any objects I instantiate through that controller?

Upvotes: 1

Views: 199

Answers (1)

Jens A. Koch
Jens A. Koch

Reputation: 41796

How do I resolve this collision without renaming my controller or do I have to use a different controller name to any objects I instantiate through that controller?

Ok, let's see..

  • the controller is called: Pusher->auth()
  • the controller loads and calls the model: $this->Pusher_model->newPusher();
  • then you are instantiating a new Pusher object by using return new Pusher and returning it to the Pusher controller.
  • that means your Pusher controller has a property $p containing a new pusher object
  • yes, you are going in circles here.

I would suggest keeping it simple:

  • do not instantiate new Pusher, but simply return the connection data from the model (Pusher_model) to the controller, e.g.

    public function newPusher()
    {
        return array(
            $this->config->item('pusher_public_key'),
            $this->config->item('pusher_secret_key'),
            $this->config->item('pusher_api_id'),
            $this->options
        );
    }
    
  • you could also rename the method to getCredentials or getApiConfig

  • that means $p is an array and you can work with the data in the controller Psuher to set up your API to later make calls to it

Another option is to introduce a Service layer between controller and model:

  • new class PusherAPIService
  • instantiated in controller
  • in controller call model->getCredentials
  • set/pass credentials to PusherAPIService, e.g. configure($credentials)
  • add actions to PusherAPIService, e.g. connect(), pull(), push() whatever your service does. that means that the service class wraps all interaction with the external API.
  • then finally in our controller: call the services methods, when you need them. e.g. when a post request comes in, let the controller handle the incoming data, then inject the data into the service layer, then call a method on the now configured service, to get a result back into the controller.

Upvotes: 1

Related Questions