1

The whole point of PHP Composer is to handle dependencies in a clean way, so that developers don't need to care about duplication, updates, and instantiating the necessary classes when needed.

But there is a case within WordPress, in which I don't understand what goes on with the part that corresponds to duplication.

Let's say there are multiple WordPress plugins which require a certain package (for example the Stripe SDK)... I effectively have duplicated copies of the Stripe SDK, since it will live in each plugin's vendor folder.

I guess, that's the only way to go about it, for plugins published in the directory.

But I wonder how this affects the site performance and if there is anything I can do for my own plugins that I don't host on the WP directory (and hence I know I have to deal with dependencies myself).

Note that I am not talking about this: Multiple versions using composer

I am specifically talking about the described scenario within the WordPress environment, and if there is anything I could do to avoid having duplicates, like for example create a third plugin whose only job is to load the Stripe SDK, would that make sense?

1 Answer 1

1

There are no performance issues with duplicating composer packages.

If you look at the file vendor/composer/autoload_classmap.php, you will see lines like these:

<?php

// autoload_classmap.php @generated by Composer

$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);

return array(
    'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
    'Codeception\\Exception\\ConnectionException' => $vendorDir . '/codeception/module-webdriver/src/Codeception/Exception/ConnectionException.php',
...

Being loaded during composer activation, this film establishes a mapping of namespaces to certain folders. A similar meaning has the file vendor/composer/autoload_psr4.php.

Now let us look at the situation when two plugins (A and B) have the same packages (Stripe SDK, for instance). When plugin A is loaded, the composer establishes the mapping of the Stripe SDK namespace to a folder in plugin A. During the loading of plugin B, its class mapping of the SDK is ignored, and plugin B uses Stripe SDK from plugin A.

Plugins are loaded in alphabetic order, so SDK from plugin A will always be used when both plugins are active. If you deactivate plugin A, SDK from plugin B will be used in B.

This causes an evident problem if plugins A and B have different SDK versions. If B tends to use a higher SDK version and tries to use a method which does not exist in an older version (which is in A), it will cause a fatal error.

To avoid this possibility, some very advanced packages, like Action Scheduler by Automattic, have a dedicated code allowing to load a small portion of the package from all plugins and later, on a hook, determine the highest available version of Action Scheduler and load it.

But from the performance point of view, class autoloading has no issues. SDK is loaded only once, and we have no excessive memory consumption.

You can check it by the following mu-plugin:

<?php
use Symfony\Polyfill\Php80\Php80;

function my_autoload_test() {
    if ( ! class_exists( Php80::class ) ) {
        return;
    }

    $php80     = new Php80();
    $reflector = new ReflectionClass( $php80 );

    error_log( $reflector->getFileName() );
}

add_action( 'init', 'my_autoload_test' );

Install and activate two well-known plugins: BackWPup and WooCommerce. Both use the same package, symfony/polyfill-php80. The code above logs where the class Php80 is used from.

When both plugins are active, we have a path like ...\wp-content\plugins\backwpup\vendor\symfony\polyfill-php80\Php80.php.

When we deactivate BackWPup, we have a path like ...\wp-content\plugins\woocommerce\vendor\symfony\polyfill-php80\Php80.php.

Composer is a great tool to load packages only once and prevent memory bloating.

1
  • Genius. ........ Commented Feb 17, 2023 at 15:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.