Search code examples
phpsplautoloaderspl-autoload-register

class_exists is calling spl_autoload_register


I create a simple script for autoload classes, but when I use class_exists the spl_autoload_register is executed, example:

<?php
function autoLoadClass($name) {
    echo 'spl_autoload_register: ', $name, '<br>';
}

spl_autoload_register('autoLoadClass');

class_exists('Foo');
class_exists('Bar');
class_exists('Foo\\Bar');

Output:

spl_autoload_register: Foo
spl_autoload_register: Bar
spl_autoload_register: Foo\Bar

Is that right? Is there any way to make "spl_autoload" ignore calls "class_exists"?


Solution

  • You can make class_exists not call autoloading.
    From the manual:

    bool class_exists ( string $class_name [, bool $autoload = true ] )

    So a call like:

    class_exists('Foo', false);

    would ignore autoloading.

    [ Demo ]

    It is also possible to make the autoloading function ignore calls from class_exists by (ab)using debug_backtrace, but that method is ugly and really slow, but for the sake of completeness, here's how to do it:

    function autoLoadClass($name) {
        foreach(debug_backtrace() as $call) {
            if(!array_key_exists('type', $call) && $call['function'] == 'class_exists') {
                return;
            }
        }
        echo 'spl_autoload_register: ', $name, '<br>';
    }
    

    (Note: This doesn't seem to work in HHVM)

    That basically aborts the function if one of the calling functions is called class_exists, and the $call['type'] must not exist to make sure that calls like SomeClass::class_exists and $someObject->class_exists are filtered out.

    [ Demo ]