【问题标题】:Composer autoload - files option and packagistComposer 自动加载 - 文件选项和 packagegist
【发布时间】:2020-08-26 21:58:10
【问题描述】:

我已经开发了几个作曲家模块,并已成功发布到 packagist。

所有这些都是完全基于类的,我知道自动加载过程是如何为它们工作的 - 如果多个项目使用我的 packagegist 模块,它们只会被包含一次。

对文件也一样吗?

我想为“缺失”的 WordPress 功能(即我在所有项目中经常使用的功能)开发一个 packageagist 模块。

如果多个项目包含该 packagegist 模块,我会收到关于同一命名空间中同一函数的多个定义的错误吗?

澄清。

我正在创建一个作曲家模块 sgi/wp-utils。它不会有课。它只会包含文件。像这样

{
    "autoload": {
        "files": [
            "src/Assets/functions.php",
            "src/Posts/functions.php"
         ]
    }
}

它将用于定义我计划在许多项目(插件、主题)中使用的实用功能。

如果多个插件/主题使用同一个包,composer 是否会在每个 WP 安装时只加载一次文件,或者我需要使用 function_exists() 调用来包装函数?

【问题讨论】:

  • “文件”究竟是什么意思?所有 PHP 类都存储在文件中

标签: php composer-php packagist


【解决方案1】:

如果同一个作曲家项目中的多个包需要同一个包,则依赖关系将被解析并且包将只包含一次,并且composer.jsonfiles键中的文件:

{
    "autoload": {
        "files": ["src/MyLibrary/functions.php"]
    }
}

无论如何都不会被多次收录。这并不是真正的“自动加载”,因为 PHP 中的“函数”实际上没有自动加载,只是这些文件将被“包含”在每个需要主 autoload.php 脚本的请求中。

既然你提到了 Wordpress,那么在那个世界里,事情可能会变得棘手,因为多个插件将是单独的 Composer 项目,每个插件都有自己声明的依赖项,这些依赖项将被加载并行。

如果多个插件声明了自己的composer.json 文件,并且它们使用相同的包,它们将尝试加载相同文件的多个副本,并再次定义相同的类和函数。这可能会导致类名和函数名发生冲突。

即使自动加载器使用include_once 之类的东西(它没有),它也不会工作。因为每个插件都有自己的包副本,并且会包含不同的文件。

您可以采取一些基本的预防措施,例如将您的函数声明包装在if (!function_exists('my_function') { } 中。比如:

<?php

if (function_exists('foo')) {
    return;
}

function foo() {
   echo "foo";
}

在尝试定义已定义的函数时避免致命错误)。

这将避免尝试定义相同的函数两次,但如果多个插件依赖于同一包的不同且不兼容的版本,您也可能会遇到麻烦。

Wordpress 和 Composer 根本就不是很好的伙伴,因为 Wordpess 在更广泛的 PHP 生态系统中很难适应现代方式来管理依赖项。

【讨论】:

  • 我已经澄清了我的问题。
  • 太棒了。但我的回答已经处理了你的澄清。如果多个插件需要同一个包,该函数将被定义多次。处理这个问题的方法是用if (! function_exists('your_function') 包装你的类定义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-28
  • 2018-11-26
  • 2021-03-18
  • 2013-02-17
  • 2017-05-06
  • 2014-10-31
  • 1970-01-01
相关资源
最近更新 更多