巅云智能建站平台搭建版(创业流派版)火爆上线,毕生受权!新增:文章智能收罗+全站真静态打包+都会分站+智能小法式+不法词过滤+H5自顺应+智能链词等功效功效概况
赞助文档Help

PHP办理依靠(dependency)干系东西 Composer的主动加载(autoload)

一佰互联网站建造(www.taishanly.com) 宣布日期 2020-04-29 09:01:07 阅读数: 183

举例来讲,假定咱们的名目想要操纵 monolog 这个日记东西,就须要在composer.json里告知composer咱们须要它:

{
 "require": {
  "monolog/monolog": "1.*"
 }
}

以后履行:

php composer.phar install

好,此刻装置完了,该怎样操纵呢?Composer主动天生了一个autoload文件,你只须要援用它

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

而后就能够很是便利的去操纵第三方的类库了,是不是是感受很棒啊!对咱们须要的monolog,就能够如许用了:

use MonologLogger;
use MonologHandlerStreamHandler;
// 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");

在这个进程中,Composer做了甚么呢?它天生了一个autoloader,再根据各个包本身的autoload设置装备摆设,从而帮咱们停止主动加载的使命。(若是对autoload这局部内容不太领会,能够看我之前的 一篇文章
)接上去让咱们看看Composer是怎样做的吧。

对第三方包的主动加载,Composer供给了四种体例的撑持,别离是 PSR-0和PSR-4的主动加载(我的一篇文章也有先容过它们),天生class-map,和间接包罗files的体例。

PSR-4是composer保举操纵的一种体例,由于它更容易操纵并能带来更简练的目次布局。在composer.json里是如许停止设置装备摆设的:

{
  "autoload": {
    "psr-4": {
      "Foo": "src/",
    }
  }
}

key和value就界说出了namespace和到呼应path的映照。根据PSR-4的法则,当试图主动加载 "FooBarBaz" 这个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/",
    }
  }
}

终究这个设置装备摆设也以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"]
  }
}

比方src/下有一个BaseController类,那末在autoload_classmap.php文件中,就会天生如许的设置装备摆设:

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

Files体例,便是手动指定供间接加载的文件。比方说咱们有一系列全局的helper functions,能够放到一个helper文件里而后间接停止加载

{
  "autoload": {
    "files": ["src/MyLibrary/functions.php"]
  }
}

它会天生一个array,包罗这些设置装备摆设中指定的files,再写入新天生的

vendor/composer/autoload_files.php

文件中,以供autoloader间接停止加载。

下面来看看composer autoload的代码吧

<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit73612b48e6c3d0de8d56e03dece61d11
{
  private static $loader;
  public static function loadClassLoader($class)
  {
 if ("ComposerAutoloadClassLoader" === $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 ComposerAutoloadClassLoader();
 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;
}

起首初始化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 详见http://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;
}

一佰互联是天下着名建站品牌办事商,咱们有九年、网站建造、网页设想、php斥地和域名注册及假造主机办事经历,供给的办事更是天下着名。最近几年来还整合团队上风自立斥地了可视化多用户”“3.0平台版,拖拽排版网站建造设想,轻松完成pc站、手机微网站、小法式、APP一体化全网营销网站扶植 ,已胜利的为天下上百家收集公司供给自助建站平台搭建办事。

相干消息more

11
05月
专业网站设想公司,胜利者首选的建站公司

当投资者们对成立本身的网站来作为宣扬本身产物最好的体例的时辰,愈来愈多的建站公司就纷纭的成立了起来,作为建站公司中的老牌建站公司,专业网站... >>概况

17
05月
百度搜索引擎优化优化莫非系数不时加大,网站优化职员

百度优化莫非系数不时加大,职员该具有哪些手艺呢? 第一、不时朝上进步的进修能力:我所提到的相同不是和客户或带领的相同,而是须要靠实战经历... >>概况

16
04月
专业网站扶植-立异营销—若何操纵社会气力

立异型营销的能源来历于对营销好处的引诱,在一个阶段外面,当发卖须要立异能力斥地新路时,咱们对立异的懂得思绪是不是是范围在手艺、战术与计谋下面,... >>概况

17
05月
【SEO数据监控】浅谈用数据领会网站经营结果

【SEO数据监控】浅谈用数据领会网站经营结果 当你想要阐发你合作敌手的网站、当你想要阐发你感乐趣的网站、想要领会一个网站的SEO结果... >>概况

高端网站扶植

美工统筹SEO,为企业电子商务营销助力!

德律风:

023-85725751
建站

产物

域名注册 假造主机 云办事器 企业邮局
智能建站 APP打包 微站/小法式 创业平台
网站推行 媒体营销 智能收罗 AI机械人
400德律风 短信营销 店销机械人
私家定制 流派网站