【问题标题】:Automatically including file in package when included as a dependency in Composer在 Composer 中作为依赖项包含时自动将文件包含在包中
【发布时间】:2016-12-11 09:17:24
【问题描述】:

我有一个包,当包包含在应用程序中时,它必须自动加载非命名空间的 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”中使用“文件”自动加载机制:

{
    ...

    "autoload": {
        "psr-4": { ... }
        "files": ["constants.php"]
    }
}

但是,当 PackageA 作为依赖项包含在 appA 中时,这不需要 constants.php。为了解决这个问题,我没有将"files": [...] 放在“packages/PackageA/composer.json”中,而是将以下内容放在“app/appsA/composer.json”的自动加载部分:

"files": ["vendors/packages/PackageA/constants.php"]

这不是很理想,因为每个使用PackageA 的应用程序都需要这个。我认为 composer 的性质将允许我确保 PackageA 中的文件可以访问(即,旨在包含)某些过程代码,例如在配置常量的情况下。有没有办法做到这一点?

【问题讨论】:

  • 您是否有理由无法将命名空间添加到您的 constants.php 文件并使用常规自动加载?
  • @Chris 因为在 php __DIR__ 等其他常量连接起来

标签: php composer-php dependency-management


【解决方案1】:

不要使用 Composer 的 files 自动加载来包含配置文件或带有常量的文件。请考虑对所有其他库的性能影响。 files 部分中的文件会在每次调用脚本时加载,无论您是否使用 PackageA。还要考虑由于非命名空间常量使用而可能出现的常量名称冲突。 files 仅自动加载!旨在用于无法正常工作的遗留代码。你应该避免使用它。

因为在 php __DIR__

主要问题不是串联,而是常量文件不是一个类。自动加载在这里不起作用,因为 Composer 的 Autolader 只加载类。

因此,一种解决方案可能是为常量引入一个空类,但在顶部添加副作用。 然后在您的 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 基于该上下文配置自身)。

【讨论】:

  • 我最终选择了这条路线,并且,就像你建议的那样,我留下了 @todo 评论,以便我们升级到 real 版本的 php
  • 很高兴我能帮上忙 :)
猜你喜欢
  • 2018-02-27
  • 2018-08-03
  • 2017-03-05
  • 1970-01-01
  • 2013-06-30
  • 1970-01-01
  • 2019-02-05
  • 2017-10-09
  • 1970-01-01
相关资源
最近更新 更多