本篇博客承接上一篇,学习一下Composer实现的PHP的类的自动加载方式。首先说明一下,Composer是PHP针对PHP语言的第三方的依赖管理工具,将工程所用到的依赖文件包含在composer.json文件中,使用composer install命令就可以将所使用对应库或者文件加载进工程里面。下面分两部分介绍composer的基础,分别是composer的依赖管理和自动加载。

  依赖管理

  在composer出现之前,如果咋PHP项目中需要第三方的依赖文件,则需要程序员将所需要的源代码拷贝进工程中或者将源代码对应的文件下载下来手动添加到工程中。如果所需要的依赖文件依赖于更多的第三方文件,则程序员会陷入拷贝依赖文件的黑洞中,费时费力不说,有可能还会出现一些失误,composer就是在这种情况下出现的用于减轻程序员的对于依赖管理的负担的工具。

  Composer通过使用配置文件composer.json文件完成依赖管理。composer.json文件包含了项目的简单介绍、项目对于外界的库或文件的依赖。从composer.json的扩展名就可以看得出来,composer.json中的内容是按照json标准组织的。本篇博客集中在类的自动加载机制上,因此对于composer.json中关于项目的作者等相关信息的解释忽略不解释。

  在composer中将本项目所需要的外部依赖包写在关键字require对应的值中,require键可以对应着多个所需要的包,各个不同的包之间用逗号分隔。假设项目需要一个外部依赖包monolog,下面是在compose.json文件中对于monolog包的依赖配置项:

{
	"require":{
		"monolog/monolog": "1.0.* @dev"
	}
}

  如上所示,require关键字将会映射包的名称monolog和包的版本1.0.*。其中,包的名称有两部分组成,中间以“/”分隔,“/”之前代表的包的所有者,在Github上一般是代表的Github的用户名,“/”代表的是实际的包的名称。其中“/”之前的名称必须是唯一的,但是"/"之后的包的名称是可以存在重复的,例如“Jack/monolog”和“monolog/monolog”是可以共存的。而后面的"1.0.*"代表的是所依赖的包的版本,其中“*”代表的是“1.0”之下的任意一个版本,例如:1.0.1,1.0.2或者1.0.9等等。“@dev”代表了可以获取该包的开发版本。默认情况下,composer将获取所需要的包的最新的稳定版本,而不会考虑开发版本,因为开发版本一般是不太稳定的版本。但是,如果确定开发版本没有什么问题就可以加上“@dev”以允许获取开发的版本。如果没有加上“@dev”,而除了开发版本之外不存在别的版本的话,则composer加载依赖项出错。

  在composer中配置好依赖的第三方的包之后,就可以使用composer install命令获取第三方的包了。运行成功之后就可以项目中就会出现vendor文件夹,vendor文件夹中会包含我们在require中所列出的monolog文件。

  出了生成列在composer.json中关键字require值下的文件之外,成功运行composer install之后还会生成对应的composer.lock文件,该文件依据composer.json中的依赖项生成依赖包对应的版本。这里需要说明的是,在我们运行composer install的时候会首先判断是否存在着composer.lock文件。如果原本就存在这composer.lock文件,那么就会直接根据composer.lock中的版本下载对应的包,此时不再理会composer.json中的配置项。如果不存在composer.lock文件,则根据composer.json文件中的配置下载对应的版本,并生成composer.json对应的composer.lock文件。composer.lock又称为锁定文件,生成对应的composer.lock之后,composer.json和composer.lock共同对版本进行控制。有了composer.lock之后,及时有了新的版本也不会触发新版本的更新,除非手动使用composer update命令进行手动的更新。

  开发环境下的依赖

  有的时候我们只是在开发的时候才会依赖于某个具体的包,但是在发行的版本中并不需要这样的包,为了达到这种要求可以使用require-dev引入开发环境下的包依赖。如下:

{
	"require-dev":{
		"xxxx/xxxx": "x.x.* @dev"
	}
}

  自动加载类

  通过composer.json或者composer.lock,所依赖的第三方库已经被下载下来了,那么在我们的项目中怎么使用这些第三方库呢?最简单的方式就是通过include或者require将所需要的类文件包含进来,但是这种方式需要我们自己去寻找所使用的类对应的类文件,这就存在和PHP语言中直接使用include和require加载所需要的类存在同样的弊端,一种比较简单的方式当然就是使用composer提供的类的自动加载机制了。类似于PHP的自动加载机制,composer提供了autoload实现类的自动加载。

  成功运行composer install之后,只要调用生成的vendor目录下的autoload.php文件就可以调用通过composer.json加载的类了。以上面所述的项目中需要monolog包为例,通过可以通过下面的方式使用monolog包中的Logger类。  

include "vendor/autoload.php";
$log = new Monolog\Logger("name");

  当然,除了使用第三方库中提供的类之外,还可以使用自己的定义的类。Composer提供了autoload关键字用于加载我们自己提供的类,假如我们定义了一个有关测试的类,如下:

class ClassTest{

	public function test()
	{
		echo "hello world!";
	}
}

  将该类放在lib目录下的ClassTest.php文件夹下面,那么怎么让composer加载自己定义的类呢?

  1. 在composer.json中加入autoload关键字  

"autoload":{
	"files":["lib/ClassTest.php"];
}

  files键对应的值是一个数组且改值是相对于文件应用根目录的文件的路径。在composer.json中加入上述的关键字之后,在命令行下运行composer dump-autoload就可以让composer重建加载信息,那么就可以在其他的文件中使用这个类了。

  上述所述的方法和PHP中直接使用include和require存在一样的弊端,每个类都需要重新书写加载文件,费时费力。

  2. composer.json中加入classmap关键字

  相比于每个类文件都需要加载一次的做法,使用classmap关键字,能够减少程序员的负担,只需要将文件所在的目录添加在classmap的值中即可,如下: 

"classmap" : ["lib"]

  其实这需要建立一种类名到类所在的文件的映射关系。当需要相应的类的时候,composer通过类名找到对应的类文件名,将相应的类include进来。但是这同样存在一个问题就是,每增加一个类都需要重新运行一次composer dump-autoload重新创建类名到文件之间的映射关系,从而将对应的类加载进来。虽然比files关键字节省了功夫,但是依然不能完全自动加载所需要的类。

  3. 基于PHP规范的自动加载方式

  针对PHP这种编程语言,到目前FIG指定了五个规范,分别如下:

  • PSR0:自动加载;
  • PSR1:基本代码规范;
  • PSR2:代码样式规范;
  • PSR3:日志接口规范;
  • PSR4:自动加载规范;

  看上去PSR4与PSR0是重复了,但是PSR4规范比较干净,可以看成PSR0规范的升级版。二者最重要区别在于:PSR0规范中,下划线会被转换为目录分隔符,但是PSR4中下划线不具有特殊的含义。二者都是通过特定的目录、文件名以及类名,实现快速查找到类文件,并将相应的类加载进来。

  PSR0和PSR4要求有个命名的空间,对上述的ClassTest类做相应的修改如下:  

<?php
namespace ClassTestLib;
class ClassTest{

	public function test()
	{
		echo "hello world!";
	}
}

  那么对应的文件的路径应该改为\lib\ClassTestLib\ClassTest.php,此时修改composer.json中的autoload如下:

"autoload":{
	"psr-0":{
		"ClassTestLib":"lib/"
	}
}

  可能你发现psr0的值有一些奇怪,是的。在这里ClassTestLib代表的是命名空间,而"lib"是目录名。加载对应的类文件的时候,搜索的路径是lib/ClassTestLib,而不是ClassTestLib/lib,这是在书写composer.json的时候需要注意的一点。

  如果命名空间中存在着“\”,则在书写对应的composer.json的时候需要在相应的“\”再添加一个“\”。例如,如果命名空间改为ClassTest\Lib,相应的对应与应用根目录的路径名称应该变为\lib\ClassTest\Lib\ClassTest.php,对应的composer.json中的autoload应该变为:

"autoload":{
	"psr-0":{
		"ClassTest\\Lib":"lib/"
	}
}

  

  小结:以上是关于composer的基本使用方法,后续在遇到相关的问题,和大家在一起学习。

Composer实现PHP中类的自动加载的更多相关文章

  1. PHP中类的自动加载

    在之前,我们已经学习过Composer自动加载的原理,其实就是利用了PHP中的类自动加载的特性.在文末有该系列文章的链接. PHP中类的自动加载主要依靠的是__autoload()和spl_autol ...

  2. Composer对于第三方包的自动加载

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

  3. 🐯 php项目中类的自动加载

    主要函数:spl_autoload_register() — 注册给定的函数作为 __autoload() 的实现 将函数注册到SPL __autoload函数队列中.如果该队列中的函数尚未激活,则激 ...

  4. PHP中类自动加载的方式

    最近在学习composer,发现从接触PHP到现在已经遇到了三种关于PHP中类的自动加载方式,这其中包括PHP自带的类的自动加载方式.PHP的第三方的依赖管理工具composer的加载方式以及PHP的 ...

  5. Composer概述及其自动加载探秘

    composer概述 一开始,最吸引我的当属 Composer 了,因为之前从没用过 Composer . Composer 是PHP中用来管理依赖关系的工具,你只需在自己的项目中声明所依赖的外部工具 ...

  6. Composer 自动加载(autoload)机制

    自动加载的类型 总体来说 composer 提供了几种自动加载类型 classmap psr-0 psr-4 files 这几种自动加载都会用到,理论上来说,项目代码用 psr-4 自动加载, hel ...

  7. Composer 的自动加载机制

    Composer 的自动加载机制 Composer 提供了四种自动加载方式,分别是 PSR-0.PSR-4.生成 classmap 以及之间包含 files. PSR-0 方式 PSR-0 方式要求目 ...

  8. 详解composer的自动加载机制

    composer是一个用PHP开发的用来管理项目依赖的工具,当你在项目中声明了依赖关系后,composer可以自动帮你下载和安装这些依赖库,并实现自动加载代码. 安装composer composer ...

  9. Yaf框架下类的自动加载

    前面两篇博客分别讲述了PHP自带的类加载和composer中类的自动加载,其实Yaf框架也实现了基于PSR0和PSR4的类的自动加载.根据我对Yaf下类的自动加载方式的理解写下这篇博客.由于接触Yaf ...

随机推荐

  1. IO:OutPutStream

    OutputStream类(java.io.OutputStream) public abstract class OutputStream extends Object implements Clo ...

  2. 如何用BarTender批量打印标签

    关于使用BarTender条码打印软件打印标签,很多小伙伴最关心的问题之一,莫过于如何实现BarTender批量打印标签.为了提高日常标签打印速度,为了方便快捷,也为了减少出错率,快来跟小编学习学习吧 ...

  3. html/京东项目/京东网页高仿/js/jq/css/java web/

    登录部分HTML+CSS: <!DOCTYPE html><html>    <head>        <meta charset="UTF-8& ...

  4. xmind8

    win10企业版安装 xmind.zip,打开应用程序报下面的错 解决办法是 先备份xmind8下的XMind.ini文件 Open up Xmind.ini and replace "Ap ...

  5. php自学提升进阶路线

    为了自己对php的系统全面深入的掌握,我通过个人经验,以及搜索网上高手经验,汇总了一份php自我学习路线规划,包括实战演练.学习建议.高手进阶.常见问题和测试总结五块.算是一个系统的学习计划和目标吧. ...

  6. Maven手动下载jar

    首先,手动下载的jar一定要是官网上的哦.http://mvnrepository.com/ 在下载之前要在pom.xml里按照官网的格式添加节点,这步一定不能省. 然后迅雷下载jar到本地硬盘. 开 ...

  7. AngularJS---自定义指令

    AngularJS提供了一系列的内置指令,如ng开头的指令,同时AngularJS也允许用户自定义指令. 目录: 1.自定义指令 2.使用自定义指令 3.自定义指令的内嵌使用 自定义指令 Angula ...

  8. modelsim操作流程

    1.File->Change Directory2.File->New->Library 在弹出的对话框中选择 a new library and a logical mapping ...

  9. day3 字典,集合,文件

    一.深浅copy 浅copy只copy第一层,不copy第二层.copy后,第一层指向不同内存地址.第二层指向相同的内存地址. 导入copy模块,deepcopy深copy.deepcopy后,均指向 ...

  10. Java的线程安全

    线程安全 我们这里讨论的线程安全,就限定于多个线程之间存在共享数据访问这个前提,因为如果一段代码根本不会与其他线程共享数据,那么从线程安全的角度来看,程序是串行执行还是多线程执行对它来说是完全没有区别 ...