The code in WSClientServiceDescription::invoke() suggests to me that it should be possible to call web service methods using named paramaters, but we're not having much luck getting it to work. Without being able to use named parmaters, code becomes pretty much illegible when there are lots of paramaters for a method.
For example. An 'update_profile' method that takes paramaters od first_name, last_name, address... and maybe 20 others.
We can call this like
$service->update_profile('Tom', 'KP', 'Address line 1' ... [20 other paramaters])
It works, but impossible to read. What if I only want to update one of those 20 paramaters, and its near the end of the sequential list? Better, would be something like this:
$service->update_profile(array('favorite_color' => 'red'));
Here, the code is instantly readable, and and is not filled with a bunch of NULL values just to get to some paramater near the end.
Things we have tried, with no success:
$service->update_profile(array('favorite_color' => 'red'));
$service->update_profile('favorite_color' => 'red');
$service->update_profile('favorite_color', 'red');
What am I missing here? Is it just not possible right now? If not, then what does the code in invoke() do:
// Assign named arguments and hidden parameters.
foreach ($this->operations[$operation]['parameter'] as $param => $info) {
if (isset($arguments[$param])) {
$named_arguments[$param] = $arguments[$param];
unset($arguments[$param]);
unset($remaining_params[$param]);
}
elseif ($info['type'] == 'hidden') {
$named_arguments[$param] = $info['default value'];
unset($remaining_params[$param]);
}
}
How would $arguments[$param]
ever be set? The indexes of $arguments are always numeric.
Comment | File | Size | Author |
---|---|---|---|
#7 | wsclient-parameters_invoke-1669854-2.patch | 1.54 KB | othermachines |
Comments
Comment #1
klausiIs it a SOAP service or a REST service? Are the operation parameters configured? Did you check the operation in the UI that it lists all parameters with their names?
Comment #2
mrfelton CreditAttribution: mrfelton commentedIt is a REST service. Not 100% sure what you mean by "Are the operation parameters configured?", but yes - all the parameters are defined. This service description was not built through the UI, it was built in code. But when I look at it in the UI, everything looks perfect. Here is an example of one of the operation descriptions:
How can I call this operation in code, only passing the
referral_host
parameter?Comment #3
longwaveYou can call the invoke() method yourself and pass a set of named arguments, something like
I have not tested this with optional arguments.
It would however be better if the magic invocation (e.g. calling $service->method() directly) could accept a named array.
Comment #4
emptyvoid CreditAttribution: emptyvoid commentedThanks everyone for posting your code examples it really helped point me in the right direction. Too bad this type of information isn't in the documentation or the read me. :(
I found when using the SOAP client, depending on how the WSDL was defined I had to wrap arguments within multiple arrays to get a correct response. This was especially true for complex types.
Calling a operation directly didn't work for me, if I used invoke it seems to provide better results.
So here is an examples:
In this example I wrote a function that calls the service description then passes a productId to the operation. For some reason I have to wrap the parameter within a array with exactly the same name as the operation.
The WSDL this is based on:
I hope this helps some one..
Comment #5
erinclerico CreditAttribution: erinclerico commentedIf you look a few lines down the assignment of '$named_arguments[$param]' (currently at line 73) reads differently:
So I reason that line 55 that currently reads:
$named_arguments[$param] = $arguments[$param];
Should read:
$named_arguments[$param] = $info['default value'];
This patch solved the problem for me.
Comment #6
othermachines CreditAttribution: othermachines commented@erinclerico - Unfortunately the patch in #5 won't do because $info['default value'] is not always what you want.
I'm attaching a patch that will permit a set of named parameters to be passed into the magic invocation (calling $webservice->method() directly).
I've also added a bit of code that will unset unused parameters. This issue is being discussed over here: Issue #8655847: The provided argument for parameter is empty. I thought it might be OK to combine them since they are so closely related.** Edit: Maybe not such a hot idea to combine these two. See patch in #7.
Comment #7
othermachines CreditAttribution: othermachines commentedPosting a new patch that only deals with this issue (using named parameters).
Test results:
$status = $service->get_jobs('2210', NULL, NULL, '4');
$status = $service->get_jobs(array('series' => '2210', 'numberofjobs' => '4'));
$status = $service->invoke('get_jobs', array('series' => '2210', 'minsalary' => '', 'locationname' => '', 'numberofjobs' => '4'));
Comment #8
druth CreditAttribution: druth commented@emptyvoid comment #4 thank you for posting this. This helped me!
Dan
Comment #9
TheLioness22 CreditAttribution: TheLioness22 commented@emptyvoid, #4 -- example code was just what I needed. I was missing the extra array. I couldn't get this to submit right with the "magic" function, so went down the $service->invoke route. Couldn't figure out why it wasn't working until I came across this thread and wrapped my array in another array with the key matching the service call function/method. Agree with you that this should be in the documentation somewhere -- this wasn't intuitively discovered. Thanks again!