title: php: Class lazy-loading?
body: <p>I have a problem here, which I have been thinking about for the past few days.
  In a php application to do something with a object you need to:</p>
  
  <ol>
  <li>define it</li>
  <li>run a function with it
  like so:
  (with autoloading, and a registry object)</li>
  <li>$registry->obj = new mathClass($var1,$var2); //creates object where $var1 holds the a database object, and $var2 holds the value 1 for example</li>
  <li>$registry->obj->calculate('value'); //fetches product rows and returns their total value.
  This way at any time in the script i can simply run the calculate function (or some other function) that I defined beforehand.</li>
  </ol>
  
  <p>Imagine a web application that has hundreds of classes that might or might not be required for this specific page load, but can only be defined at the start of the application.
  The desired solution is that I simply run </p>
  
  <pre><code>$obj-&gt;calculate('price'); 
  </code></pre>
  
  <p>without creating the object, for example like this </p>
  
  <pre><code>mathclass::calculate('price'); 
  </code></pre>
  
  <p>this then autoloads the mathclass as required without having the principal overhead, the problem here is that I can no longer give the mathclass any variables at the start </p>
  
  <pre><code>($var1,$var2).
  </code></pre>
  
  <p>What I want is to be able to pseudo-create the object without any autoloading of the class happening, as to not add the overhead, but that the object creates itself with the variables but only when I actually need to do something with it.</p>
  
  <p>I mean does php really expect me to define each and every class at the start so that I can later use them?
  is this Lazy-loading? Eager loading?</p>
  
  <p>I might be explaining this badly so please point me in the right direction.</p>
  
  <h2>Edit 2015: Simple pseudocode example solution:</h2>
  
  <pre><code>class Service {
      private $cb, $instance;
      public function __construct($cb){
          $this-&gt;cb = $cb;
      }
      public function __invoke() {
          if(!$this-&gt;instance){
              $this-&gt;instance = call_user_func($this-&gt;cb);
          }
          return $this-&gt;instance;
      }
  }
  
  // setup autoloading
  set_include_path(__DIR__.'/vendor'. PATH_SEPARATOR .get_include_path()); // optional
  spl_autoload_register(function($c){
      include preg_replace('#\\\|_(?!.+\\\)#','/',$c).'.php';
  });
  
  // simple dependency injection
  $service['db'] = new Service(function(){
      return new Database('sqlite::filename.sqlite');
  });
  $service['config'] = function() use(&amp;$service){
      return new Config($service['db']());
  };
  $service['math'] = function() use(&amp;$service){
      return new Math($service['config']());
  };
  
  // usage
  $service['math']()-&gt;calculate('price');
  </code></pre>