Implementation Analysis of composer Automatic Loading in Laravel Framework

  • 2021-08-21 19:52:36
  • OfStack

Foundation

Auto-load allows you to load the required class files in a ready-to-use way without having to write tedious require and include statements every time. Therefore, the execution process of each request only loads the necessary classes, and does not care about the loading of classes, as long as it is needed to use it directly.

The laravel framework is automatically loaded through composer.

Is implemented by the following code.


require_once __DIR__ . '/composer' . '/autoload_real.php';
return ComposerAutoloaderInit7b20e4d61e2f88170fbbc44c70d38a1f::getLoader();

First, we explain the functions spl_autoload_register and spl_autoload_unregister.

spl_autoload_register automatically registers one or more auto-load functions that run automatically when the class is instantiated.

spl_autoload_unregister is the opposite.

Paste the code of my experiment:

This is autoload. php


<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/12/7
 * Time: 14:10
 */
namespace app;
class Autoload {

 public function __construct()
 {
  $this->autoload();
 }
 public function autoload(){
  // spl_autoload_register(array('Autoload','ss'),true);  Will trigger a fatal error and must bring a namespace 
  spl_autoload_register(array('app\Autoload','ss'),true);
 }
 public function ss(){
  echo 666;
  exit;
 }
}

This is index. php


<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/12/7
 * Time: 14:10
 */
require 'autoload.php';
$autoload=new \app\Autoload();
$b=new B();//  The auto-load function runs automatically at this time 
echo 77;
exit;

Find the function getLoader and analyze it:


 public static function getLoader()
 {
  if (null !== self::$loader) {
   return self::$loader;
  }
  // Register auto-load functions, load or instantiate classes, run loadClassLoader Function 
  spl_autoload_register(array('ComposerAutoloaderInit7b20e4d61e2f88170fbbc44c70d38a1f', 'loadClassLoader'), true, true);
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
  spl_autoload_unregister(array('ComposerAutoloaderInit7b20e4d61e2f88170fbbc44c70d38a1f', 'loadClassLoader'));
/********************1********************************************************
  $map = require __DIR__ . '/autoload_namespaces.php';
  foreach ($map as $namespace => $path) {
   $loader->set($namespace, $path);
  }
  $map = require __DIR__ . '/autoload_psr4.php';
  foreach ($map as $namespace => $path) {
   $loader->setPsr4($namespace, $path);
  }
  $classMap = require __DIR__ . '/autoload_classmap.php';
  if ($classMap) {
   $loader->addClassMap($classMap);
  }
/********************1********************************************************
  $loader->register(true);  $includeFiles = require __DIR__ . '/autoload_files.php';  foreach ($includeFiles as $fileIdentifier => $file) {   composerRequire7b20e4d61e2f88170fbbc44c70d38a1f($fileIdentifier, $file);  }  return $loader; }}

/*****, mainly for the part in ClassLoader

$prefixesPsr0, $prefixDirsPsr4, $classMap, and so on. That is to say, load some configured files, and when loading or looking for files later, it is to look for them from the loaded configuration files. Finding the class to load is mainly realized by register function. Then the register function is analyzed.


public function register($prepend = false)
{
 spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}

It is found that the loadClass function in this class is actually registered as an auto-load function. So we began to analyze loadClass function, and finally searched for classes through findFile.


public function findFile($class)
{
///  Pay special attention   Parameter $class  Is generated according to the namespace class Name, please refer to namespace properties for details. 
 // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
 if ('\\' == $class[0]) {
  $class = substr($class, 1);
 }
 // class map lookup  First, from the loaded classMap  Search in 
 if (isset($this->classMap[$class])) {
  return $this->classMap[$class];
 }
 if ($this->classMapAuthoritative) {
  return false;
 }
//  Find the file from the configuration file just loaded. First follow  psr4  Find the rules, and then follow them psr0  Looking for 
//  The main difference between the two rules is the way to deal with underscores. 
 $file = $this->findFileWithExtension($class, '.php');
 // Search for Hack files if we are running on HHVM
 if ($file === null && defined('HHVM_VERSION')) {
  $file = $this->findFileWithExtension($class, '.hh');
 }
 if ($file === null) {
  // Remember that this class does not exist.
  return $this->classMap[$class] = false;
 }
 return $file;
}

At this point, the register function is analyzed. We then analyze the remaining code of the getLoader function.


$includeFiles = require __DIR__ . '/autoload_files.php';
foreach ($includeFiles as $fileIdentifier => $file) {
 composerRequire7b20e4d61e2f88170fbbc44c70d38a1f($fileIdentifier, $file);
}

This code actually loads the autoload_file. php file.

Summarize


Related articles: