¿Por qué el orden de los parámetros de SOAP importa en PHP SOAP y cómo solucionarlo?
-
26-09-2019 - |
Pregunta
Un comentario en el manual indica PHP:
Si está utilizando este método, recuerde que la matriz de argumentos necesita estar aprobada en el ordenamiento ser el mismo orden que el extremo SOAP Espera.
por ejemplo // Espera servidor: Foo (string name, int edad)
//won't work $args = array(32, 'john'); $out = $client->__soapCall('Foo', $args); //will work $args = array('john', 32); $out = $client->__soapCall('Foo', $args);
Estoy construyendo un cliente SOAP que asigna dinámicamente los valores de los argumentos, lo que significa que sucede que los argumentos no siempre están en el orden correcto. Esto entonces se rompe la llamada SOAP real.
¿Hay una solución fácil a este, a falta de comprobar el orden de los parámetros para cada llamada?
Solución 2
Existe una solución fácil para los parámetros con nombre:
function checkParams($call, $parameters) {
$param_template = array(
'Foo' => array('name', 'age'),
'Bar' => array('email', 'opt_out'),
);
//If there's no template, just return the parameters as is
if (!array_key_exists($call, $param_template)) {
return $parameters;
}
//Get the Template
$template = $param_template[$call];
//Use the parameter names as keys
$template = array_combine($template, range(1, count($template)));
//Use array_intersect_key to filter the elements
return array_intersect_key($parameters, $template);
}
$parameters = checkParams('Foo', array(
'age' => 32,
'name' => 'john',
'something' => 'else'
));
//$parameters is now array('name' => 'john', 'age' => 32)
$out = $client->__soapCall('Foo', $parameters);
No sólo correctamente los parámetros de la orden, que también filtra los parámetros de la matriz.
Otros consejos
Yo tenía el mismo problema en el que dinámicamente añadido los parámetros de SOAP y tuve que conseguir que en el orden correcto para mi llamada SOAP al trabajo.
Así que tuve que escribir algo que hará que todos los métodos de jabón de los WSDL y luego determinar en qué orden para organizar los argumentos del método.
Por suerte PHP hace que sea fácil de obtener las funciones de SOAP a través del '$ cliente -> __ getFunctions ()' método, todo lo que tiene que hacer es buscar el método de servicio que desea llamar la cual contendrá los argumentos del método en el orden correcto y luego hacer algo de variedad a juego para conseguir su gama parámetro de la petición en el mismo orden.
Este es el código ...
<?php
// Instantiate the soap client
$client = new SoapClient("http://localhost/magento/api/v2_soap?wsdl", array('trace'=>1));
$wsdlFunctions = $client->__getFunctions();
$wsdlFunction = '';
$requestParams = NULL;
$serviceMethod = 'catalogProductInfo';
$params = array('product'=>'ch124-555U', 'sessionId'=>'eeb7e00da7c413ceae069485e319daf5', 'somethingElse'=>'xxx');
// Search for the service method in the wsdl functions
foreach ($wsdlFunctions as $func) {
if (stripos($func, "{$serviceMethod}(") !== FALSE) {
$wsdlFunction = $func;
break;
}
}
// Now we need to get the order in which the params should be called
foreach ($params as $k=>$v) {
$match = strpos($wsdlFunction, "\${$k}");
if ($match !== FALSE) {
$requestParams[$k] = $match;
}
}
// Sort the array so that our requestParams are in the correct order
if (is_array($requestParams)) {
asort($requestParams);
} else {
// Throw an error, the service method or param names was not found.
die('The requested service method or parameter names was not found on the web-service. Please check the method name and parameters.');
}
// The $requestParams array now contains the parameter names in the correct order, we just need to add the values now.
foreach ($requestParams as $k=>$paramName) {
$requestParams[$k] = $params[$k];
}
try {
$test = $client->__soapCall($serviceMethod, $requestParams);
print_r($test);
} catch (SoapFault $e) {
print_r('Error: ' . $e->getMessage());
}
Otra solución es verificar los archivos XSD de su WSDL. PHP SOAP de construcción de la solicitud sobre la base de parámetros de orden en los archivos XSD.