使用本地包时Composer无法自动加载类的问题排查
问题分析与解决:本地Composer项目引入自定义包时找不到Google API类
我开发了一个本地Google API包装包companyname/googletools,想通过命名空间直接引入到另一个本地Composer项目testproject里,但在testproject中运行代码时出现错误:
PHP Fatal error: Uncaught Error: Class "Google_Client" not found.
但这个包装包在自己的项目目录里运行完全正常。
目录结构
├── companyname │ └── googletools │ ├── bin │ ├── composer.json │ ├── composer.lock │ ├── config │ ├── src │ └── vendor └── testproject ├── bin │ └── test.php ├── composer.json ├── composer.lock ├── src └── vendor ├── autoload.php └── composer
相关配置文件
googletools/composer.json:
{ "name": "companyname/googletools", "version": "1.0.0", "require": { "google/apiclient": "^2.17" }, "autoload": { "psr-4": { "CompanyName\\GoogleTools\\": "src/" } } }
testproject/composer.json:
{ "name": "companyname/testproject", "version": "1.0.0", "require": { }, "autoload": { "psr-4": { "Testproject\\": "src/", "CompanyName\\GoogleTools\\": "../companyname/googletools/src" } } }
包装包中Sheet.php的开头代码:
<?php namespace CompanyName\GoogleTools; use Google_Client; use Google_Service_Sheets;
为什么两段测试代码表现不同?
- 在googletools项目内运行时,加载的是自身的
vendor/autoload.php,这个自动加载器已经包含了google/apiclient的类映射规则,所以能正常找到Google_Client类。 - 在testproject中,你只是通过PSR-4把
CompanyName\GoogleTools命名空间指向了googletools的src目录,但testproject的vendor目录里并没有google/apiclient依赖,而且Composer不会自动扫描外部目录的依赖并加入自己的自动加载体系,因此找不到Google相关的类。
解决方法
方法一:将googletools作为本地Composer包引入(推荐)
修改testproject的composer.json,添加本地仓库配置并引入googletools:
{ "name": "companyname/testproject", "version": "1.0.0", "repositories": [ { "type": "path", "url": "../companyname/googletools" } ], "require": { "companyname/googletools": "^1.0.0" }, "autoload": { "psr-4": { "Testproject\\": "src/" } } }
执行composer update后,Composer会自动把googletools作为本地包安装,并同步它的所有依赖(包括google/apiclient)到testproject的vendor目录,自动加载器就能找到所有需要的类。
方法二:手动添加依赖(不推荐)
直接在testproject的composer.json里添加google/apiclient依赖:
"require": { "google/apiclient": "^2.17" }
执行composer update后也能解决问题,但这种方式会分散依赖管理,一旦googletools升级依赖版本,testproject需要手动同步,维护成本较高。
内容的提问来源于stack exchange,提问作者Joshua Alexander
相关产品推荐
相关产品推荐

