real ultimate waffe (.net)

WordPress __autoload() idea

Advertisements

PHP 5 introduces autoloading classes. The way WordPress is currently structured, I don’t think we’d get much benefit from switching to autoloading. There aren’t that many classes in core WordPress that don’t need to get loaded on every page load.

With some restructuring, though, we might be able to cut down on the number of bytes of code we load on every page (and we could get rid of some class_exists() and require_once calls).

We’d want an autoloader, though, that could handle plugin files as well as core files.

Idea: an autoloader that can load classes from some deterministic path (e.g., the usual $classname.class.php or what have you) but that can also register classes at specific paths.


if ( !defined( 'WP_AUTOLOAD_CLASSES' ) ) {
    define(
        'WP_AUTOLOAD_CLASSES',
        function_exists( 'spl_autoload_register' )
    );
}

if ( WP_AUTOLOAD_CLASSES ) {
   /**
<ul>
  <li>PHP 5.1.2+</li>
<li>Called once per class during setup (each time</li>
<li>with two args) to tell it where the class is</li>
<li>located.</li>
<li>Don't need to call for a class if that class</li>
<li>exists in some easy deterministic path.</li>
<li>Called (with only one arg) when looking for a</li>
<li>not-currently-loaded class.</li>
<li>/</li>
</ul>

    function wp_autoload( $class, $path = null ) {
        static $classes = array();

        // Being called by PHP's autoloader
        if ( is_null( $path ) ) {
            if ( isset( $classes[$class] ) ) {
               /* Use include, not require.  That
<ul>
  <li>way we get a more meaningful</li>
<li>Fatal error: class does not exist</li>
<li>/</li>
</ul>

                include( $classes[$class] );
            } else {
               /* Look in some default path(s) for
<ul>
  <li>appropriately named files.</li>
<li>/</li>
</ul>

            }
            return;
        }

        // Being called by us
        $classes[$class] = $path;
    }
    
    // Register it
    spl_autoload_register( 'wp_autoload' );
} else {
   /**
<ul>
  <li>PHP 4 (PHP 5.1.1-)</li>
<li>Just require each file.</li>
<li>/</li>
</ul>

    function wp_autoload( $class, $path ) {
        require_once( $path );
    }
}

// Core classes in WPINC probably wouldn't have
// to be explicitly registered, but as an example:
wp_autoload(
    'WP_Error',
    ABSPATH . WPINC . '/classes.php'
);
// OK to call multiple times per path
wp_autoload(
    'Walker',
    ABSPATH . WPINC . '/classes.php'
);
// ...

// In some plugin file
wp_autoload(
    'My_Plugin_Foo',
    plugin_dir_path( __FILE__ ) . 'foo.class.php'
);

Update: To clarify, I don’t mean to imply that this idea would improve WordPress performance. It’s just an idea, not a proposal. I haven’t done any benchmarking or even naive experimentation.

Conditionally including files involves tradeoffs that need to be evaluated per app. Also, as Jacob Santos points out in the comments below, conditionally including files from conditionally defined functions is way out there.

I might call the idea clever, but it’s not necessarily good 🙂

Advertisements

Advertisements