Heim Backend-Entwicklung PHP-Tutorial PHP管理依赖(dependency)关系工具 Composer的自动加载(autoload)_PHP

PHP管理依赖(dependency)关系工具 Composer的自动加载(autoload)_PHP

May 31, 2016 pm 07:30 PM
autoload composer php 自动加载

举例来说,假设我们的项目想要使用 monolog 这个日志工具,就需要在composer.json里告诉composer我们需要它:

{
 "require": {
  "monolog/monolog": "1.*"
 }
}
Nach dem Login kopieren

之后执行:

php composer.phar install

Nach dem Login kopieren

好,现在安装完了,该怎么使用呢?Composer自动生成了一个autoload文件,你只需要引用它

require '/path/to/vendor/autoload.php';

Nach dem Login kopieren

然后就可以非常方便的去使用第三方的类库了,是不是感觉很棒啊!对于我们需要的monolog,就可以这样用了:

use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// create a log channel
$log = new Logger('name');
$log->pushHandler(new StreamHandler('/path/to/log/log_name.log', Logger::WARNING));
// add records to the log
$log->addWarning('Foo');
$log->addError('Bar');

Nach dem Login kopieren

在这个过程中,Composer做了什么呢?它生成了一个autoloader,再根据各个包自己的autoload配置,从而帮我们进行自动加载的工作。(如果对autoload这部分内容不太了解,可以看我之前的 一篇文章
)接下来让我们看看Composer是怎么做的吧。

对于第三方包的自动加载,Composer提供了四种方式的支持,分别是 PSR-0和PSR-4的自动加载(我的一篇文章也有介绍过它们),生成class-map,和直接包含files的方式。

PSR-4是composer推荐使用的一种方式,因为它更易使用并能带来更简洁的目录结构。在composer.json里是这样进行配置的:

{
  "autoload": {
    "psr-4": {
      "Foo\\": "src/",
    }
  }
}
Nach dem Login kopieren

key和value就定义出了namespace以及到相应path的映射。按照PSR-4的规则,当试图自动加载 "Foo\\Bar\\Baz" 这个class时,会去寻找 "src/Bar/Baz.php" 这个文件,如果它存在则进行加载。注意, "Foo\\"
并没有出现在文件路径中,这是与PSR-0不同的一点,如果PSR-0有此配置,那么会去寻找

"src/Foo/Bar/Baz.php"

这个文件。

另外注意PSR-4和PSR-0的配置里,"Foo\\"结尾的命名空间分隔符必须加上并且进行转义,以防出现"Foo"匹配到了"FooBar"这样的意外发生。

在composer安装或更新完之后,psr-4的配置换被转换成namespace为key,dir path为value的Map的形式,并写入生成的 vendor/composer/autoload_psr4.php 文件之中。

{
  "autoload": {
    "psr-0": {
      "Foo\\": "src/",
    }
  }
}
Nach dem Login kopieren

最终这个配置也以Map的形式写入生成的

vendor/composer/autoload_namespaces.php

文件之中。

Class-map方式,则是通过配置指定的目录或文件,然后在Composer安装或更新时,它会扫描指定目录下以.php或.inc结尾的文件中的class,生成class到指定file path的映射,并加入新生成的 vendor/composer/autoload_classmap.php 文件中,。

{
  "autoload": {
    "classmap": ["src/", "lib/", "Something.php"]
  }
}
Nach dem Login kopieren

例如src/下有一个BaseController类,那么在autoload_classmap.php文件中,就会生成这样的配置:

'BaseController' => $baseDir . '/src/BaseController.php'

Files方式,就是手动指定供直接加载的文件。比如说我们有一系列全局的helper functions,可以放到一个helper文件里然后直接进行加载

{
  "autoload": {
    "files": ["src/MyLibrary/functions.php"]
  }
}
Nach dem Login kopieren

它会生成一个array,包含这些配置中指定的files,再写入新生成的

vendor/composer/autoload_files.php

文件中,以供autoloader直接进行加载。

下面来看看composer autoload的代码吧

<&#63;php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit73612b48e6c3d0de8d56e03dece61d11
{
  private static $loader;
  public static function loadClassLoader($class)
  {
 if ('Composer\Autoload\ClassLoader' === $class) {
   require __DIR__ . '/ClassLoader.php';
 }
  }
  public static function getLoader()
  {
 if (null !== self::$loader) {
   return self::$loader;
 }
 spl_autoload_register(array('ComposerAutoloaderInit73612b48e6c3d0de8d56e03dece61d11', 'loadClassLoader'), true, true);
 self::$loader = $loader = new \Composer\Autoload\ClassLoader();
 spl_autoload_unregister(array('ComposerAutoloaderInit73612b48e6c3d0de8d56e03dece61d11', 'loadClassLoader'));
 $vendorDir = dirname(__DIR__); //verdor第三方类库提供者目录
 $baseDir = dirname($vendorDir); //整个应用的目录
 $includePaths = require __DIR__ . '/include_paths.php';
 array_push($includePaths, get_include_path());
 set_include_path(join(PATH_SEPARATOR, $includePaths));
 $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);
 }
 $loader->register(true);
 $includeFiles = require __DIR__ . '/autoload_files.php';
 foreach ($includeFiles as $file) {
   composerRequire73612b48e6c3d0de8d56e03dece61d11($file);
 }
 return $loader;
  }
}
function composerRequire73612b48e6c3d0de8d56e03dece61d11($file)
{
  require $file;
}

Nach dem Login kopieren

首先初始化ClassLoader类,然后依次用上面提到的4种加载方式来注册/直接加载,ClassLoader的一些核心代码如下:

/**
  * @param array $classMap Class to filename map
  */
 public function addClassMap(array $classMap)
 {
  if ($this->classMap) {
   $this->classMap = array_merge($this->classMap, $classMap);
  } else {
   $this->classMap = $classMap;
  }
 }
 /**
  * Registers a set of PSR-0 directories for a given prefix,
  * replacing any others previously set for this prefix.
  *
  * @param string  $prefix The prefix
  * @param array|string $paths The PSR-0 base directories
  */
 public function set($prefix, $paths)
 {
  if (!$prefix) {
   $this->fallbackDirsPsr0 = (array) $paths;
  } else {
   $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
  }
 }
 /**
  * Registers a set of PSR-4 directories for a given namespace,
  * replacing any others previously set for this namespace.
  *
  * @param string  $prefix The prefix/namespace, with trailing '\\'
  * @param array|string $paths The PSR-4 base directories
  *
  * @throws \InvalidArgumentException
  */
 public function setPsr4($prefix, $paths)
 {
  if (!$prefix) {
   $this->fallbackDirsPsr4 = (array) $paths;
  } else {
   $length = strlen($prefix);
   if ('\\' !== $prefix[$length - 1]) {
    throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
   }
   $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
   $this->prefixDirsPsr4[$prefix] = (array) $paths;
  }
 }
 /**
  * Registers this instance as an autoloader.
  *
  * @param bool $prepend Whether to prepend the autoloader or not
  */
 public function register($prepend = false)
 {
  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
 }
 /**
  * Loads the given class or interface.
  *
  * @param string $class The name of the class
  * @return bool|null True if loaded, null otherwise
  */
 public function loadClass($class)
 {
  if ($file = $this->findFile($class)) {
   includeFile($file);
   return true;
  }
 }
 /**
  * Finds the path to the file where the class is defined.
  *
  * @param string $class The name of the class
  *
  * @return string|false The path if found, false otherwise
  */
 public function findFile($class)
 {
  //这是PHP5.3.0 - 5.3.2的一个bug 详见https://bugs.php.net/50731
  if ('\\' == $class[0]) {
   $class = substr($class, 1);
  }
  // class map 方式的查找
  if (isset($this->classMap[$class])) {
   return $this->classMap[$class];
  }
  //psr-0/4方式的查找
  $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;
 }
 private function findFileWithExtension($class, $ext)
 {
  // PSR-4 lookup
  $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
  $first = $class[0];
  if (isset($this->prefixLengthsPsr4[$first])) {
   foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
    if (0 === strpos($class, $prefix)) {
     foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
      if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
       return $file;
      }
     }
    }
   }
  }
  // PSR-4 fallback dirs
  foreach ($this->fallbackDirsPsr4 as $dir) {
   if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
    return $file;
   }
  }
  // PSR-0 lookup
  if (false !== $pos = strrpos($class, '\\')) {
   // namespaced class name
   $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
    . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
  } else {
   // PEAR-like class name
   $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
  }
  if (isset($this->prefixesPsr0[$first])) {
   foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
    if (0 === strpos($class, $prefix)) {
     foreach ($dirs as $dir) {
      if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
       return $file;
      }
     }
    }
   }
  }
  // PSR-0 fallback dirs
  foreach ($this->fallbackDirsPsr0 as $dir) {
   if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
    return $file;
   }
  }
  // PSR-0 include paths.
  if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
   return $file;
  }
 }

/**
 * Scope isolated include.
 *
 * Prevents access to $this/self from included files.
 */
function includeFile($file)
{
 include $file;
}

Nach dem Login kopieren

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Java-Tutorial
1664
14
PHP-Tutorial
1268
29
C#-Tutorial
1246
24
Verwenden Sie den Komponisten, um das Dilemma von Empfehlungssystemen zu lösen: Andres-Montanez/Empfehlungen-Bundle Verwenden Sie den Komponisten, um das Dilemma von Empfehlungssystemen zu lösen: Andres-Montanez/Empfehlungen-Bundle Apr 18, 2025 am 11:48 AM

Bei der Entwicklung einer E-Commerce-Website habe ich auf ein schwieriges Problem gestoßen: So liefern Sie den Benutzern personalisierte Produktempfehlungen. Anfangs habe ich einige einfache Empfehlungsalgorithmen ausprobiert, aber die Ergebnisse waren nicht ideal und die Benutzerzufriedenheit war ebenfalls betroffen. Um die Genauigkeit und Effizienz des Empfehlungssystems zu verbessern, habe ich mich entschlossen, eine professionellere Lösung zu übernehmen. Schließlich habe ich Andres-Montanez/Empfehlungen durch den Komponisten installiert, was nicht nur mein Problem löste, sondern auch die Leistung des Empfehlungssystems erheblich verbesserte. Sie können Komponist über die folgende Adresse lernen:

Beispiel für Laravel -Einführung Beispiel für Laravel -Einführung Apr 18, 2025 pm 12:45 PM

Laravel ist ein PHP -Framework zum einfachen Aufbau von Webanwendungen. Es bietet eine Reihe leistungsstarker Funktionen, darunter: Installation: Installieren Sie die Laravel CLI weltweit mit Komponisten und erstellen Sie Anwendungen im Projektverzeichnis. Routing: Definieren Sie die Beziehung zwischen der URL und dem Handler in Routen/Web.php. Ansicht: Erstellen Sie eine Ansicht in Ressourcen/Ansichten, um die Benutzeroberfläche der Anwendung zu rendern. Datenbankintegration: Bietet eine Out-of-the-Box-Integration in Datenbanken wie MySQL und verwendet Migration, um Tabellen zu erstellen und zu ändern. Modell und Controller: Das Modell repräsentiert die Datenbankentität und die Controller -Prozesse HTTP -Anforderungen.

Die fortgesetzte Verwendung von PHP: Gründe für seine Ausdauer Die fortgesetzte Verwendung von PHP: Gründe für seine Ausdauer Apr 19, 2025 am 12:23 AM

Was noch beliebt ist, ist die Benutzerfreundlichkeit, die Flexibilität und ein starkes Ökosystem. 1) Benutzerfreundliche und einfache Syntax machen es zur ersten Wahl für Anfänger. 2) eng integriert in die Webentwicklung, eine hervorragende Interaktion mit HTTP -Anforderungen und Datenbank. 3) Das riesige Ökosystem bietet eine Fülle von Werkzeugen und Bibliotheken. 4) Active Community und Open Source Nature passen sie an neue Bedürfnisse und Technologietrends an.

Laravel Framework Installationsmethode Laravel Framework Installationsmethode Apr 18, 2025 pm 12:54 PM

Artikelzusammenfassung: Dieser Artikel enthält detaillierte Schritt-für-Schritt-Anweisungen, um die Leser zu leiten, wie das Laravel-Framework einfach installiert werden kann. Laravel ist ein leistungsstarkes PHP -Framework, das den Entwicklungsprozess von Webanwendungen beschleunigt. Dieses Tutorial deckt den Installationsprozess von den Systemanforderungen bis zur Konfiguration von Datenbanken und das Einrichten von Routing ab. Durch die Ausführung dieser Schritte können die Leser schnell und effizient eine solide Grundlage für ihr Laravel -Projekt legen.

Wie sehe ich die Versionsnummer von Laravel an? So sehen Sie die Versionsnummer von Laravel Wie sehe ich die Versionsnummer von Laravel an? So sehen Sie die Versionsnummer von Laravel Apr 18, 2025 pm 01:00 PM

Das Laravel-Framework verfügt über integrierte Methoden, um die Versionsnummer einfach zu sehen, um die verschiedenen Anforderungen der Entwickler zu erfüllen. In diesem Artikel werden diese Methoden untersucht, einschließlich der Verwendung des Befehlszeilen -Tools des Composers, der Zugriff auf .Env -Dateien oder das Erhalten von Versionsinformationen über PHP -Code. Diese Methoden sind für die Aufrechterhaltung und Verwaltung der Versionierung von Laravel -Anwendungen von wesentlicher Bedeutung.

Verwenden von DICR/YII2-Google zur Integration von Google API in YII2 Verwenden von DICR/YII2-Google zur Integration von Google API in YII2 Apr 18, 2025 am 11:54 AM

VPROCESSERAZRABOTKIVEB-ENTLEGEN, мненеришшшо & лносsprechen, LeavallySumballanceFriablanceFaumdoptomatification, čtookazalovnetakprosto, Kakaožidal.Posenesko

So vereinfachen Sie das E -Mail -Marketing mit Composer: Anwendungspraktiken von Duwa.io. So vereinfachen Sie das E -Mail -Marketing mit Composer: Anwendungspraktiken von Duwa.io. Apr 18, 2025 am 11:27 AM

Ich habe ein schwieriges Problem bei einer Mail -Marketing -Kampagne: So erstellen und senden Sie E -Mails im HTML -Format effizient. Der traditionelle Ansatz besteht darin, Code manuell zu schreiben und E-Mails mit einem SMTP-Server zu senden. Dies ist jedoch nicht nur zeitaufwändig, sondern auch fehleranfällige. Nachdem ich mehrere Lösungen ausprobiert hatte, entdeckte ich Duwa.io, eine einfache und benutzerfreundliche Wiederherstellung, die mir hilft, HTML-Mail schnell zu erstellen und zu senden. Um den Entwicklungsprozess weiter zu vereinfachen, habe ich beschlossen, Composer für die Installation und Verwaltung von Duwa.ios PHP -Bibliothek - Captaindoe/Duwa zu verwalten.

Laravel -Installationscode Laravel -Installationscode Apr 18, 2025 pm 12:30 PM

Um Laravel zu installieren, befolgen Sie die folgenden Schritte: Installieren Sie den Komponisten (für MacOS/Linux und Windows). Installieren Sie LaRavel Installer. Erstellen Sie eine neue Projektstart -Service -Access -Anwendung (URL: http://127.0.0.1:8000).

See all articles