我有一个软件包,当软件包包含在应用程序中时,必须自动加载非命名空间的PHP文件。
以下是我的一般目录结构
packages/
+-- PackageA/
+-- Entities/
+-- Mappers/
+-- Services/
+-- composer.json
+-- constants.php
apps/appA/
+-- vendors/
+-- autoload/
+-- composer.json
apps/appB/
+-- vendors/
+-- composer.json
我按照here的说明使用路径存储库,使PackageA
成为appA/
的依赖项。这部分工作顺利。
PackageA
中的某些文件需要访问常量,主要是文件路径。这就是“constants.php”的用途,这些值是按程序定义的:
<?php
define('XML_REPO_PATH', __DIR__ . '/../blah/xml/');
// --etc--
我原本以为在“packages / PackageA / composer.json”中使用'files'自动加载机制:
{
...
"autoload": {
"psr-4": { ... }
"files": ["constants.php"]
}
}
但是,当PackageA
作为appA
中的依赖项时,这不需要constants.php。要解决此问题,我将以下内容放在“app / appsA / composer.json”的自动加载部分中,而不是将"files": [...]
放入“packages / PackageA / composer.json”中:
"files": ["vendors/packages/PackageA/constants.php"]
这不是很理想,因为使用PackageA
的每个应用程序都需要这个。我认为作曲家的本质可以让我确保PackageA
中的文件可以访问(即,意味着包括)某些过程代码,就像配置常量一样。有没有办法做到这一点?
答案 0 :(得分:1)
不要使用Composer的files
自动加载来包含配置文件或包含常量的文件。请考虑所有其他库的性能影响。无论您是否使用PackageA,都会在每次调用脚本时加载files
部分中的文件。还要考虑由于非命名空间常量使用而导致的常量名称冲突。仅files
自动加载!意味着用于遗留代码,否则无法使其工作。你应该避免使用它。
因为在php&lt; 5.6我不能将类常量与
等其他常量连接起来__DIR__
主要问题不是连接,而是常量文件不是类。自动加载在这里不起作用,因为Composer的Autolader仅加载类。
因此,一种解决方案可能是为Constants引入一个空类,但在顶部添加副作用。
然后在vendor \ PackageA伞下命名它。
这使您可以在其他类中添加use vendor\PackageA\Constants;
,
为了触发自动加载,对吧?
您正在包含一个空类,但是当文件被自动加载时,定义将作为副作用发生。一个好的IDE会在这个文件上放置一个错误标志,因为它会引起副作用。它仍然很难看,因为其他开发人员不知道定义的来源,当他们只是包含一个类时 - 但比使用autoloading
files
部分更好。
composer.json
"autoload": {
"psr-4": { "\Vendor\PackageA\\" : "./src/packages/PackageA/" }
}
constants.php
<?php
namespace Vendor\PackageA;
class Constants
{
// @todo PHP 5.6 namespaced class constants
}
// global side effect: constant definition
define('XML_REPO_PATH', __DIR__ . '/../blah/xml/');
// etc..
最佳做法可能是使用带有构造函数的Configuration类,该构造函数接受用于配置包的配置对象或数组。 这从硬编码全局配置中解耦包和应用程序。 基本上,配置注入(App环境到Package,Package根据该上下文配置自己。)