我可以在 zf3 的服务中调用服务吗?

Can I call a service inside a service in zf3?

我真的是框架和 ZF3 的新手,但我需要使用以下逻辑制作一个 API。我收到参数,我将它们存储在 bd 中,如果调用是在此时进行的操作(调用管理器),我将它发送给(提供者调用者)。我能够完成第一部分和第二部分,但是现在,我不知道如何做最后一部分......我有以下代码:

IndexController.php

use Application\Service\CallManager;
use Application\Service\TropoCaller;
use Application\Service\NexmoCaller;



class IndexController extends AbstractActionController
{
 /**
 * Entity manager.
 * @var Doctrine\ORM\EntityManager 
 */
private $entityManager;

/**
 * Call manager.
 * @var Application\Service\CallManager 
 */
private $callManager;

/**
 * Call manager.
 * @var Application\Service\NexmoCaller
 */
private $NexmoCaller;

/**
 * Call manager.
 * @var Application\Service\TropoCaller
 */
private $TropoCaller;

/**
 * Constructor is used for injecting dependencies into the controller.
 */
public function __construct($entityManager, $callManager, $NexmoCaller, $TropoCaller) 
{
    $this->entityManager = $entityManager;
    $this->callManager = $callManager;

    $this->NexmoCaller = $NexmoCaller;
    $this->TropoCaller = $TropoCaller;
}

public function contactUSAction()
{
    $form= new ButtoncallForm();

    // Check whether this post is a POST request.
    if ($this->getRequest()->isPost()) {

        // Get POST data.
        $data = $this->params()->fromPost();

        // Fill form with data.
        $form->setData($data);
        if ($form->isValid()) {

            // Get validated form data.
            $data = $form->getData();

            // Use post manager service to add new call to the database             
            $this->callManager->CallManager($data);



            return $this->redirect()->toRoute('application', 
                    ['action'=>'thankYou']);
        }
    }

 return new ViewModel([

        'form' => $form,
        ]);
 }

public function thankYouAction() 
{
    return new ViewModel();
}

}

IndexControllerFactory.php

   <?php
namespace Application\Controller\Factory;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use Application\Service\CallManager;
use Application\Service\TropoCaller;
use Application\Service\NexmoCaller;
use Application\Controller\IndexController;
/**
 * This is the factory for IndexController. Its purpose is to instantiate the
 * controller.
 */
class IndexControllerFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $entityManager = $container->get('doctrine.entitymanager.orm_default');
        $callManager = $container->get(CallManager::class);
        $NexmoCaller = $container->get(NexmoCaller::class);
        $TropoCaller = $container->get(TropoCaller::class);

        // Instantiate the controller and inject dependencies
        return new IndexController($entityManager, $callManager, $NexmoCaller, $TropoCaller);
    }
}

我的CallManager.php

<?php

namespace Application\Service;

use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Application\Entity\CallRequested;
use Doctrine\ORM\EntityManager;
use Stomp\Client;
use Stomp\StatefulStomp;
use Stomp\Network\Connection;
use Stomp\Transport\Message;
use Application\Service\NexmoCaller;
use Application\Service\TropoCaller;

class CallManager
{
   /**
   * Doctrine entity manager.
   * @var Doctrine\ORM\EntityManager
   */
    private $entityManager;

   /**
   * @var Application\Service\NexmoCaller
   */
    private $NexmoCaller;

    /**
    * @var Application\Service\TropoCaller
    */
    private $TropoCaller;
  // Constructor method is used to inject dependencies to the controller.
  public function __construct($entityManager) 
  {
    $this->entityManager = $entityManager;


  }

    public function CallManager($data) 
    {
    $callRequested= new CallRequested;
    $callRequested-> setClientContact($data['clientContact']);
    $callRequested-> setProvider($data['provider']);
    $callRequested-> setCallCenter($data['callCenterContact']);
    $whenCall= $data['schedule'];
    $language= $data['language'];
    $date = new \DateTime();
    $callRequested-> setRequestTime($date);


    $provider=$data['provider'];
    $tropo='Tropo';
    //var_dump($data);


    $this->entityManager->persist($callRequested);
    $this->entityManager->flush();

    $id=$callRequested->getID();
    //var_dump($callRequested->getID());
    $data=array($id,$data);
    $data=json_encode($data, true);

//confirmar onde usar esta lógica
    if($whenCall==='1')
    { echo "Vamos establecer a ligaçao \n";
        if (stripos($provider, $tropo) !== false) {


                                            $destination  = '/queue/tropozend';
                                            $messages = 1;
                                            $size = 256;

                                            $DATA = "calls";

                                            $body = $data;


                                              try {
                                               $connection = new Connection('tcp://192.168.64.3:61613');
                                                $con1 = new StatefulStomp(new Client($connection));


                                                  $con1->send($destination, new Message($body));

                                                    //echo "Message sent $body \n" ;

                                              } catch(StompException $e) {
                                                echo $e->getMessage();

                                                // TropoCall();

                                              }



    } 
    else{                                     
                                              $destination  = '/queue/nexmozend';
                                              $messages = 1;
                                              $size = 256;

                                              $DATA = "calls";

                                              $body = $data;

                                              try {
                                               $connection = new Connection('tcp://192.168.64.3:61613');
                                                $con1 = new StatefulStomp(new Client($connection));


                                                  $con1->send($destination, new Message($body));

                                                    //echo "Message sent $body \n" ;


                                                    } catch(StompException $e) {
                                                echo $e->getMessage();
                                                    }

                                                    }
                                                   // NexmoCall();

     }
     else {echo "Vamos agendar a sua chamada \n"; 
 }


}
}

我创建了 NexmoCaller 和 TropoCaller,但不知道如何调用它们。 这是逻辑的一个例子: class NexmoCaller

{
    // public function __construct($NexmoCaller) 
  //   {
  //       $this->NexmoCaller = $NexmoCaller;
  //   }


    public function NexmoCall()
    {

            $service= new NexmoCaller();
            $serviceManager->set(NexmoCaller::class, $service); 

$key = file_get_contents('scripts/application.key');

$basic  = new \Nexmo\Client\Credentials\Basic($keyNexmo, $secret);
$keypair = new \Nexmo\Client\Credentials\Keypair($key, $application_id);
$client = new \Nexmo\Client(new \Nexmo\Client\Credentials\Container($basic, $keypair));

$jwt = generate_jwt($application_id, $key);


header('Content-Type: application/json', 'Authorization: Bearer'.$jwt); 

$destination  = '/queue/nexmozend';


      $connection = new Connection('tcp://192.168.64.3:61613');
      $stomp = new StatefulStomp(new Client($connection));
      $stomp->subscribe($destination);


      echo "Waiting for messages...\n";
        while(true) {
                     $frame = $stomp->read();
                     $body = $frame->getBody();
                     //echo($frame);
                     echo "message received $body \n";
                     //echo $stomp->read()->body, PHP_EOL;
                    //print_r($frame = $stomp->read());
                    //print_r($stomp->read()->body);
                    break;
                    }


//codificar o json como é necessário       
$json = json_decode($body, true);
var_dump($json);

}

}

我的config.module.php

'controllers' => [
        'factories' => [
            Controller\IndexController::class => Controller\Factory\IndexControllerFactory::class,

        ],
    ],
    'service_manager' => [
        'factories' => [
                    Service\CallManager::class => Service\Factory\CallManagerFactory::class,
                    Service\NexmoCaller::class => InvokableFactory::class,
                    Service\TropoCaller::class => InvokableFactory::class,
        ],            
    ],

我尝试了几种方法,但其中 none 创建了管理器或调用它...另外,我还没有发现任何在服务内部使用服务的情况,所以我什至不确定有可能的... 我尝试过的解决方案之一是: - 在我的呼叫管理器中构建:

   /**
   * Doctrine entity manager.
   * @var Doctrine\ORM\EntityManager
   */
    private $entityManager;

   /**
   * @var Application\Service\NexmoCaller
   */
    private $NexmoCaller;

    /**
    * @var Application\Service\TropoCaller
    */
    private $TropoCaller;
     public function __construct($entityManager, $NexmoCaller, 
       $TropoCaller) 
      {
        $this->entityManager = $entityManager;
        $this->NexmoCaller = $NexmoCaller;
        $this->TropoCaller = $TropoCaller;

       }

我得到这个错误:

函数 Application\Service\CallManager::__construct() 的参数太少,在第 15 行 /opt/lampp/htdocs/buttoncall/skeleton-application/module/Application/src/Service/Factory/CallManagerFactory.php 中传递了 1 个参数,正好有 3 个预期

或者直接调用:

 $this->NexmoCaller->NexmoCaller();

并得到这个:在 null

上调用成员函数 NexmoCaller()

我在我的工厂中使用了给定的答案:

<?php
namespace Application\Service\Factory;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use Application\Service\CallManager;
use Application\Service\NexmoCaller;
use Application\Service\TropoCaller;

class CallManagerFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $entityManager = $container->get('doctrine.entitymanager.orm_default');
         $nexmoCaller = $container->get(NexmoCaller::class);
        $tropoCaller = $container->get(TropoCaller::class);

        return new $requestedName(
            $entityManager, 
            $nexmoCaller, 
            $tropoCaller
    );


    }
}

并得到这个:在 null

上调用成员函数 NexmoCaller()

我该怎么办?

据我了解,您正在尝试在 CallManager 中使用 NexmoCaller 和 TropoCaller,但您尚未注入它们。

您在创建构造函数的正确路径上:

public function __construct($entityManager, $NexmoCaller, $TropoCaller) 
{
    $this->entityManager = $entityManager;
    $this->NexmoCaller = $NexmoCaller;
    $this->TropoCaller = $TropoCaller;
}

但是当您期待 3 个参数时,错误告诉我们 CallManagerFactory 只发送 1 个。

要解决此问题,请修改 CallManagerFactory,使其看起来像这样:

public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
    $entityManager = $container->get('doctrine.entitymanager.orm_default');
    $nexmoCaller = $container->get(NexmoCaller::class);
    $tropoCaller = $container->get(TropoCaller::class);

    return new $requestedName(
        $entityManager, 
        $nexmoCaller, 
        $tropoCaller
    );
}