详解composer的自动加载机制

详解composer的自动加载机制

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

 

详解composer的自动加载机制

 

安装composer

composer的安装非常的容易

1.下载安装脚本,这里把安装脚本保存为 composer-setup.php

 

  1. [root@localhost composer]
    # php -r “copy(‘https://install.phpcomposer.com/installer’, ‘composer-setup.php’);”

  2. [root@localhost composer]
    # ls

  3. composer-setup.php

2. 然后执行运行安装脚本,然后会生成一个可执行的phar包文件composer.phar(类似java中的.jar包)

 

  1. [
    root@localhost composer]# php composer-setup.php

  2. All settings correct
    for using Composer

  3. Downloading…

  4.  
  5. Composer (version
    1.5.2) successfully installed to: /root/composer/composer.phar

  6. Use it: php composer.phar

  7.  
  8. [
    root@localhost composer]# ls

  9. composer.phar composer-setup.php

 

3.执行命令: php composer.phar,  显示如下信息说明安装成功,注意最好不要使用root账户来执行composer命令,否则会报警告:

Do not run Composer as root/super user! See https://getcomposer.org/root for details

 

  1. [root@localhost composer]
    # php composer.phar

  2. Do
    not run Composer as root/super user! See https://getcomposer.org/root for details

  3. _____
    _

  4. / ___
    _/___ ____ ___ ____ ____ ________ _____

  5. /
    / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/

  6. / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ /

  7. \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/

  8. /_/

  9. Composer version 1.5.2 2017-09-11 16:59:25

  10.  
  11. Usage:

  12. command [options] [arguments]

  13.  
  14. Options:

  15. -h, –help Display this help message

  16. …..

  17.  

4. 如果想让composer在任意目录下都可以执行,可以执行命令:mv composer.phar /usr/local/bin/composer ,将 composer.phar 放到系统环境变量之下并重命名为composer,  之后便可以在任意目录使用 composer 来代替 php composer.phar 命令

 

  1. [root@localhost composer]
    # mv composer.phar /usr/local/bin/composer

  2. [root@localhost composer]
    # cd ~

  3. [root@localhost ~]
    # composer

  4. Do
    not run Composer as root/super user! See https://getcomposer.org/root for details

  5. _____
    _

  6. / ___
    _/___ ____ ___ ____ ____ ________ _____

  7. /
    / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/

  8. / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ /

  9. \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/

  10. …..

  11.  

 

配置composer使用国内镜像库

由于国内特殊的网络环境,访问国外的官方镜像库往往速度很慢,甚至无响应,所以我们配置使用composer中文网(http://www.phpcomposer.com)提供的国内镜像库,执行以下命令即可

 

[zyee@localhost root]$ composer config -g repo.packagist composer https://packagist.phpcomposer.com

 

简单的composer.json

假设我们现在的项目根目录为demo,并且我们的项目依赖 monolog(https://github.com/Seldaek/monolog) 这个php日志库,这时我们可以在项目根目录建立一个 composer.json 文件,并输入以下内容:

 

  1. {

  2. “require”: {

  3. “monolog/monolog”: “1.0.*”

  4. }

  5. }


然后输入命令 composer install,composer会帮我们自动下载monolog库,一般依赖库会默认放在项目的vendor目录下

 

  1. [
    root@localhost demo]# ls

  2. composer.json

  3. [
    root@localhost demo]# composer install

  4. Do not run Composer
    as root/super user! See https://getcomposer.org/root for details

  5. Loading composer repositories with package information

  6. Updating dependencies (including require-dev)

  7. Package operations: 1 install, 0 updates, 0 removals

  8. Failed to download monolog/monolog from dist: The zip extension and unzip command are both missing, skipping.

  9. The php.ini used by your command-line PHP is: /etc/php.ini

  10. Now trying to download from source

  11. – Installing monolog/monolog (1.0.2): Cloning b704c49a30

  12. Writing lock file

  13. Generating autoload files

  14. [root@localhost demo]# ls

  15. composer.json composer.lock vendor


composer的自动加载

composer不仅仅帮我们处理依赖,还帮我们实现了自动加载。在vendor目录下有一个autoload.php, 只要在我们的项目中引入这个文件就可以自动加载依赖库。

详解composer的自动加载机制

项目根目录下新建一个index.php, 并输入以下测试代码:

 

  1. <?php

  2. require ‘vendor/autoload.php’;

  3.  
  4. use Monolog\Logger;

  5. use Monolog\Handler\StreamHandler;

  6.  
  7. $log =
    new Logger(‘demo’);

  8. $log->pushHandler(
    new StreamHandler(‘app.log’, Logger::WARNING));

  9. $log->addWarning(
    “this is a warning log!”);


测试是否运行正常:

 

  1. [root@localhost demo]# php index.php

  2. [root@localhost demo]# ls

  3. app.log composer.json composer.lock index.php vendor

  4. [root@localhost demo]# cat app.log

  5. [2017-09-28 00:32:27] demo.WARNING: this is a warning log! [] []


可以看到monolog库完全不需要我们手动去加载,只需要使用正确的命名空间,composer的自动加载机制会帮我们找到对应的文件并加载。

对于依赖库,composer帮我们处理好了自动加载,那对于我们自己的项目文件该怎么实现自动加载呢,比如现在在我的项目根目下创建一个 controllers 目录存放控制器,并在该目录下新建一个Controller.php, 代码如下:

 

  1. <?php

  2. namespace controllers;

  3.  
  4. class Controller

  5. {

  6. public function test()

  7. {

  8. echo “Controller::test\n”;

  9. }

  10. }


现在如何在index.php中自动加载这个 Controller 类呢,如果我们直接在index.php写

 

  1. <?php

  2. require ‘vendor/autoload.php’;

  3. use controllers\Controller;

  4.  
  5. $c =
    new Controller();

  6. $c->test();

 

上面代码肯定是无法找到Controller类的:

  1. [root@localhost demo]# php
    index.php

  2. PHP Fatal error: Uncaught Error:
    Class ‘controllers\Controller’ not found in /root/demo/index.php:6

  3. Stack trace:

  4. #0 {main}

  5. thrown
    in /root/demo/index.php on line 6

 

要想解决上述这个问题我们首先需要了解下composer的自动加载机制。

composer支持四种自动加载的方式:PSR-0PSR-4 /ClassmapFiles , 其中 PSR-4 是当前推荐的加载方式。

 

什么是 PSR ?

PSR 是 PHP Standards Recommendations(PHP 标准建议)的缩写,这是一个叫做 PHP Framework Interop Group(http://www.php-fig.org/) 的组织所推出的关于PHP编程方面的一些标准建议,这个组织的成员包括一些知名的框架和项目,比如 CakePHP,Drupal,Magento,Symfony,Yii framework,Zend Framework 2等等,当然也包括这里说的 composer,该组织曾推出了一系列的 PSR, 具体的有哪些请参考 http://www.php-fig.org/psr/ , 其中 PSR-0 http://www.php-fig.org/psr/psr-0/)和 PSR-4http://www.php-fig.org/psr/psr-4/)是关于自动加载方面做出的一些规范

 

1. Files 是最简单的加载方式,这种方式不管加载的文件是否用到始终都会加载,而不是按需加载

修改项目根目下的composer.json, 加入 “autoload” 项:

 

  1. {

  2. “require”: {

  3. “monolog/monolog”: “1.0.*”

  4. },

  5. “autoload”: {

  6. “files”: [“controllers/Controller.php”]

  7. }

  8. }

需要加载哪个文件,直接写入文件路径即可,路径相对项目的根目录。然后执行composer dump-autoload,该命令可以遍历我们项目根目录以及各依赖库下的 composer.json 文件然后重新生成 vendor/composer/autoload_* 跟自动加载相关的配置文件

 

  1. [root@localhost demo]
    # composer dump-autoload

  2. Do
    not run Composer as root/super user! See https://getcomposer.org/root for details

  3. Generating autoload files

此时composer会帮我们更新自动加载相关的配置文件,composer dump-autoload 之后composer会把配置值写入与 Files加载方式对应的 vendor/composer/autoload_files.php 配置文件中:

  1. [root@localhost demo]
    # cat vendor/composer/autoload_files.php

  2. <?php

  3.  
  4. // autoload_files.php @generated by Composer

  5.  
  6. $vendorDir = dirname(dirname(
    __FILE__));

  7. $baseDir = dirname($vendorDir);

  8.  
  9. return array(

  10. ‘0b001b283842589bdffd092a1d29de66’ => $baseDir . ‘/controllers/Controller.php’,

  11. );


此时再运行index.php就一切正常了

 

  1. [root@localhost demo]# php index.php

  2. Controller::test

 

2. Classmap 加载方式也很简单,composer会搜寻我们指定的目录或文件,并把搜寻到的结果写到Classmap对应的 vendor/composer/autoload_classmap.php 配置文件中。 修改composer.json :

 

  1. {

  2. “require”: {

  3. “monolog/monolog”: “1.0.*”

  4. },

  5. “autoload”: {

  6. “classmap”: [“controllers/”]

  7. }

  8. }


以上配置会让composer搜寻 controllers 目录下的所有类,并生成配置文件,同样先 composer dump-autoload 下:

 

  1. [root@localhost demo]
    # composer dump-autoload

  2. Do not run Composer as root/super user! See https://getcomposer.org/root for details

  3. Generating autoload files

  4.  
  5. [root@localhost demo]
    # cat vendor/composer/autoload_classmap.php

  6. <?php

  7.  
  8. // autoload_classmap.php @generated by Composer

  9.  
  10. $vendorDir = dirname(dirname(
    __FILE__));

  11. $baseDir = dirname($vendorDir);

  12.  
  13. return array(

  14. ‘controllers\\Controller’ => $baseDir . ‘/controllers/Controller.php’,

  15. );

 

此时发现之前生成的 vendor/composer/autoload_files.php 配置文件也被 composer 删除了(由于项目中没再使用到Files的加载方式)

 

  1. [root@localhost demo]# ll vendor/composer/

  2. 总用量 44

  3. -rw-r–r– 1 root root 222 9月 28 01:59 autoload_classmap.php

  4. -rw-r–r– 1 root root 210 9月 28 01:59 autoload_namespaces.php

  5. -rw-r–r– 1 root root 143 9月 28 01:59 autoload_psr4.php

  6. -rw-r–r– 1 root root 1762 9月 28 01:59 autoload_real.php

  7. -rw-r–r– 1 root root 867 9月 28 01:59 autoload_static.php

  8. -rw-r–r– 1 root root 13451 9月 28 01:59 ClassLoader.php

  9. -rw-r–r– 1 root root 1375 9月 28 01:59 installed.json

  10. -rw-r–r– 1 root root 1070 9月 28 01:59 LICENSE

测试结果:

  1. [root@localhost demo]# php index.php

  2. Controller::test


3. PSR-0 ,这种加载方式已经过时,所以不推荐在新项目中使用,请用 PSR-4 来代替它。修改composer.json 如下, 然后执行composer dump-autoload

  1. {

  2. “require”: {

  3. “monolog/monolog”: “1.0.*”

  4. },

  5. “autoload”: {

  6. “psr-0”: {
    “controllers\\”: “”}

  7. }

  8. }


以上配置的意思是指定 controllers命名空间 所在的父级目录,由于controllers命名空间所在的父级目录就是项目根目录, 所以配置值用 “” ,composer dump-autoload后配置会写入 PSR-0对应的 vendor/composer/autoload_namespaces.php 配置文件中,而且从配置文件中可以看到之前使用的 monolog 也是使用 遵循PSR-0 规范的自动加载

 

  1. [root@localhost demo]
    # composer dump-autoload

  2. Do not run Composer as root/super user! See https://getcomposer.org/root for details

  3. Generating autoload files

  4.  
  5. [root@localhost demo]
    # cat vendor/composer/autoload_namespaces.php

  6. <?php

  7.  
  8. // autoload_namespaces.php @generated by Composer

  9.  
  10. $vendorDir = dirname(dirname(
    __FILE__));

  11. $baseDir = dirname($vendorDir);

  12.  
  13. return array(

  14. ‘controllers\\’ => array($baseDir . ‘/’),

  15. ‘Monolog’ => array($vendorDir . ‘/monolog/monolog/src’),

  16. );

  17. [root@localhost demo]
    # php index.php

  18. Controller::test


4. PSR-4  是 PSR-0 的升级版,是目前推荐的自动加载方式,这种方式使用的是按需加载。

修改composer.json 如下:

 

  1. {

  2. “require”: {

  3. “monolog/monolog”: “1.0.*”

  4. },

  5. “autoload”: {

  6. “psr-4”: {
    “controllers\\”: “controllers/”}

  7. }

  8. }


注意和PSR-0 的 composer.json 做对比,PSR-4 和 PSR-0 的主要区别是,PSR-4指定的就当作当前命名空间的目录, 而PSR-0 指定的是当前命名空间的父目录。composer dump-autoload 一下, 配置会写入PSR-4对应的 vendor/composer/autoload_psr4.php 文件中

 

  1. [root@localhost demo]
    # cat vendor/composer/autoload_psr4.php

  2. <?php

  3.  
  4. // autoload_psr4.php @generated by Composer

  5.  
  6. $vendorDir = dirname(dirname(
    __FILE__));

  7. $baseDir = dirname($vendorDir);

  8.  
  9. return array(

  10. ‘controllers\\’ => array($baseDir . ‘/controllers’),

  11. );

  12.  
  13. [root@localhost demo]
    # php index.php

  14. Controller::test

以上就是对composer的四种自动加载方式的简单介绍,这里主要偏向于使用,至于代码的实现,大家可以阅读 vendor/autoload.php 以及 vendor/composer/ 目录下的相关代码,有时间我再单独写一篇composer自动加载机制实现的源码分析^^

That’s it!

 

此文为原创,转载请注明出处 :http://blog.csdn.net/zhang197093/article/details/78118491

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/112920.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • python保存json格式_如何写json文件

    python保存json格式_如何写json文件Python小白之创建json文件做数据处理的时候需要用Python生成轨迹点的json文件,在百度上搜了一下Python如何创建json文件,第一页竟然都没有我想要的内容,大家都乱起标题么。。。真的对小白不友好,这里记录一下自己用的方法。我是从csv里面读出的dataframe,要取里面的经度和纬度两列的值,然后生成json文件,再在cesium上画出轨迹。要生成对应的json文件,先创建一个…

    2022年10月12日
  • 安装VS2005 SP1之后无法更改或卸载VS2005的处理方法

    安装VS2005 SP1之后无法更改或卸载VS2005的处理方法经历千辛万苦装上VS2005之后,一直相安无事,但今天想调整一下VS2005的安装项,于是麻利的调出控制面板–>添加删除程序,选中VS2005点“更改/删除”按钮,发现在加载安装控件的时候爆出一个错误,说是VS_Setup.MSI文件找不到,我按照提示所说的路径,即本机的安装位置,发现确实没有,于是又拿出安装盘来点Setup,结果还是说VS_Setup.MSI文件找不到,这次提示的位置是安装

  • 内网渗透的步骤_内网渗透思路

    内网渗透的步骤_内网渗透思路0x00Preface内网渗透主要是基于前期外围打点getshell的webserver,通过收集webserver上的信息,然后对其他内网主机进行口令上的攻击,当然也有一些基于漏洞的攻击。内网相关概念这里不再进行介绍,大家可以自行百度,诸如什么是域、域与工作组的区别、什么是DC、什么是AD等。当然,概念是生涩难懂的,结合实际环境会有助于理解。0x01信息收集systeminfo查看系统详细信息,如OS版本、补丁安装情况,可以根据这些信息筛选可利用的漏洞。netstart查看启动进

  • 层次分析法(AHP)详细步骤

    层次分析法(AHP)详细步骤1.算法简介

  • 微信小程序+PHP实现登录注册(手把手教程)[通俗易懂]

    微信小程序+PHP实现登录注册(手把手教程)[通俗易懂]1.环境说明环境版本PHP版本号:PHP7(!!!!注意本文基于PHP7环境开发,PHP5与PHP7有很多语法不兼容,如果您的本地环境为PHP5,则需修改PHP代码中不兼容语法部分)MySQL版本号:5.7.26开发工具PhPstudy8.1.0.5微信开发者工具Navicat122.创建user表首先创建用户表,这里以Navicat工具为例2.1新建数据库如果是第一次使用Navicat,需要新建连接点击左上角的连接->选择MySQL…设置

  • stringbuffer截取一段字符串_flutter常用插件

    stringbuffer截取一段字符串_flutter常用插件stringstr=”123abc456″;inti=3;1.取字符串的前i个字符str=str.Substring(0,i);2.去掉字符串的前i个字符str=str.Substring(i);3.从右边开始取i个字符str=str.Substring(str.Length-i);4.从右边开始去掉i个字符str=str.Substring(0,str.Len…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号