Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Autoloading on Autopilot

Autoloading on Autopilot

Autoloading is a wonderful feature in PHP that allows you to automatically include the files that your classes are in as they are referenced. Let's talk about how it works, how to do it, and all that goes with it, including namespaces, PSR standards, and Composer. Hopefully by the end of this discussion, autoloading will be so easy for you that it will feel like it's on autopilot.

Jeremy Lindblom

August 11, 2015
Tweet

More Decks by Jeremy Lindblom

Other Decks in Programming

Transcript

  1. a.php CODE CODE include ‘b.php’; CODE Includes = Why I

    Started Using PHP b.php CODE CODE CODE CODE Executed code CODE CODE CODE CODE CODE CODE CODE
  2. include include_once require require_once Including vs. Requiring On errors: include

    ➔ E_WARNING require ➔ E_COMPILE_ERROR “once”: Only loads file if you haven’t loaded it before.
  3. Including Classes - Not Fun <?php // NOTE: Assuming one

    class per file require_once(‘classes/user.class.php’); require_once(‘classes/page.class.php’); require_once(‘classes/role.class.php’); require_once(‘classes/db.class.php’); // ...
  4. The Bottom Line Explicit includes/requires are: 1. Necessary and helpful

    for procedural code. 2. Cumbersome and harmful for object- oriented code.
  5. What is an Autoloader? 1. A callback triggered when a

    non-existent class is referenced.
  6. What is an Autoloader? 1. A callback triggered when a

    non-existent class is referenced. 2. A function that provides a definition for a specified class name.
  7. What is an Autoloader? 1. A callback triggered when a

    non-existent class is referenced. 2. A function that provides a definition for a specified class name. “Providing a definition” can mean: • Loading a class from a file (include/require) • Dynamically creating a class (eval) • Aliasing an existing class (class_alias)
  8. Autoloader Advantages • Classes are loaded on demand ◦ No

    need to write specific include statements ◦ Class never loaded unless it’s needed • Leads to better code maintainability • Easy to write
  9. The Old Way – Includes everywhere require_once(‘classes/user.class.php’); require_once(‘classes/page.class.php’); // ...

    $page = Page::forTemplate(‘profile’); $page->set(‘user’, User::fetchById(5));
  10. Autoloading to the Rescue function __autoload($class) { $file = strtolower($class).‘.class.php’;

    require(‘classes/’.$file); } $page = Page::forTemplate(‘profile’); $page->set(‘user’, User::fetchById(5));
  11. Autoloading to the Rescue function __autoload($class) { $file = strtolower($class).‘.class.php’;

    require(‘classes/’.$file); } $page = Page::forTemplate(‘profile’); $page->set(‘user’, User::fetchById(5)); WHY NOT USE require_once?
  12. Implicit “Once” Autoloaders are only triggered if the specified class

    is not loaded, So… The “_once” is implied, since once you load a class, the autoloader won’t be called again.
  13. Implicit “Once” No need for these: • include_once • require_once

    Don’t use them anymore for loading classes.
  14. Please Use spl_autoload_register • Added in PHP 5.1.2 • Can

    register multiple autoloaders ◦ Allows third-party libraries to provide their own! • Can add an autoloader to the front or back of the autoloader queue • Any use of __autoload gets superceded by spl_autoload_register
  15. Please Use spl_autoload_register spl_autoload_register(function ($c) { if ($c === ‘Foo’)

    require ‘lib/foo.inc’; }); spl_autoload_register(function ($c) { $path = ‘classes/’.strtolower($c).‘.class.php’; if (file_exists($path)) require $path; });
  16. Errors in Autoloaders Do not throw exceptions or trigger errors

    in an autoloader. Give the rest of the chain a chance.
  17. Namespaces • Added in PHP 5.3 • Prevents naming collisions

    • Syntax: ◦ Before Namespaces: Zend_Http_Client ◦ With Namespaces: Zend\Http\Client • Allows aliasing
  18. • FIG = Framework Interop Group • PSR - PHP

    Standards Recommendation ◦ Autoloading: PSR-0, PSR-4 ◦ Others: ▪ PSR-1, PSR-2 - Coding style ▪ PSR-3 - Logging interface ▪ PSR-7 - HTTP message interface PHP-FIG
  19. Composer - “Dependency Manager for PHP” • Installs dependencies (a.k.a.

    third-party libraries) into your project. • Creates an autoloader capable of autoloading everything in your project.
  20. Setting up Autoloading w/ Composer Your files: Project/ |- README

    |- composer.json |- src/ |- Foo.php (contains SeaPhp\Example\Foo) |- Bar.php (contains SeaPhp\Example\Bar)
  21. Autoloading on Autopilot w/ Composer In your index.php: <?php require

    ‘vendor/autoload.php’; use SeaPhp\Example\Foo; $foo = new Foo;
  22. Classmap Autoloading spl_autoload_register(function ($c) use ($paths) { if (isset($paths[$c])) require

    $paths[$c]; }); // vs. spl_autoload_register(function ($c) { $path = str_replace(‘\\’, ‘/’, $class); if (file_exists($path)) require $path; });
  23. Summary of Best Practices 1. Don’t use include_once or require_once

    2. Use spl_autoload_register, not __autoload 3. Don’t throw exceptions in autoloaders 4. One class per file 5. Namespaces/classes match directories/files 6. Follow PSR-4 (or PSR-0) 7. Use Composer, even if no dependencies 8. Use classmap autoloaders in production