On line 422 in services.module (v 1.8.2.88.2.14 2009/12/11) there's this line:
$result = call_user_func_array($method['callback'], $args);
$args is an array of arguments to the callback, for example:
Array
(
[0] => 5
[2] => Test
)
Following the previous logic, the key denotes the position of the argument in the function signature. However, call_user_func_array() cannot use keys for argument position. In effect, what happens is this:
callback(5, 'Test');
not this:
callback(5, null, 'Test'); as intended.
I've been googling and pouring over the relevant pages at php.net without finding anything to support the idea of indexes as argument positions in the function called. It looks like this will have to be implemented manually by creating an array of the same length, then combining the two.
Comments
Comment #1
marcingy commentedMarking as won't fix and if this is a real issue then it is an issue with php/drupal core rather than services.
Comment #2
solipsist commentedCan you explain your reasoning behind deeming this an issue with PHP and not Services? Even if it could be considered a bug in PHP, a workaround in Services is needed since call_user_func_array() doesn't work as expected. I'm prepared to write a patch.
Comment #3
solipsist commentedI can see a case for not considering this an issue. A well-defined method wouldn't order arguments without regards to whether they're required or not, in which case this won't be an issue.
However, assuming we have this function:
Using the JSON-RPC server, which can take arguments by name, we can pass just a few of the arguments, say argument 1, 4 and 6:
Example 1:
Instead of having to pass a bunch of NULL values just to match the function signature (which is internal to the actual implementation and should not be exposed through the API):
Example 2:
Using example one above, the way it works now the function call would be
function(1, 4, 6), which is not what we intended, we'd rather see this:function(1, null, null, 4, null, 6), without having to resort to doing example two.However allowing calls by parameter name and hiding argument order would mean the server implementation would have to assume default values for the arguments not included in our call, more precisely: two, three and five, since we cannot dynamically get the function signature while the code is being executed.
A solution would be to include a #default key in hook_service for each argument defined. Basically, every argument set #optional = TRUE could also have a #default key defined.
Comment #4
solipsist commentedComment #5
gddI can see the point being made here, and I understand how it can cause problems and would be nice to fix. However it just seems like too major a change to be made this late in the release cycle (I hope to roll a stable release next week or possibly sooner) especially since it can easily be worked around easily by the caller. If you want to work on a patch for 2.1, I'd be more than happy to look at it. Marking this postponed for the time being.
Comment #6
gddI definitely think this is a good change for 3.x, and it ties into #388236: Update Method Declaration to be in Drupal Style in terms of naming.
Comment #7
iTiZZiMO commentedthis function makes also problems on system resource, so i had to disable it
i had to disable the following code part (line 139, services.runtime.inc)
/** Call default or custom access callback
if (call_user_func_array($controller['access callback'], $access_arguments) != TRUE) {
global $user;
return services_error(t('Access denied for user !uid "@user"', array(
'!uid' => $user->uid,
'@user' => isset($user->name) ? $user->name : 'anonymous',
)), 401);
}
**/
no i can get a session id via path/to/endpoint/system/connect
is there any possibilty to fix this issue?
Comment #8
ygerasimov commentedI this is really critical issue when it comes to passing arguments to resource callback. Find attached patch that just fix this particular case, but the problem is deeper.
I think it would be nice to not use not keyed arguments arrays at all. Also to pass arguments array to resource callback and not every argument separately.
I understand that this is cruicial changes that change API so I would like to hear comments from maintainers whether it is nice feature to implement.
Comment #9
kylebrowning commentedI think this has been fixed in 3.x-dev that I committed today, can anyone verify? If not, explain to me what is going on here.
Comment #10
ygerasimov commentedNo. The issue is not fixed in current 3.x-dev version. Please install attached echo resource. When you enable it try to see the result of the call:
You will see that value of $_GET['arg2'] gets passed to argument $arg1. So I reply will be:
Comment #11
kylebrowning commentedI think this patch is a lot cleaner and solves the problem.
One thing you never did was set the default value for the info of the argument
Either way, this new patch takes into account if you set it null, or it does not exist.
[EDIT] Typo fixes
Comment #12
ygerasimov commentedThis patch works properly (that is much nicer place to fix) and does fix the bug
Comment #13
kylebrowning commentedThis issue has been fixed and I will update the documention for the api per ygerasimov's suggestion
Comment #14
kylebrowning commented