【问题标题】:CodeIgniter: Global Vars via Controller and Indirect modification of overloaded propertyCodeIgniter:通过控制器和间接修改重载属性的全局变量
【发布时间】:2016-11-09 11:16:01
【问题描述】:

从早期的 CodeIgniter 到现在一直困扰着我的一个问题,随着新的 CI 3,我想看看是否有更优雅的方法来解决它。

// 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();
   }
}

然后,在后面的代码中,我需要动态获取和设置 $GLO 变量的值。比如:

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

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

将打印正确的array('foo'=>'bar, 'arr'=>Array())。同样在我的模型中,我可以以相同的方式获取 $GLO 数组的值。但是,只要我需要在 $GLO 数组中设置任何值,我就会得到Indirect modification of overloaded property notice,所以我被卡住了。在我的模型中(执行数据库查询后):

// 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
}

关于如何使用$this-&gt;GLO['foo'] = 'baz'; 在我的模型中设置此全局数组的属性的任何线索?

干杯。

【问题讨论】:

  • MY_Controller GLO和CI_Model GLO是什么关系?我没听懂。
  • 这个想法是在控制器中声明一个全局变量,并在应用程序的其他控制器和模型中使用它。 $this->GLO 应该在整个应用程序中引用同一个公共 $GLO。
  • 但是您将其定义为 My_Controller 类范围。看起来这就是为什么您无法从模型范围内访问它的原因。查看更多关于类的信息,$this 变量。 $this 不是全局变量。
  • 似乎我可以读取 var,但我无法设置 var - 尽管它在不同的范围内?嗯..

标签: php arrays codeigniter oop


【解决方案1】:

我多次偶然发现这个问题。既然你要求一个优雅的解决方案 - 我试着给你一些想法。

有一个名为 Registry 的库,它编写得非常好,可以随时扩展。你可以找到图书馆here

把它放在你的库文件夹中。 这个库应该被自动加载,所以它总是可用的。 将其添加到您的 config/autoload.php

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

之后,您应该有一种非常简单的方法在 CI 中全局存储东西 - 例如,在您的代码中,它看起来像

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");

    }
}

【讨论】:

  • 感谢您的提示!在尝试了这门课之后,我做了一些肮脏的事情:)。看我的回答。
【解决方案2】:

sintakonte,非常感谢您的提示。昨晚我不得不重写很多代码来看看它是否以及如何工作。 Registry 类按预期工作!这个 set/get 方法的唯一问题是处理深度数组,尤其是那些动态创建的并且它们的数据也动态推送的数组。所以今天早上我做了一件非常糟糕的事情:) 刚刚创建了这个类:

class Globals {
  public $data = array();
}

所以现在我要从 $this-&gt;GLO['foo'] 转到 $this-&gt;globals-&gt;data['foo'] 并保持现有语法不变!它还使我能够以不同的名称在不同的控制器模型中重用该类,一次将其初始化为“全局”,另一次初始化为“管理员”。似乎也可以正常工作!

【讨论】:

  • 呵呵,如果它嵌入为库,它就不会脏;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-23
  • 1970-01-01
  • 2012-05-16
  • 1970-01-01
  • 2019-06-15
  • 2012-03-02
相关资源
最近更新 更多