Search code examples
phpnamespacesautoload

PHP's "use" Keyword and Autoloading


My question is in three parts:

  1. Does putting in a use statement trigger the autoloader immediately, or does it wait until the class is used? (lazy-loading)

  2. If autoloading isn't done in a lazy-load fashion, could that negatively affect performance?

  3. Which pattern is best to follow, and why? PhpStorm shows "Unnecessary fully qualified name..." as a code issue when the use statement isn't employed.

Here's an example class definition for a Laravel controller with a use statement:

namespace App\Http\Controllers;

use Carbon\Carbon;

class FooController extends Controller
{
    /**
     * This action uses the Carbon class
     */
    public function bar1()
    {
        return view('foo.bar1', ['now' => new Carbon()]);
    }

    /**
     * This action does not use the Carbon class
     */
    public function bar2()
    {
        return view('foo.bar2');
    }
}

The same class without the use statement:

namespace App\Http\Controllers;

class FooController extends Controller
{
    /**
     * This action uses the Carbon class
     */
    public function bar1()
    {
        return view('foo.bar1', ['now' => new \Carbon\Carbon()]);
    }

    /**
     * This action does not use the Carbon class
     */
    public function bar2()
    {
        return view('foo.bar2');
    }
}

Solution

  • 1) The class is autoloaded when you perform a new Class() statement.

    2) see 1)

    3) Which pattern is best to follow and why?:

    I'd recommend to use use because you might get into a situation where you have really long namespaces and your code will become unreadable.

    From the php docs:

    This example attempts to load the classes MyClass1 and MyClass2 from the files MyClass1.php and MyClass2.php respectively.

    <?php
    spl_autoload_register(function ($class_name) {
        include $class_name . '.php';
    });
    
    $obj  = new MyClass1();
    $obj2 = new MyClass2(); 
    ?>
    

    Namespaces are only an additional feature to organize classes.

    EDIT: As @IMSoP pointed out in the comments, new is not the only time the autoloader is triggered. Accessing a class constant, static method, or static property will also trigger it, as will running class_exists.