Chris Muench February 2016

lazy load models and libraries in CI 3 __get magic method of controller

I am attempting to write a lazy loader for models + libraries in CI 3.0.4

I am trying to get the following as described in:

Model/library lazy load in CodeIgniter

This code seems to be for CI version 2 and when I tried to apply it to CI version 3.0.4 I get the following errors.

Severity: Notice

Message: Indirect modification of overloaded property Items::$benchmark has no effect

Filename: core/Controller.php

Line Number: 75


Fatal error: Cannot assign by reference to overloaded object in /Applications/MAMP/htdocs/phppos/PHP-Point-Of-Sale/system/core/Controller.php on line 75

Here is what I did:

  1. Create file application/core/MY_Controller.php

  2. Create the following code:

        //Lazy load based on http://stackoverflow.com/questions/17579449/model-library-lazy-load-in-codeigniter
        function __get($name)
        {
           if (isset($this->$name) && $this->$name instanceof CI_Model) 
            {
                  return $this->$name;
            }
        }
      }
    

Once I can get this to work without errors; I will add my custom logic to load the right model or library.

I want to do this WITHOUT modifying core.

Answers


Chris Muench February 2016

Based on example I have come up with the following that does NOT require core modifications and works in CI 3.0.4. It first tries to load a model and if the model does NOT exist it attempts to load a library.

  1. Create file application/core/MY_Controller.php

  2. Put these contents in it.

    <?php
    class MY_Controller extends CI_Controller 
    {
    
        //Lazy loading based on http://stackoverflow.com/questions/17579449/model-library-lazy-load-in-codeigniter
        public function __construct()
        {
            foreach (is_loaded() as $var => $class)
            {
                 $this->$var = '';
            }
    
            $this->load = '';
            parent::__construct();
        }
    
    
        // Lazy load models + libraries....If we can't load a model that we have; then we will try to load library $name
        public function __get($name)
        {
            //Cache models so we only scan model dir once
    
            static $models = FALSE;
            $this->load->helper('file');
    
            if (!$models)
            {
                $model_files = get_filenames(APPPATH.'models', TRUE);
                foreach($model_files as $model_file)
                {
                    $model_relative_name = str_replace('.php','',substr($model_file,strlen(APPPATH.'models'.DIRECTORY_SEPARATOR)));
                    $model_folder = strpos($model_relative_name, DIRECTORY_SEPARATOR) !== FALSE ? substr($model_relative_name,0,strrpos($model_relative_name,DIRECTORY_SEPARATOR)) : '';
                    $model_name = str_replace($model_folder.DIRECTORY_SEPARATOR, '',$model_relative_name);
    
                    $models[$model_name] = $model_folder.'/'.$model_name;
                }
            }
    
            if (isset($models[$name]))
            {
                $this->load->model($models[$name]);
                return $this->$name;
            }
            else //Try a library if we cannot load a model
            {
                $this->load->library($name);
                return $this->$name;
            }
    
            return NULL;
        } 

Post Status

Asked in February 2016
Viewed 1,877 times
Voted 4
Answered 1 times

Search




Leave an answer