Search code examples
phpmodelscontrollers

Creating dynamic property in a object


I used cakePHP which has a nice feature where the model (if present is already created as a property within your controllers, so effectively I would have access to a property named $this->model_name within my controller without having the create an instance of the model object.

From what I understand all properties must be defined in a class to be able to use it, so is there another way for me to be able to complete the above?

  // Sample code:
  <?php
  class controller {
        public function create_model($model_name) {
              // Assuming that I have spl_autoload enabled to achieve the below:
              $this->$$model_name = new model_name();      
        }
  }

Solution

  • You can do things like this with magic methods (check out _set() and _get() )

    Here is some sample code:

    class Controller
    {
        protected $models;
    
        public function __get($key)
        {
            return $this->models[$key];
        }
    
        public function __set($key, $value)
        {
            $this->models[$key] = $value;
        }
    }
    

    You can implement your own functionality in __set() and __get(). You can set data with $this->my_model = $something;.

    Here is something that's more tailored to your specific example:

    public function __get($key) // you will only need __get() now
        {
    
            if (array_key_exists($key, $this->models) && $this->models[$key] instanceof $key) { 
                return $this->models[$key];
            } else {
                $this->models[$key] = new $key;
                return $this->models[$key];
            }
    
        }
    

    So now, $this->my_model with try to instantiate my_model if it doesn't exist, and return the current object if it exists. Maybe not the best solution, but added it here so you can understand how it works.