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

时间:2017-09-12 08:08:53

标签: php zend-framework3 servicemanager

我是框架和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,但不知道如何调用它们。 以下是逻辑的一个示例: 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,
        ],            
    ],

我已经尝试了几个aproaches,但没有一个创建经理或称之为...另外,我还没有发现在服务中使用服务的任何情况,所以我甚至不确定它是否可能。 .. 我尝试过的解决方案之一是: - 在我的通话管理器中构建:

   /**
   * 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()的参数太少,1传入/opt/lampp/htdocs/buttoncall/skeleton-application/module/Application/src/Service/Factory/CallManagerFactory.php 15和3预期

或者只需致电:

 $this->NexmoCaller->NexmoCaller();

得到这个:在null

上调用成员函数NexmoCaller()

我在工厂里使用了答案gaven:

<?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()

我该怎么办?

1 个答案:

答案 0 :(得分:1)

根据我的理解,你试图在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
    );
}