我正在使用以下代码进行电话呼叫。
如果我添加wsdl并进行我的客户呼叫,我将得到响应而无需整个肥皂包装。
declare(strict_types=1);
namespace Vendor\DocBasics\Controller;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use Vendor\DocBasics\Domain\Repository\EventsRepository;
use Vendor\CartExtended\Domain\Repository\Order\ItemRepository;
require_once(PATH_site . 'typo3conf/ext/doc_basics/Classes/Libs/nusoap/nusoap.php');
class EventsController
{
protected $action = '';
protected $order;
protected $Vbeln = '';
protected $Zaehl = '';
protected $objectManager;
/**
* @var array
*/
protected $responseArray = [
'hasErrors' => false,
'message' => 'Nothing to declare'
];
/**
* @param ServerRequestInterface $request
* @param ResponseInterface $response
* @return ResponseInterface
*/
public function processRequest(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
$this->initializeData(file_get_contents('php://input')); //xml datas from soap call
switch (isset($request->getQueryParams()['action']) ? (string)$request->getQueryParams()['action'] : '') {
case 'create':
$this->createAction();
break;
case 'update':
$this->updateAction();
break;
default:
$this->updateAction(); //call it as default, so i can call it as endpoint without action parameter
}
$this->prepareResponse($response,$request->getQueryParams()['action']);
return $response;
}
/**
* action create
*
* @return void
*/
public function createAction()
{
$server = new \soap_server();
$server->configureWSDL("updateorderservice", "https://domain.tld/updateorderservice", "https://domain.tld/index.php?eID=update_order");
$server->register(
"update",
array("Vbeln" => 'xsd:string', "Zaehl" => 'xsd:integer'),
array("return" => 'xsd:string'),
"https://domain.tld/updateorderservice",
"update",
"rpc",
"encoded",
"Update a given order"
);
$this->responseArray['message']= $server->service(file_get_contents('php://input'));
}
public function updateAction()
{
$this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$this->itemRepository = $this->objectManager->get(ItemRepository::class);
$order=$this->itemRepository->findOrderByOrder($this->Vbeln);
if($order){
$order->setCancelDate($this->Veindat);
$this->itemRepository->update($order);
$this->persistenceManager->persistAll();
$msg= '<MESSAGE><TYPE>S</TYPE><MSGTXT>Auftrag '.$this->Vbeln.' aktualisiert!</MSGTXT></MESSAGE>';
}
else $msg= '<MESSAGE><TYPE>E</TYPE><MSGTXT>Auftrag '.$this->Vbeln.' konnte nicht aktualisiert!</MSGTXT></MESSAGE>';
$this->responseArray['message'] = $msg; //receive the message but don't know how to wrap it
}
/**
* @param ResponseInterface $response
* @param String $action
* @return void
*/
protected function prepareResponse(ResponseInterface &$response, $action)
{
if($action=='create'){
$response = $response->withHeader('Content-Type', 'text/html; charset=utf-8');
$response->getBody()->write($this->responseArray['message']);
}
else{
$response = $response->withHeader('Content-Type', 'text/xml; charset=utf-8');
$response->getBody()->write($this->responseArray['message']);
}
}
/**
* @param $request
* @return void
*/
protected function initializeData($request)
{
$resp= $this->parseResult($request);
if($resp->Vbeln[0]) $this->Vbeln = (string)($resp->Vbeln[0]);
if($resp->Zaehl[0]) $this->Zaehl = intval($resp->Zaehl[0]);
}
public function parseResult($result){
$result = str_ireplace(['soapenv:','soap:','upd:'], '', $result);
$result = simplexml_load_string($result);
$notification = $result->Body->Update;
return $notification;
}
}
我的响应只是我正在写的小xml,作为对updateAction()的返回。我的回应应该介于两者之间,依此类推可能是我丢失了某些东西,或者我使用eID概念的方式是错误的。
您的案例在这里比在Facebook上更有意义,但是在您将来关于stackoverflow的帖子中,您应该为所有其他没有我背景知识的开发人员写更多背景知识。
[通常:您使事情变得过于复杂。 :-)
[首先,您在Facebook上告诉我,您的soap服务器本身(没有TYPO3集成为eID)有效。是这样吗?我看不到您的代码:-)您处理一些控件http参数“ action”,并仅在值为“ create”时创建SOAP服务器。但是对于“动作”值“更新”,是否没有服务器初始化?那怎么行?您必须记住,必须在每个请求上初始化SOAP服务器。它不是恶魔,它只能启动一次并在后台运行。
在输入端绝对不需要这样的“动作”控制参数。这就是NuSOAP服务器的“ SOAP远程方法”注册所针对的-具有专有名称的方法,您可以在客户端上显式调用它。
然后您的parseResult和parseResponse方法?您是否在尝试手动处理SOAP协议? NuSOAP应该为您处理所有这些。您只需要注册适当的数据类型(ComplexType)。
您首先需要获得有关NuSOAP本身的更多背景知识。
这是我在一个非常旧的项目中使用的简单正在工作示例。我简化了它,以向您展示NuSOAP应该如何工作。
服务器定义了一个单一的方法“ echoStringArray”,该方法将一个数组作为名为“ inputStringArray”的属性,并对其进行回显,而无需进行任何修改。
您可以将未做任何修改的粘贴粘贴并复制到eID脚本中,因此您将立即进行基本的TYPO3集成。然后,一个接一个地添加其他内容,例如数据库层等等。尽量不要先使用类,而应使用与我的示例相同的过程方法。
所以这是服务器定义soap-server.php:
<?php
// Pull in the NuSOAP code
require_once('./nusoap-0.9.5/lib/nusoap.php');
function logRequest($userAgent, $methodName, $request, $response, $result) {
$fp = fopen("./soap.log","a+");
fputs($fp,"$userAgent\n$methodName\n$request\n$response\n$result\n=======================================\n");
fclose($fp);
}
$log = true;
// Create the server instance
$SOAP_server = new soap_server;
$SOAP_server->configureWSDL(
'Test Service',
'http://my-soap-server.local/xsd'
);
// Set schema target namespace
$SOAP_server->wsdl->schemaTargetNamespace = 'http://my-soap-server/xsd';
// Define SOAP-Types which we will need. In this case a simple array with strings
$SOAP_server->wsdl->addComplexType(
'ArrayOfstring',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]')),
'xsd:string'
);
// Define SOAP endpoints (remote methods)
$SOAP_server->register(
'echoStringArray', // this is the name of the remote method and the handler identifier below at the same time
array('inputStringArray'=>'tns:ArrayOfstring'),
array('return'=>'tns:ArrayOfstring'),
'http://soapinterop.org/'
);
// Define SOAP method handlers
// This is the handler for the registered echoStringArray SOAP method. It just receives an array with strings and echoes it back unmodified
function echoStringArray($inputStringArray){
$outputData = $inputStringArray;
return $outputData;
}
// Now let the SOAP service work on the request
$SOAP_server->service(file_get_contents("php://input"));
if(isset($log) and $log == true){
logRequest($SOAP_server->headers['User-Agent'],$SOAP_server->methodname,$SOAP_server->request,$SOAP_server->response,$SOAP_server->result);
}
这是适当的客户端soap-client.php:
<?php
require_once('./nusoap-0.9.5/lib/nusoap.php');
// This is your Web service server WSDL URL address
$wsdl = "http://my-soap-server.local/soap-server.php?wsdl";
// Create client object
$client = new nusoap_client($wsdl, 'wsdl');
$err = $client->getError();
if ($err) {
// Display the error
echo '<h2>Constructor error</h2>' . $err;
// At this point, you know the call that follows will fail
exit();
}
// Call the hello method
$result1 = $client->call('echoStringArray', ['inputStringArray' => ['Hello', 'World', '!']]);
print_r($result1);
您可以看到,绝对没有对消息正文,XML,标头等的自定义处理。 NuSOAP本身正在照顾所有这些。
您只需在$ client-> call()中提供一个数组,并在服务器端获得与方法处理程序echoStringArray]相同的数组