【问题标题】:How to properly set config paths from within vendor folder?如何从供应商文件夹中正确设置配置路径?
【发布时间】:2021-05-21 12:08:55
【问题描述】:

我正在本地开发一个作曲家包以调整图像大小。我有一个类,它的方法根据配置文件中的设置调整大小。配置文件设置了一些变量,如图像位置、大小等。

Composer 包结构

/src
    - ImageResizer.php
    - config.php
    - /config
        - Config.php

由于这是一个作曲家包,我的问题是在我的 config.php 文件中设置相对于它所服务的项目的路径,而不是相对于供应商目录。

config.php

'paths' => [
     'source' => 'source/_images',
      'new' => 'source/assets/images',
],

例如,在我的配置文件中,我设置了上面的路径。我需要这些路径相对于根项目,而不是相对于包/供应商文件夹内部。确保它们与安装它们的项目相关的最佳方法是什么?

参考:完整的包可以在这里找到: https://github.com/nathangross/php-image-resizer

回复:cmets:

此外,即使使用根项目目录中的用户配置文件,ImageResizer.php 也会在其自己的目录中查找路径。所以也许我的问题在于调整大小的方法:

ImageResizer.php

class ImageResizer
{
    public static function resizeImageWidth()
    {
        $config = new Config;
        $config->load(__DIR__ . '/config.php');           
        $sourcePath = $config->get('paths.source');

        $directory = new RecursiveDirectoryIterator($sourcePath);
        $iterator = new RecursiveIteratorIterator($directory);
        $regex = new RegexIterator($iterator, '@^(?<directory>.+)/(?<filename>[^/]+)\.(?P<extension>
                    jpe?g|png)$@i', RecursiveRegexIterator::GET_MATCH);

        foreach ($regex as $entry => $match) {
                // ... do some image resizy stuff
        }
    }
}

【问题讨论】:

  • 配置路径必须由用户在其项目中设置。否则他会使用你的配置。同时删除 require 'config/Config.php';从你的类和设置路径到 src 像这样getcomposer.org/doc/04-schema.md#psr-4
  • 要使用您的配置,您可以设置为 getcomposer.org/doc/04-schema.md#files 但这对您的项目来说是个坏方法。
  • 同意使用 composer 自动加载配置文件。我从概念上理解它,但是在正确设置它时遇到了问题。我一次迈出这一步;)
  • 我也同意允许用户设置配置。我也在努力进行设置。对于这个特定的项目,实际上有一个项目级别的配置文件。但是,即使我在那里设置了路径,我仍然遇到上面提到的相同问题:该方法从配置中获取相对路径并在供应商文件夹中搜索。我将进行编辑以更好地解释这一点。
  • $resizer = new ImageResizer($config); $resizer->resizeImageWidth();

标签: php package composer-php


【解决方案1】:

这实际上与 composer 没有太大关系,但它是关于如何使任何类型的包(通过 composer 或任何其他方式分发)可配置。

您无法知道用户将如何存储他们的配置。它甚至可能不是一个文件。但是看看你的示例配置,你需要的只是一个数组。因此,让用户从他们想要的任何地方提供该数组,并从那里为您的包创建一个 Config 对象。

不要在 ImageResizer 类中实例化 Config,而是使用依赖注入使配置对象可用于调整大小。

例如:

class Config
{

    public function __construct(array $config) 
    { /** implementation **/

}
class ImageResizer
{
    private Config $config;
    public function __construct(Config $config) {
        $this->$config = $config;
    }

    // lose the **static** here. 
    public function resizeImageWidth()
    {
    // method implementation
    }

}

然后你的包的消费者会简单地做,不管它对他们的应用程序有意义的方式

  1. 首先创建必要的配置,该配置应记录在您的包中。很可能,由于应用程序需要路径,配置应该使用绝对路径,让用户解决这个问题,你的包应该不知道谁在使用它以及他们的文件结构:
// example config.php

return [
    'paths' => [
        'source' => __DIR__ . '/source/_images',
        'new'    => __DIR__ . '/source/assets/images',
    ]
]
  1. 然后,在他们的实际应用程序中,他们可以这样做以使用您正在创建的包:
// index.php
require 'vendor/autoload.php';


$config = new Config(include('config.php');
$resizer = new ImageResizer($config);

$resizer->resizeImageWidth();

现在你不需要了解消费者文件结构,包消费者可以提供他们喜欢的配置。

如果您想提供以不同格式(XML、JSON、YAML 等)读取配置的选项,您可以简单地为 Config 添加不同的 static 构建器方法,以从所需格式实例化配置对象(例如Config::fromJson(string $jsonString)等)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-07
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多