PHP - avoid many on-demand imports I'm trying to create small PHP framework for my own needs (and likes). However there are questions for which I may need advice of more wise and experienced people before things became too complicated - so I moved it to github from private repo.

Currently I'm curious about organizing imports of modules better. I use the special object, "context" - to hold links to all necessary modules - data access objects, utils etc. I use lazy initialization here, so that when field of this object is required, it is provided by the getter of the same name.

It looks like:

class ProtoContext {

    function __get($name) {
        $methodName = 'get' . ucfirst($name);
        if (!method_exists($this, $methodName)) {
            throw new Exception("No property '$name' in Context!");
        }
        $res = $this-&gt;$methodName();
        if (is_object($res)) {
            $res-&gt;ctx = $this;
        }
        $this-&gt;$name = $res;
        return $res;
    }

    protected function getElems() {
        return Elems::$elems;
    }

    protected function getUtil() {
        module('sys/Util');
        return new Util();
    }

}


main Context class is inherited from this ProtoContext, though it is not significant now. With the grow of application context may look like this:

module('sys/ProtoContext');

class Context extends ProtoContext {

    protected function getAuth() {
        module('MyAuth');
        return new MyAuth();
    }

    protected function getUsersDao() {
        module('dao/MysqlDao');
        return new MysqlDao('users');
    }

    protected function getRolesDao() {
        module('dao/MysqlDao');
        return new MysqlDao('roles');
    }

    /*
     * 5-10 more similar methods 'getSomethingDao'    
     * each including MysqlDao via method 'module'
     */

    protected function getLinksCViewDao() {
        module('dao/MysqlDao');
        return new MysqlDao('linksc_view');
    }

}


There is no problem that module method may be called several times, include is performed once only. However it looks annoying that inclusion of MysqlDao is mentioned so many times. On the other hand if I pull it above the class (like import of ProtoContext) it will be imported even if I need it not. For example when addressing $ctx->auth field (which will call getAuth method).

I wonder, whether here is comfortable workaround which will preserve lazy load and lazy initialization - and at the same time will allow to get rid of extra imports?
As N.B. mentioned in their comment - why are you implementing a module method if we already have lazy loading via autoloading? I've even written a class that you can simply attach and not have to worry about loading your classes. Now, there are better autoloaders out there - like Symphony's ClassLoader/autoload.php. Anyways, here's your code, with my LazyLoader class handling the loading of methods (untested code). 

/LazyLoader.php


/**
 * LazyLoader
 * A fast, strict lazy loader (time ~ 0.0001)
 * 
 * Class name must match File name.
 * If class has namespace, must be called via namespace.
 *
 * @author Juan L. Sanchez &lt;juanleonardosanchez.com&gt;
 * @license MIT
 * @version 1.2.0
 * @internal 06.26.2013
 */

Namespace LazyLoader;

class LazyLoader{
    public static $dirRoot;

    public static function autoload($class_name){
        $file = dirname(__FILE__) . 
                (strlen(self::$dirRoot) &gt; 0 ? self::$dirRoot : "") . 
                '/' . array_pop(explode("\\", $class_name)) . '.php';

        file_exists($file) ? require_once($file) : "";
    }

    public static function SetBaseDirectory($directory_root){
        self::$dirRoot = substr($directory_root, -1) == "\\" ? 
                         substr($directory_root, 0, -1) : "";
    }

    public static function Register(){
        return spl_autoload_register(__NAMESPACE__ .'\LazyLoader::autoload');
    }
}

$LazyLoader = new LazyLoader;
$LazyLoader-&gt;SetBaseDirectory("Classes"); # Optional
$LazyLoader-&gt;Register();


/Context.php

&lt;?php
module('sys/ProtoContext');

class Context extends ProtoContext {

    protected function getAuth() {
        return new MyAuth();
    }

    protected function getUsersDao() {
        return new MysqlDao('users');
    }

    protected function getRolesDao() {
        return new MysqlDao('roles');
    }

    /*
     * 5-10 more similar methods 'getSomethingDao'    
     * each including MysqlDao via method 'module'
     */

    protected function getLinksCViewDao() {
        return new MysqlDao('linksc_view');
    }

}


The directory structure of the above code would look something like:

/LazyLoader.php
/Context.php
/Classes/MyAuth.php
/Classes/ProtoContext.php
/Classes/MysqlDao.php