专栏首页野路子程序员徒手解剖composer,简单了解其实现过程

徒手解剖composer,简单了解其实现过程

“composer”?,相信很多做PHP工作的对他并不陌生,他是一个针对第三方库管理工具,解决库与库之间的依赖关系等等等,例如一些yii、laravel等框架都搭载着composer来方便管理第三方包和自身的包,总之他是一个很牛逼的库。牛逼在哪儿,为什么牛逼,且先不去谈。

来看看官网,https://getcomposer.org/(外文社区)

http://www.phpcomposer.com/(中文镜像),首先可以看到一个很放纵的男人,在肆无忌惮的发挥着自己的灵感去创作东西,毫不为其他琐事担心(除过肢体,怎么看都感觉这个人好难受,在遭罪的样子),这大概是composer所带来的精妙之处。

除此之外,你还可以看到其文档、指南以及基本介绍和下载途径等,关于这个composer的一些发展史,和发展背景及常用的以及大概的基本使用流程。

但我怎么没有看到他的工作原理呢?例如,composer install 、update 这些命令实际做了什么工作呢,她能为我的项目带来哪些便利呢?我该怎么接入他?  含糊不及,没有人知道他在说些什么。

日前,拿到了一个laravel的项目增添一些东西,其中涉及到一个验证码的问题,laravel内置并没有验证码的相关库,大多都是通过第三方引入或者是手写的。

通过搜索得到,有gregwar/captcha相关的库可以进行方便接入验证码,可是网上关于这个库的使用介绍只有composer的使用方式,按理说我就只需要install一下,update一下,引入一下就可以很方便的得以使用,却还要纠结那么久。

如果你是以上思维,那么恭喜你,你不太适合做程序员,缺少了程序员与生俱来癖症,他让你那么做,你就那么做吗?它让你执行shutdown -s 你也执行吗?最起码也是需要将composer的来龙去脉搞清楚之后再去享受他所带来的便捷之处,不然只会被工具所蒙蔽。

按照我以往的习性,是不会给我电脑装一堆自己所不知道其在干些什么事情的软件。都不知道他在干什么,何必安装它浪费那么一大块儿内存呢?当然这句话不是说composer,composer类似于一个插件,只有运行时才会去执行,不会常驻内存。

我们继续,关于安装composer,使用composer,网上有很多更专业的文章文档可以供予大家参考。此文只介绍composer的简单工作内容

那么,不安装composer,不使用那一堆堆命令就不能引用第三方库了吗?答案是可以的,但对于初探者来说,可能会到处碰壁。

我们所需要了解到,composer是安装在PHP之上的,不借助于apache、nginx等web服务器运行,来看看一个命令:

php composer.phar install

由此就可以看出,他是借助于PHP去运行他的一些东西。假设你没有安装PHP或者没有设置PHP路径为全局变量,那么你也是无法进行使用的。

拆解命令得到:

D:\php\php.exe composer.phar install

那么这样也是可以执行的,其就是省去了精准到PHP程序所在目录这个步骤。

那么后面的composer.phar install 到底做了些什么内容,怎么做的呢?

官方是这样解释的,

接着前面的例子,这将会找到 monolog/monolog 的最新版本,并将它下载到 vendor 目录。 这是一个惯例把第三方的代码到一个指定的目录 vendor。如果是 monolog 将会创建 vendor/monolog/monolog 目录。

大概描述清楚了,就是自动去寻找对应版本下载并创建一些目录做以配置,可他是怎么做的呢?

我们得对php 的参数做以简单了解,简单举例。

#运行PHP代码
php -r "echo 'hello oschina';"

#运行PHP文件
php -f "d:\work\test.php"   #需要在php.ini里配置对应的目录,否则没权限。

#变相一下,可以在本地直接执行远程服务端写好的代码(从服务端脱下来在本地执行)
php -r "eval(file_get_contents("http://www.server.com/test.php"))"

#更加变相一下,以下伪代码
http://server.com/install.php 内容如下

<?php
$version = parseParamGetVersion($_SERVER['QUERY_STRING']);
$rootPath = dirname(__FILE__).'/';
$packArray = getPackByVersion($version)->toArray();

foreach($packArray as $key=>$files){
    $packPath = $rootPath.'verdor/'.$key.'/';
    if(! is_dir($packPath)){
        mkdir($pathPath);
        foreach($files as $filename => $file){
            $fileContent = file_get_contents($file);//获取最新包的内容
            file_put_contents($packPath.$filename);//写入包的内容
        }
    }
}
?>

#那么本地只需要执行,就实际将存在于网上上的某个包最新数据获取并且规范的写到了本地项目中。
php -r "eval('http://server.com/install.php')";
甚至可以将上一条代码保存到install.bat,直接双击运行。

或许有些人看到这里会恍然大悟,原来是这么回事。那么composer的工作方式也是类似,只不过他比较专业规范一些,使用了很多标准,统一代码。

大概了解过后,我们继续回归问题,解决图形验证码的问题。

幸甚,gregwar/captcha的所有源代码已经在github上公开,链接从官网获取。直接将git上代码下载下来。所得到的是一个关于这个库的实例demo和核心库以及关于composer自动加载的json配置。

我们将它直接复制到项目目录中,习惯性的将它和其他同类改成一致的小写命名。

以及写入一个简单的demo,竟然无耻的报错了。

很显然,错是应当的,因为当前项目加载的时候并不知道已经新增了一个库,就算引用也没有找到地方。

尝试手工修改composer.json,

"psr-4": {
            "App\\": "app/",
            "Gregwar\\Captcha\\": "vendor/captcha/" //增加引用库,路径模仿楼上
        },
    "require": {
        "php": ">=5.5.9",
        "laravel/framework": "5.2.*",
        "gregwar/captcha": "dev-master" //当前不是必须的,当前配置时给composer看的,用作版本对比。
        
    },

修改保存了之后依然报错,没有找到对应的类。这时候应该是很操蛋的情况。因为你明明知道,你此时只需要执行 

php composer update

就完事了,但是仍然忍者痛去剖解。

使用手工排除法,一步步echo exit;

报错很明确,找不到那个类,那么我们只需要找到一些我们认为应该加载类的地方去调试看是否加载上那个类就可以得以解决。

首先来到vendor目录中的autoload.php,增加调试语句。

当前已经执行到此处了,继续往下。深入到图中所示的autoload_real.php中去看看。

很明显,我们可以看到他加载4大类的加载文件。我们的库在psr4标准中,执行后,发现dump出来的库不包含我们的库。继续追溯到所在的文件中,autoload_psr4.php。

保持队形,在数组尾部增加自己所需要使用的库配置。

保存后,将其他调试代码屏蔽掉后。再次运行,发现我们的验证码出来了。

这个过程也就是php composer update 的主要操作。

还有一些其他的命令,最好是自行研究,此文不再多说。

文前,曾问过一些朋友,很多对这个工具使用都是游刃有余,有的表现的很是了解,但当我问起原理时,他好像并不知道什么。

更明确了解其工作原理,会让自己的工作更有信心,更不会被质疑,最好不要让自己干了些什么事情都不晓得,都在一天瞎折腾,否则有一天自己调试bug的时候遇到奇葩的问题,更是无从入手。

最后推荐到https://getcomposer.org/ composer 官网看看,文档都很全,只不过英文不太好的人阅读起来很比较痛苦,比如说是我。可以通过中文入门后再通过其深入。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Centos7+Nginx+PHP 基础WEB运行环境手工部署

    Eller
  • PHP错误日志,解决不显示不记录日志文件等疑难杂症

    Eller
  • 从已有安装包(vendor)恢复 composer.json

    Eller
  • 移动应用如何埋点收集什么数据以便于统计分析?

    国内比较普遍的第三方统计工具是友盟和talking data,在大多数的情况下这两个差别不大,但是如果你的app是游戏或者需要用到互联网金融的一些垂直细分统计,...

    CSDN技术头条
  • 洛谷P2044 [NOI2012]随机数生成器

    题目描述 栋栋最近迷上了随机算法,而随机数是生成随机算法的基础。栋栋准备使用线性同余法(Linear Congruential Method)来生成一个随机数列...

    attack
  • 基于 Composer 的 PHP 模块化开发

    overtrue
  • 共享可变状态中出现的问题以及如何避免[每日前端夜话0xDB]

    这里有两个独立的部分:函数logElements()和函数main()。后者想要在对数组进行排序的前后都打印其内容。但是它到用了 logElements() ,...

    疯狂的技术宅
  • 流水线救赎:Spinnaker如何塑造SAP卓越的交付

    作为一名负责卓越交付的现场可靠性工程师(Site Reliability Engineer,SRE),可靠的部署对我来说很重要。我已经在SAP工作了一段时间,我...

    CNCF
  • Redis慢查询日志

    通过 slowlog get 查看慢查询日志是什么样子?【从其他redis服务器看的】

    每天晒白牙
  • 本周日-先行者课程小总结

    本周日的先行者课程,是用vue.js做一个点菜结账pos类的应用。 里面使用了vue-cli做为脚手架,使用了ElementUI做为前端组件库,主要的知识点包括...

    web前端教室

扫码关注云+社区

领取腾讯云代金券