title: PHP - How should the controller communicate data with the model layer in a proper MVC pattern
body: <p>I have been researching so many times, asking experts on stackoverflow for the best practice, but I still could not find the solution, I might have got told the correct answer, but I didn't get it.</p>
  
  <p>I always wanted to create a '<em>proper</em>' MVC pattern to work on my projects, I have been researching for example this <a href="http://www.phpro.org/tutorials/Model-View-Controller-MVC.html" rel="nofollow noreferrer">http://www.phpro.org/tutorials/Model-View-Controller-MVC.html</a> but I got told that this is awful design, and I should not use the registery pattern anymore.</p>
  
  <p>So I looked at teresko's answer, even though it's very old, can be seen here <a href="https://stackoverflow.com/questions/5863870/how-should-a-model-be-structured-in-mvc">How should a model be structured in MVC?</a> and I got the idea there, to use a global factory, which will create other factories</p>
  
  <p>The idea I got from there, is to have a big factory, called <code>ServiceFactory</code> which will create  instances of other factories like ModelFactory which will create instances of classes that are serving the model layer, and a ViewFactory, which will serve the view (Pretty useless at the moment I think).</p>
  
  <p>But got something like this:</p>
  
  <pre><code>namespace library\application;
  
  use library\application\exceptions\ClassNotFoundException;
  use library\application\exceptions\PackageNotFoundException;
  
  class ServiceFactory {
  
      private $mapper;
      private $package;
      private $services = array();
  
      public function __construct(DataMapper $mapper) {
          $this-&gt;mapper = $mapper;
      }
  
      /**
       * Setting a default package
       * @param $package  string  Package path
       * @throws exceptions\PackageNotFoundException
       */
  
      public function setDefaultPackage($package) {
          if (is_dir('library' . $package)) {
              $this-&gt;package = 'library' . $package;
              return;
          }
          throw new PackageNotFoundException("The package: " . $package . " was not found.");
      }
  
      /**
       * @param $name string  Class name
       * @param null $constructor IF the class needs constructor parameters, use it.
       * @return Factory
       * @throws exceptions\ClassNotFoundException
       */
  
      public function create($name, $constructor = null) {
          $path = $this-&gt;package . "\\" . $name;
          if (file_exists($path)) {
              if ($constructor) {
                  return new $path($constructor);
              }
              return new $path;
          }
          throw new ClassNotFoundException("The requested class was not found: " . $path);
      }
  
      /**
       * @param $name     string  Class name
       * @param $object   object  Object to register
       */
  
      public function register($name, $object) {
          $this-&gt;services[$name] = $object;
      }
  
      /**
       * @param $name string Class name
       * @return Factory
       */
  
      public function get($name) {
          if (isset($this-&gt;services[$name])) {
              return $this-&gt;services[$name];
          }
          return null;
      }
  }
  </code></pre>
  
  <p>This is awesome actually, but in my opinion, OO-wise, it's totally wrong, because it's not object-oriented friendly, since the returning object of S <code>ServiceFactory::create()</code> is anonymous, well fine, It's no longer anonymous, because the purpose of the class is to create instances of factories, sure, just added the interface of the factories in return. </p>
  
  <p><strong>But now the next problem,</strong> when I want to use the factories to create objects, that should not have the same interface, will cause problems to my IDE, since it doesn't know what is the object I am going to return, it can be Foo, can be Car and one day it can be HelloWorld.</p>
  
  <p>So I always will have to declare a variable with the object when using it in the controller:</p>
  
  <pre><code>    /**
       * @var $items  Items
       * @var $categories CategoryModel
       */
  
      $items = parent::getModelFactory()-&gt;create('Items');
      $items-&gt;setDb(parent::getDatabase());
      $categories = parent::getModelFactory()-&gt;create('Categories');
      $categories-&gt;setDb(parent::getDatabase());
  </code></pre>
  
  <p>Now in one of <code>Teresko</code>'s answer(s), it says the following rule: <code>A controller can not create instances of the Model layer</code></p>
  
  <p>So I assume he means like <code>$foo = new Foo(); $foo-&gt;method($db);</code> in the controller, but why not? how should a controller actually communicate the model layer?</p>
  
  <p>The main purpose of me creating that god factory class, is to prevent doing <code>new Object()</code> in the controller class, but since it's calling the factory, which creates the instance, it's still considered as I am creating an instance of a model layer in a controller (I think).</p>
  
  <p>I also could cache objects, using <code>ServiceFactory::register()</code> method, but that doesn't change the situation.</p>
  
  <p>So is the <code>ServiceFactory</code> and factories idea fine ? What is the correct way communcating between the controller and the model layer? </p>