将C#转换为PHP

时间:2013-07-19 13:01:37

标签: c# php soap soap-client

我正在使用SOAP和PHP访问Web服务。我可以通过webservice 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);

输出连接时返回的web服务

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
                )

        )

1 个答案:

答案 0 :(得分:9)

你的阵列看起来不对劲。 ItemLinesPaymentLines应该是数组而不是包含数组的对象。

即使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的外观,您可能需要传递一个关联数组作为参数,键为salekey(根据WSDL),而不是传递两个单独的参数:

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

salekey更改为WSDL将其定义为的任何内容。