Composer autoload - 文件选项和 packagist

Composer autoload - files option and packagist

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

它们都是完全基于 class 的,我知道自动加载过程是如何工作的 - 如果多个项目使用我的 packagist 模块,它们将只包含一次。

文件也一样吗?

我想为 "missing" WordPress 功能开发一个 packagist 模块 - 即我在所有项目中经常使用的功能。

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

澄清。

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

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

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

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

如果同一个作曲家项目中的多个包需要同一个包,依赖关系将被解决,包将只包含一次,[=12]中的文件=] composer.json 的键:

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

反正不会被多次收录。这不是真正的 "autoloading",因为在 PHP 中确实没有 "functions" 的自动加载,只是这些文件将在每个需要主 [=] 的请求上 "included" 14=]脚本。

既然你提到了 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 生态系统中的依赖关系。