2

I am having an issue when my class get called multiple times I need to reinitialize my class to send request and get data properly.

I am calling an API so I am using httpClient to call my api.

My class

<?php 

namespace ModuleNameSpace\Modulename\Model\Api;

    class ApiModel
    {

        public function __construct(
            \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
            \Psr\Log\LoggerInterface $logger,
            \Zend\Http\Headers $headers,
            \Zend\Http\Request $request,
            \Zend\Http\Client $client
        ){
            $this->scopeConfig = $scopeConfig;
            $this->logger = $logger;
            $this->httpHeaders = $headers;
            $this->httpRequest = $request;
            $this->httpClient = $client;
        }

        private function callApi(){
            $this->httpClient->reset(); // Tried this to reset but this does not work

            $this->httpHeaders->addHeaders($this->getHeaders());

            $this->httpRequest->setHeaders($this->httpHeaders);
            $this->httpRequest->setUri($this->apiUrl);
            $this->httpRequest->setMethod($this->apiMethod);

            $options = [
               'adapter'   => 'Zend\Http\Client\Adapter\Curl',
               'curloptions' => [CURLOPT_FOLLOWLOCATION => true],
               'maxredirects' => 0,
               'timeout' => 60
            ];

            $this->httpClient->setOptions($options);

            return $this->httpClient->send($this->httpRequest);
        }

    }

However If I reinitialize in dirty way it works fine

$httpHeaders = new \Zend\Http\Headers();

Is there a way around when class in injected ?

1 Answer 1

2

You can add this to your di.xml file

<type name="Zend\Http\Headers" shared="false" />

If that doesn't work, you can try to inject a factory in your constructor.

protected $headersFactory;
public function __construct(
    ...
    \Zend\Http\HeadersFactory $headersFactory,
    ....
)
{
    ....
    $this->httpHeadersFactory = $headersFactory;
    ....
}

then you can use in your call api method $headers = $this->httpHeadersFactory->create();

but I'm not sure if the factories are autogenerated for zend classes.
In case they are not, you can create one by yourself in your module and use that one.
Something like this:

<?php
namespace Vendor\Module\Http;

class HeadersFactory
{
    /**
     * Object Manager instance
     *
     * @var \Magento\Framework\ObjectManagerInterface
     */
    protected $_objectManager = null;

    /**
     * Instance name to create
     *
     * @var string
     */
    protected $_instanceName = null;

    /**
     * Factory constructor
     *
     * @param \Magento\Framework\ObjectManagerInterface $objectManager
     * @param string $instanceName
     */
    public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager, $instanceName = '\\Zend\\Http\\Headers')
    {
        $this->_objectManager = $objectManager;
        $this->_instanceName = $instanceName;
    }

    /**
     * Create class instance with specified parameters
     *
     * @param array $data
     * @return \Zend\Http\Headers
     */
    public function create(array $data = array())
    {
        return $this->_objectManager->create($this->_instanceName, $data);
    }
}

Then make your class constructor look like this

protected $headersFactory;
public function __construct(
    ...
    \Vendor\Module\Http\HeadersFactory $headersFactory,
    ....
)
{
    ....
    $this->httpHeadersFactory = $headersFactory;
    ....
}

Then, same as above, when you need a clean instance of headers call $headers = $this->httpHeadersFactory->create();

I haven't tested this, but I hope at least one of these 3 works.

1
  • Thanks Marius as usual your answer worked (second one). Yes Zend Class are autoloaded so had no issues.
    – Priyank
    Commented Mar 7, 2017 at 12:05

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.