paso - Convierta C#a PHP
ejecutar php desde c# (1)
Estoy accediendo a un servicio web usando SOAP y PHP. Me puedo conectar a una serie de funciones a través de API de servicio web. Pero uno se me escapa. Tengo un ejemplo pero está en C #.
Intenté emular el ejemplo en PHP sin suerte.
He adjuntado el código C # y mi intento en PHP. También el mensaje de error está incluido.
C # code
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();
}
}
Código 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);
Salida de lo que devuelve el servicio web cuando se conecta
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
)
Mensaje de error
[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
)
)
Tus matrices no se ven bien. ItemLines
y PaymentLines
deben ser matrices en lugar de un objeto que contiene una matriz.
Aunque StartSale
devuelve como objetos, todavía deberían ser una matriz para la llamada a SaveSale
. La razón por la que se devuelven como objetos es una peculiaridad del PHP SoapClient. Lo que sucede es que, si solo hay un elemento en la matriz, SoapClient le otorga un objeto con sus propiedades establecidas como propiedades de elemento único. Sin embargo, si hay más de un elemento en la matriz, obtendrá una matriz de objetos en su lugar, y un nivel más profundo que el resultado cuando solo hay un elemento. Entonces, como se devuelven sin elementos de StartSale
, se dan como objetos en lugar de como una matriz vacía.
...
...
$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);
Además, dependiendo de cómo se vea el WSDL, es posible que deba pasar una matriz asociativa como parámetros, con claves como sale
y key
(según WSDL), en lugar de pasar dos argumentos separados:
$response = $client->SaveSale(array(''sale'' => $Sale->StartSaleResult, ''key'' => ''xxxxxxxx''));
Cambie la sale
y key
para lo que WSDL los define como.