7

我正在使用 SOAP 和 PHP 访问网络服务。我可以通过网络服务 API 连接到许多功能。但是一个让我望而却步。我有一个例子,但它是在 C# 中。

我试图在 PHP 中模拟该示例,但没有成功。

我附上了 C# 代码和我在 PHP 中的尝试。还包括错误消息。

C# 代码

 public void MakeSale()
 {
     string yourKey = "your key";
     using(DdDSaleService.SaleServiceClient client = new SaleServiceClient())
     {
         Sale sale = client.StartSale();
         //header info
         sale.ClientNumber = 996001;
         sale.Date = DateTime.Now;
         sale.Employee = 1;
         sale.NoteID = 123;
         sale.Terminal = 1;
         sale.Type = SaleType.Sale;

         //items in basket.
         ItemLine line1 = new ItemLine();
         line1.Type = ItemLineType.Sale;
         line1.ItemGroup = 1;
         line1.Supplier = 1;
         line1.Qty = 3;  //should -3 if a return of goods.
         line1.LineAmount = 600;  //The normal amount of the goods.
         line1.EDBNumber = 1; //unique key in our system. You have this if you got the articles by our service.
         line1.DiscountAmount = -100;  //the discount.

         //line2 comes here....

         //add the lines to the sale
         sale.ItemLines = new ItemLine[] { line1 };

         //The payment lines
         //1 with cash, and one with the change. the sale MUST sum to zero (itemlines + paymentlines)
         PaymentLine cash = new PaymentLine();
         cash.Type = PaymentLineType.Cash;
         cash.Qty = 1;
         cash.LineAmount = 600;

         PaymentLine change = new PaymentLine();
         change.Type = PaymentLineType.Change;
         change.Qty = 1;
         change.LineAmount = -100;

         //add the paymentlines
         sale.PaymentLines = new PaymentLine[]{cash,change};

         //submit the sale.
         Status response = client.SaveSale(sale, yourKey);
         Console.WriteLine(string.Format("got response from save sale saved: {0}, message: {1}",response.Saved,response.Message));
         Console.ReadLine();
    }
}

PHP 代码

$client = new SoapClient("http://xxx.xxxxx.xxxx/xxxxxxx.svc?wsdl", array("trace" => 1, "connection_timeout" => 500));

// Initialize sale
// $client is a valid SOAP connection
// That has been setup earlier
$Sale = $client->StartSale();

// Output what initalize sale returns
print_r($Sale);

// Format order date/time
$timezone = new DateTimeZone("Europe/Copenhagen");
$date = new DateTime("now", $timezone);
$order_date_time = $date->format("Y-m-d\TH:i:s");

// Set header information
$Sale->StartSaleResult->ClientNumber = 996001;
$Sale->StartSaleResult->Date = $order_date_time;
$Sale->StartSaleResult->Employee = 1;
$Sale->StartSaleResult->NoteID = 123;
$Sale->StartSaleResult->Terminal = 1;
$Sale->StartSaleResult->Type = 'Sale';

// Itemline
$line = new stdClass();
$line->Type = 'Sale';
$line->ItemGroup = 1;
$line->Supplier = 1;
$line->Qty = 3;
$line->LineAmount = 600;
$line->EDBNumber = 1;
$line->DiscountAmount = 1-100;
$Sale->StartSaleResult->ItemLines->ItemLine[] = $line;

// Payment line, cash
$cash = new stdClass();
$cash->Type = 'Cash';
$cash->Qty = 1;
$cash->LineAmount = 600;
$Sale->StartSaleResult->PaymentLines->PaymentLine[] = $cash;

// Payment line, Change
$change = new stdClass();
$change->Type = 'Change';
$change->Qty = 1;
$change->LineAmount = -100;
$Sale->StartSaleResult->PaymentLines->PaymentLine[] = $change;

// Save sale
$response = $client->SaveSale($Sale->StartSaleResult, 'xxxxxxxx');

print_r($response);

输出连接时webservice返回的内容

print_r($Sale);

stdClass Object
(
    [ClientNumber] => 0
    [Date] => 0001-01-01T00:00:00
    [Employee] => 0
    [ItemLines] => stdClass Object
        (
        )

    [NoteID] => 0
    [PaymentLines] => stdClass Object
        (
        )

    [Terminal] => 0
    [Type] => Sale
)

错误信息

    [previous:Exception:private] => 
    [faultstring] => End element 'Body' from namespace 'http://schemas.xmlsoap.org/soap/envelope/' expected. Found element 'param1' from namespace ''. Line 2, position 149.
    [faultcode] => a:InternalServiceFault
    [detail] => stdClass Object
        (
            [ExceptionDetail] => stdClass Object
                (
                    [HelpLink] => 
                    [InnerException] => 
                    [Message] => End element 'Body' from namespace 'http://schemas.xmlsoap.org/soap/envelope/' expected. Found element 'param1' from namespace ''. Line 2, position 149.
                    [StackTrace] =>    at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)
   at System.Xml.XmlExceptionHelper.ThrowEndElementExpected(XmlDictionaryReader reader, String localName, String ns)
   at System.Xml.XmlBaseReader.ReadEndElement()
   at System.ServiceModel.Channels.Message.ReadFromBodyContentsToEnd(XmlDictionaryReader reader, EnvelopeVersion envelopeVersion)
   at System.ServiceModel.Channels.Message.ReadFromBodyContentsToEnd(XmlDictionaryReader reader)
   at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)
   at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object[] parameters)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
                    [Type] => System.Xml.XmlException
                )

        )
4

1 回答 1

9

你的数组看起来不正确。ItemLines并且PaymentLines应该是数组而不是包含数组的对象。

即使StartSale将它们作为对象返回,它们仍然应该是一个用于调用的数组SaveSale。它们作为对象返回的原因是 PHP SoapClient 的一个怪癖。发生的情况是,如果数组中只有一个元素,SoapClient 会为您提供一个对象,其属性设置为单个元素属性。但是,如果数组中有多个元素,则会得到一个对象数组,因此比只有一个元素时的结果更深一层。因此,因为它们返回时没有来自 的元素StartSale,所以它们作为对象而不是空数组给出。

...
...
$Sale->StartSaleResult->ItemLines = array($line);

// Payment line, cash
$cash = new stdClass();
$cash->Type = 'Cash';
$cash->Qty = 1;
$cash->LineAmount = 600;

// Payment line, Change
$change = new stdClass();
$change->Type = 'Change';
$change->Qty = 1;
$change->LineAmount = -100;
$Sale->StartSaleResult->PaymentLines = array($cash, $change);

此外,根据 WSDL 的样子,您可能需要传递一个关联数组作为参数,键为saleand key(根据 WSDL),而不是传递两个单独的参数:

$response = $client->SaveSale(array('sale' => $Sale->StartSaleResult, 'key' => 'xxxxxxxx'));

更改sale并更改key为 WSDL 将它们定义为的任何内容。

于 2013-07-22T10:25:38.533 回答