将C#转换为PHP

7

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

        )

使用SOAP连接到网络服务。为了确保准确性,我已经编辑了我的问题。 - Cudos
1个回答

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定义的任何内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接