0

I use soap to do some calls to a remote server, php has changed method signature for __doRequest between php 7.4 & 8.x, is there any di.xml tag that can conditionally change the loaded class based on the php version?

1 Answer 1

0

Generally Magento has PHP requirements for each release version and doesn't designed to solve PHP version with DI

Simple way is create custom factory for your class, create 2 classes with implementation and in factory create method check PHP version and returns correct one class instance. Use factory whatever where you need to use class

Example

<?php
declare(strict_types=1);

namespace Acme\StackExchange\Adapter\SoapClient;

use Magento\Framework\ObjectManagerInterface;

class Factory
{
    protected ObjectManagerInterface $objectManager;

    public function __construct(ObjectManagerInterface $objectManager)
    {
        $this->objectManager = $objectManager;
    }

    /**
     * @param string|null $wsdl
     * @param array|null $options
     * @return \Acme\StackExchange\Adapter\SoapClient
     */
    public function create(?string $wsdl, array $options = null)
    {
        $class = 'Acme\StackExchange\Adapter\SoapClient';
        if (PHP_VERSION_ID < 80000) {
            $class = 'Acme\StackExchange\Adapter\SoapClient7';
        }

        return $this->objectManager->create($class, [
            'wsdl'    => $wsdl,
            'options' => $options,
        ]);
    }
}

[Update]

Always wants to find better and concise solution, but in some case works only some "classic" way.

After some tests I can confirm that solution with factory will not work properly with magento setup:di:compile.

Following example tested on 7.4, 8.0, 8.1

<?php
declare(strict_types=1);

namespace Acme\StackExchange\Adapter;

if (PHP_VERSION_ID >= 80000) {
    class SoapClient extends \SoapClient
    {
        public function __doRequest(string $request, string $location, string $action, int $version, bool $oneWay = false): ?string
        {
            parent::__doRequest($request, $location, $action, $version, $oneWay);
        }
    }
} else {
    class SoapClient extends \SoapClient
    {
        public function __doRequest($request, $location, $action, $version, $oneWay = false)
        {
            parent::__doRequest($request, $location, $action, $version, $oneWay);
        }
    }
}

You pick incompatible parts and cover with version workaround and keep all compatible code in class like

<?php
declare(strict_types=1);

namespace Acme\StackExchange\Adapter;

if (PHP_VERSION_ID >= 80000) {
    class SoapClientProxy extends \SoapClient
    {
        public function __doRequest(string $request, string $location, string $action, int $version, bool $oneWay = false): ?string
        {
            parent::__doRequest($request, $location, $action, $version, $oneWay);
        }
    }
} else {
    class SoapClientProxy extends \SoapClient
    {
        public function __doRequest($request, $location, $action, $version, $oneWay = false)
        {
            parent::__doRequest($request, $location, $action, $version, $oneWay);
        }
    }
}

class SoapClient extends SoapClientProxy
{
    // all other staff compatible with all versions
}
2
  • i attempted your solution previously, but the warning still pops up when i compile using magento setup:di:compile Jun 17 at 6:29
  • You are right, with some workarounds i can compile with 8.1, but cannot with 7.4. See alternative in update Jun 17 at 7:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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