2013-07-19 9 views
7

Uzyskuję dostęp do usługi sieciowej przy użyciu SOAP i PHP. Mogę połączyć się z wieloma funkcjami za pomocą interfejsu API serwisu. Ale umyka mi. Mam przykład, ale jest w języku C#.Konwertuj C# na PHP

Próbowałem naśladować przykład w PHP bez powodzenia.

Dołączyłem kod C# i moją próbę w PHP. Dołączony jest również komunikat o błędzie.

kod C# powraca

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(); 
    } 
} 

kod 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); 

Wyjście co WebService podczas podłączania

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 
) 

Komunikat o błędzie

[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

co to jest klient $? – DevZer0

+0

Połączenie z serwisem internetowym przy użyciu protokołu SOAP. Zmieniłem moje pytanie na wszelki wypadek. – Cudos

Odpowiedz

9

Twoje tablice nie wyglądają dobrze. ItemLines i PaymentLines powinny być tablicami zamiast obiektów zawierających tablicę.

Mimo że StartSale zwraca je jako obiekty, powinny one nadal być tablicą dla połączenia z SaveSale. Powodem, dla którego są zwracane jako obiekty, jest dziwactwo PHP SoapClient. Co się dzieje, jeśli w tablicy znajduje się tylko jeden element, obiekt SoapClient udostępnia obiekt z jego właściwościami ustawionymi jako właściwości pojedynczego elementu. Jeśli jednak w macierzy znajduje się więcej niż jeden element, zamiast tego otrzymuje się tablicę obiektów, a więc jest o jeden poziom głębszy od wyniku, gdy jest tylko jeden element. Ponieważ są one zwracane bez elementów od StartSale, są one podawane jako obiekty zamiast pustej tablicy.

... 
... 
$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); 

Również w zależności od tego, co WSDL wygląda, może trzeba przekazać tablicę asocjacyjną jako parametrów, z klawiszami jak sale i key (zgodnie z WSDL), zamiast przekazywać dwa oddzielne argumenty:

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

Zmiana sale i key na dowolne WSDL definiuje je jako.

+0

Awesome! Pracuję jak czar, dzięki za pakiet! – Cudos

+0

Nie ma problemu .. :) – MrCode