Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
231 views
in Technique[技术] by (71.8m points)

php - CodeIgniter: Global Vars via Controller and Indirect modification of overloaded property

A problem haunting me since early days of CodeIgniter and now, with the new CI 3 i want to see if there is a more elegant way to solve it.

// file: application/core/MY_Controller.php
class MY_Controller extends CI_Controller {

   public $GLO;

   function __construct(){
      parent::__construct();
      $this->GLO['foo'] = 'bar';
      $this->GLO['arr'] = array();
   }
}

then, later in the code, I need to get and set the values of the $GLO variable dynamically. So for instance:

// file: application/controllers/dispatcher.php
class Dispatcher extends MY_Controller {

   function __construct() {
     parent::__construct();
     $this->load->model('public/langs');
     print_r($this->GLO);
   }
}

will print array('foo'=>'bar, 'arr'=>Array()) which is correct. Also in my models I can get the values of the $GLO array in the same manner. However, as soon as I need to set any values in the $GLO array, I get the Indirect modification of overloaded property notice and so I am stuck. In my model (after executing a DB query):

// file: application/models/public/langs.php
class Langs extends CI_Model {

function __construct(){
    parent::__construct();  
}

function set_global_languages(){
  print_r($this->GLO); // <<< prints the same values as in the controller above
  $temp = array();
  // [stripped db code]
  $temp['label'] = $row->label;
  $temp['id'] = $row->id;      
  $this->GLO['arr'][] = $temp; // <<< this is where the notice happens
}

Any clues of how I can use $this->GLO['foo'] = 'baz'; for setting properties of this global array in my models?

Cheers.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I stumbled upon this problem a ton of times. Since you are asking for an elegant solution - i try to give you some idea.

There is a library called Registry, which is written totally fine and can be extended any time. You can find the library here.

Put it in your libraries folder. This library should get autoloaded so it is always available. Add it to your config/autoload.php

$autoload['libraries'] = array(...,"Registry");

After that you should have a really easy way of storing things globally within CI - in your code for example it would look like

class MY_Controller extends CI_Controller {

    function __construct()
    {
        parent::__construct();

        $arrSomething = [
            'foo' => "bar",
            "arr" => array()
        ];
        $this->registry->set("arrSomething",$arrSomething);
    }
}

class Dispatcher extends MY_Controller 
{

    function __construct() 
    {
        parent::__construct();
        $this->load->model('public/langs');
    }
}

class Langs extends CI_Model 
{

    function __construct(){
        parent::__construct();  
    }

    function set_global_languages()
    {
        $arrSomething = $this->registry->get("arrSomething");
        $temp = array();
        // [stripped db code]
        $temp['label'] = $row->label;
        $temp['id'] = $row->id;      
        $arrSomething['arr'][] = $temp;

        //in case of an array i guess you've to reset it because there is no reference or try to call it by reference with "&"
        $this->registry->set("arrSomething");

    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...