Search code examples
phpmagic-methods

PHP Magic methods


My question revolves arround magic methods.

This is a little example:

$context = new Context('Entities.xml');
$user_array = $context->Users;
$user = $context->Users->find(array('name' => 'John Smith'));

The second line returns an array with all user objects in it. The third line returns only the User object of the user called John Smith.

I wondered if this would be possible, the tricky part is that I don't know the properties of the Context class. They are generated from an xml file the user supplies upon instantiation and are accessable through magic getters and setters.

Context example(not complete, just to give an idea):

class Context {
   private $path, $entities;

   public function __construct($path) {
      $this->path = $path;
   }

   public function __get($name) {
      return $entities[$name];
   }

   public function __set($name, $arg) {
      $entities[$name] = $arg;
   }
}

Solution

  • Because I really needed a solution I implemented the following solution.

    The getters of the Context class return a ResultLayer class that handles the results.

    Example:

    class ResultLayer implements IteratorAggregate {
        public $data = array();
        private $entity, $context;
    
        public function __construct($context, $entity) {
            $this->context = $context;
            $this->entity = $entity;
        }
    
        public function getIterator() {
            return new ArrayIterator($this->data);
        }
    
        public function get($index) {
            return $this->data[$index];
        }
    
        public function toArray() {
            return $this->data;
        }
    
        public function find($properties) {
            return $this->context->getEntity($this->entity, $properties);
        }
    }
    

    I have implemented the IteratorAggregate interface so that you can use a foreach loop to for example go through $Context->Users this makes the code more readable.

    If anyone has a better approach, I'm still open to it. Any help is much appreciated!