title: Dependancy Injection where virtualy every class is dependant on several others
body: <p>I'm trying to implement best practices while learning PHP OOP. I understand the concept, but kind of doubt with proper implementation. As I'm trying to figure out the basic implementation principle, I'm not implementing DI container in this piece of code.</p>
  
  <h2><strong>Structure</strong></h2>
  
  <ul>
  <li><p><strong>Db</strong> class for database connection.</p></li>
  <li><p><strong>Settings</strong> class, retrieve settings from db.   </p></li>
  <li><p><strong>Languages</strong> class, retrieving information for a specific language.</p></li>
  <li><p><strong>Page</strong> class, <strong>Product</strong> class, <strong>Customer</strong> class, and many more.</p></li>
  </ul>
  
  <h1>Idea</h1>
  
  <p><strong>Settings</strong> class needs <strong>Db</strong> class to retrieve settings.</p>
  
  <p><strong>Languages</strong> class needs both <strong>Db</strong> and <strong>Settings</strong> to retreive information based on settings from a database.</p>
  
  <p><strong>Page</strong> class needs <strong>Db</strong>, <strong>Settings</strong> and <strong>Languages</strong>. It may also need some other classes in the future.</p>
  
  <h2>Simplified code</h2>
  
  <p>Db.php extends PDO</p>
  
  <p>Settings.php</p>
  
  <pre><code>class Settings
  {
      /* Database instance */
      protected $db;
  
      /* Cached settings */
      private $settings   = array();
  
      public function __construct(Db $db)
      {
          $this-&gt;db = $db;
      }
  
      public function load ()
      {
          $selq = $this-&gt;db-&gt;query('SELECT setting, value FROM settings');
          $this-&gt;settings = $selq-&gt;fetchAll();
      }
  }
  </code></pre>
  
  <p>Languages.php</p>
  
  <pre><code>class Languages
  {
  
      public $language;
  
      protected $db;
      protected $settings;
  
      private $languages = array();
  
      public function __construct(Db $db, Settings $settings)
      {
          $this-&gt;db = $db;
          $this-&gt;settings = $settings;
          // set value for $this-&gt;language based on user choice or default settings
          ...
      }
  
      public function load() 
      {
          $this-&gt;languages = array();
          $selq = $this-&gt;db-&gt;query('SELECT * FROM languages');
          $this-&gt;languages = $selq-&gt;fetchAll();
      }
  
  }
  </code></pre>
  
  <p>Page.php</p>
  
  <pre><code>class Page
  {
      protected $db;
      protected $settings;
      protected $language;
  
      public function __construct(Db $db, Settings $settings, Languages $languages)
      {
          $this-&gt;db = $db;
          $this-&gt;settings = $settings;
          $this-&gt;languages = $languages;
      }
  
      public function load() 
      {
          // load page info from db with certain settings and in proper language
          ...
      }
  
  }
  </code></pre>
  
  <p>Config.php</p>
  
  <pre><code>$db = new Db;
  
  /* Load all settings */
  $settings   = new Settings($db);
  $settings-&gt;load();
  
  /* Load all languages */
  $languages  = new Languages($db, $settings);
  $languages-&gt;load();
  
  /* Instantiate page */
  $page   = new Page($db, $settings, $languages);
  </code></pre>
  
  <p>I don't like the idea of injection same classes over and over again. This way, I'll get to the point, where I'll need to inject 10 classes. So, my code is wrong from the beginning.</p>
  
  <p>Maybe, a better way is to do the following:</p>
  
  <p>Config.php</p>
  
  <pre><code>$db = new Db;
  
  /* Load all settings */
  $settings   = new Settings($db);
  $settings-&gt;load();
  
  /* Load all languages */
  $languages  = new Languages($settings);
  $languages-&gt;load();
  
  /* Instantiate page */
  $page   = new Page($languages);
  </code></pre>
  
  <p>as Settings already have access to $db, and $languages to both $db and $settings.
  However in this manner, I'll have to make calls like $this->languages->settings->db->...</p>
  
  <p>All my code architecture seems to be completely wrong :)
  How it should be done?</p>