Multiplay Labs

tech hits and tips from Multiplay

Archive for October 10th, 2010

PHP class_exists fails to return for missing dependent classes

without comments

If you call class_exists( $sClass ) which in turn triggers an autoloader that fails to load a dependent class of $sClass e.g. where $sClass extends a missing class, then class_exists fails silently and never returns.

Note this only fails on missing dependent classes if the original class fails to load then class_exists returns false as expected.

The following code demonstrates the bug:
AutoLoader.php:

<?php
class AutoLoader
{
    // Public Methods
    public static function factory( $sClass )
    {
        error_log( "factory: $sClass" );
        if ( class_exists( $sClass ) )
        {
            error_log( "Class Exists" );
            return new $sClass;
        }
        error_log( "Failed to autoload: $sClass" );
        return null;
    }
    public static function autoload( $sClass )
    {
        // NOTE: its unclear if the return codes of autoload functions are ever used?
        error_log( "autoload: $sClass" );
        if ( class_exists( $sClass, false ) )
        {
            error_log( "Already loaded" );
            return true;
        }
        error_log( "including: $sClass" );
        $iRet = @include_once( "$sClass.php" );
        error_log( "included: $iRet for $sClass, " . class_exists( $sClass, false ) );
 
        return class_exists( $sClass, false );
    }
}
 
// Register our Autoloader
spl_autoload_register( array( 'AutoLoader', 'autoload' ) );
 
$oMyClass = AutoLoader::factory( 'MyClass' );
if ( $oMyClass )
{
    error_log( "Got object:" . get_class( $oMyClass ) );
}
else
{
    error_log( "Failed to load 'MyClass'" );
}
?>

MyClass.php

<?php class MyClass extends MyBaseClass {} ?>

This bug is registered here: http://bugs.php.net/bug.php?id=53036

Written by Dilbert

October 10th, 2010 at 4:22 pm

Posted in Code,PHP