XmlRpc string decode into struct problem

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

XmlRpc string decode into struct problem

James Dempster
Error Received
Calling parameters do not match signature


Server Code
<code>
<?php
require_once 'Zend/XmlRpc/Server.php';

/**
 * Return the MD5 sum of a value
 *
 * @param string $value Value to md5sum
 * @return string MD5 sum of value
 */
function md5Value($value)
{
    return md5($value);
}

$server = new Zend_XmlRpc_Server();
$server->addFunction('md5Value');
echo $server->handle();
</code>


Client Code
<code>
require_once 'Zend/XmlRpc/Client.php';

$server = new Zend_XmlRpc_Client('http://localhost/xmlrpc/server.php');
$client = $server->getProxy();
$client->md5Value('071641301627');

</code>


Description
From what I can gather it's looking at the data type that the function md5Value takes, which is php default mixed. Then trying to match it up to the type provided by the XmlRpc which is string and failing.

At the moment I've commented out the code that does the check lines 505 - 507 of \library\Zend\XmlRpc\Server.php

P.S. if I force the value being passed to the server though $client->md5Value('071641301627'); to be of type struct then it works e.g. $client->md5Value(array('val'=>'071641301627');

Please help.
Reply | Threaded
Open this post in threaded view
|

Re: XmlRpc string decode into struct problem

weierophinney
Administrator
-- LetsSurf <[hidden email]> wrote
(on Monday, 23 April 2007, 01:46 PM -0700):

> Error Received
> Calling parameters do not match signature
>
>
> Server Code
> <code>
> <?php
> require_once 'Zend/XmlRpc/Server.php';
>
> /**
>  * Return the MD5 sum of a value
>  *
>  * @param string $value Value to md5sum
>  * @return string MD5 sum of value
>  */
> function md5Value($value)
> {
>     return md5($value);
> }
>
> $server = new Zend_XmlRpc_Server();
> $server->addFunction('md5Value');
> echo $server->handle();
> </code>
>
>
> Client Code
> <code>
> require_once 'Zend/XmlRpc/Client.php';
>
> $server = new Zend_XmlRpc_Client('http://localhost/xmlrpc/server.php');
> $client = $server->getProxy();
> $client->md5Value('071641301627');
>
> </code>
>
>
> Description
> From what I can gather it's looking at the data type that the function
> md5Value takes, which is php default mixed. Then trying to match it up to
> the type provided by the XmlRpc which is string and failing.
>
> At the moment I've commented out the code that does the check lines 505 -
> 507 of \library\Zend\XmlRpc\Server.php
>
> P.S. if I force the value being passed to the server though
> $client->md5Value('071641301627'); to be of type struct then it works e.g.
> $client->md5Value(array('val'=>'071641301627');

I just ran the code you provided as written above, and it worked
perfectly for me. Are you sure you didn't modify the sample you provided
here from what you were running?

The XmlRpc server scans the docblocks of your functions/class methods
and uses the typehints you provide in order to build signatures against
which to match incoming requests. Having the "@param string $value"
above tells the server that it expects a string for the value passed to
it.

I'm thinking that perhaps it saw the value you provided as a number,
however -- which would *not* match (though in my test it worked fine).

Can you try testing with alphanumerics and see if it works.

--
Matthew Weier O'Phinney
PHP Developer            | [hidden email]
Zend - The PHP Company   | http://www.zend.com/
Reply | Threaded
Open this post in threaded view
|

Re: XmlRpc string decode into struct problem

James Dempster
You are quite right Matthew thank you for your help. I was missing docblock on some of my functions and didn't know that they must be there, I just happened to copy the one with a dockblock, lol.

I'm having another issue again it's down to lack of docs.

If you have the time could you show me a quick example of how a system.multicall should be constructed.

Thanks for you time,
Regards,
LetsSurf

Matthew Weier O wrote
-- LetsSurf <letssurf@gmail.com> wrote
(on Monday, 23 April 2007, 01:46 PM -0700):
> Error Received
> Calling parameters do not match signature
>
>
> Server Code
> <code>
> <?php
> require_once 'Zend/XmlRpc/Server.php';
>
> /**
>  * Return the MD5 sum of a value
>  *
>  * @param string $value Value to md5sum
>  * @return string MD5 sum of value
>  */
> function md5Value($value)
> {
>     return md5($value);
> }
>
> $server = new Zend_XmlRpc_Server();
> $server->addFunction('md5Value');
> echo $server->handle();
> </code>
>
>
> Client Code
> <code>
> require_once 'Zend/XmlRpc/Client.php';
>
> $server = new Zend_XmlRpc_Client('http://localhost/xmlrpc/server.php');
> $client = $server->getProxy();
> $client->md5Value('071641301627');
>
> </code>
>
>
> Description
> From what I can gather it's looking at the data type that the function
> md5Value takes, which is php default mixed. Then trying to match it up to
> the type provided by the XmlRpc which is string and failing.
>
> At the moment I've commented out the code that does the check lines 505 -
> 507 of \library\Zend\XmlRpc\Server.php
>
> P.S. if I force the value being passed to the server though
> $client->md5Value('071641301627'); to be of type struct then it works e.g.
> $client->md5Value(array('val'=>'071641301627');

I just ran the code you provided as written above, and it worked
perfectly for me. Are you sure you didn't modify the sample you provided
here from what you were running?

The XmlRpc server scans the docblocks of your functions/class methods
and uses the typehints you provide in order to build signatures against
which to match incoming requests. Having the "@param string $value"
above tells the server that it expects a string for the value passed to
it.

I'm thinking that perhaps it saw the value you provided as a number,
however -- which would *not* match (though in my test it worked fine).

Can you try testing with alphanumerics and see if it works.

--
Matthew Weier O'Phinney
PHP Developer            | matthew@zend.com
Zend - The PHP Company   | http://www.zend.com/
Reply | Threaded
Open this post in threaded view
|

Re: XmlRpc string decode into struct problem

weierophinney
Administrator
-- LetsSurf <[hidden email]> wrote
(on Tuesday, 24 April 2007, 01:33 AM -0700):
>
> You are quite right Matthew thank you for your help. I was missing docblock
> on some of my functions and didn't know that they must be there, I just
> happened to copy the one with a dockblock, lol.
>
> I'm having another issue again it's down to lack of docs.
>
> If you have the time could you show me a quick example of how a
> system.multicall should be constructed.

Certainly.

Basically, system.multicall() accepts a single array as a parameter.
Each element of the array is a struct, with two elements:

  * methodName: string
  * params: array

It then returns an array. Each element in the array will be a return
value for the corresponding request element. If any of the requests
results in a fault response, the return value for that element will be a
struct with the keys 'faultCode' and 'faultString'.

So, let's say you want to call system.listMethods(),
system.methodHelp('md5Value'), and then md5Value('system.listMethods'):

    $connection = new Zend_XmlRpc_Client('http://localhost/xmlrpc');
    $client = $connection->getProxy();
    $request = array(
        array(
            'methodName' => 'system.listMethods',
            'params'     => array()
        ),
        array(
            'methodName' => 'system.methodHelp',
            'params'     => array('md5Value')
        ),
        array(
            'methodName' => 'md5Value',
            'params'     => array('system.listMethods')
    );

    $response = $client->system->multicall($request);

You should then receive an array with three elements, the first an array
of available method names, the second a string with the method
description for 'md5Value' (pulled from its docblock), and the last a
string with the md5sum of 'system.listMethods'.

> Matthew Weier O wrote:
> >
> > -- LetsSurf <[hidden email]> wrote
> > (on Monday, 23 April 2007, 01:46 PM -0700):
> >> Error Received
> >> Calling parameters do not match signature
> >>
> >>
> >> Server Code
> >> <code>
> >> <?php
> >> require_once 'Zend/XmlRpc/Server.php';
> >>
> >> /**
> >>  * Return the MD5 sum of a value
> >>  *
> >>  * @param string $value Value to md5sum
> >>  * @return string MD5 sum of value
> >>  */
> >> function md5Value($value)
> >> {
> >>     return md5($value);
> >> }
> >>
> >> $server = new Zend_XmlRpc_Server();
> >> $server->addFunction('md5Value');
> >> echo $server->handle();
> >> </code>
> >>
> >>
> >> Client Code
> >> <code>
> >> require_once 'Zend/XmlRpc/Client.php';
> >>
> >> $server = new Zend_XmlRpc_Client('http://localhost/xmlrpc/server.php');
> >> $client = $server->getProxy();
> >> $client->md5Value('071641301627');
> >>
> >> </code>
> >>
> >>
> >> Description
> >> From what I can gather it's looking at the data type that the function
> >> md5Value takes, which is php default mixed. Then trying to match it up to
> >> the type provided by the XmlRpc which is string and failing.
> >>
> >> At the moment I've commented out the code that does the check lines 505 -
> >> 507 of \library\Zend\XmlRpc\Server.php
> >>
> >> P.S. if I force the value being passed to the server though
> >> $client->md5Value('071641301627'); to be of type struct then it works
> >> e.g.
> >> $client->md5Value(array('val'=>'071641301627');
> >
> > I just ran the code you provided as written above, and it worked
> > perfectly for me. Are you sure you didn't modify the sample you provided
> > here from what you were running?
> >
> > The XmlRpc server scans the docblocks of your functions/class methods
> > and uses the typehints you provide in order to build signatures against
> > which to match incoming requests. Having the "@param string $value"
> > above tells the server that it expects a string for the value passed to
> > it.
> >
> > I'm thinking that perhaps it saw the value you provided as a number,
> > however -- which would *not* match (though in my test it worked fine).
> >
> > Can you try testing with alphanumerics and see if it works.

--
Matthew Weier O'Phinney
PHP Developer            | [hidden email]
Zend - The PHP Company   | http://www.zend.com/
Reply | Threaded
Open this post in threaded view
|

Re: XmlRpc string decode into struct problem

James Dempster
That absolutely fantastic, thanks again for all your help Matthew, and it's a great piece of work that you and Zend + Partners and developers have been doing, I'm very impressed

Regards

On 4/24/07, Matthew Weier O'Phinney <[hidden email]> wrote:
-- LetsSurf <[hidden email]> wrote
(on Tuesday, 24 April 2007, 01:33 AM -0700):
>
> You are quite right Matthew thank you for your help. I was missing docblock
> on some of my functions and didn't know that they must be there, I just
> happened to copy the one with a dockblock, lol.
>
> I'm having another issue again it's down to lack of docs.
>
> If you have the time could you show me a quick example of how a
> system.multicall should be constructed.

Certainly.

Basically, system.multicall() accepts a single array as a parameter.
Each element of the array is a struct, with two elements:

  * methodName: string
  * params: array

It then returns an array. Each element in the array will be a return
value for the corresponding request element. If any of the requests
results in a fault response, the return value for that element will be a
struct with the keys 'faultCode' and 'faultString'.

So, let's say you want to call system.listMethods(),
system.methodHelp ('md5Value'), and then md5Value('system.listMethods'):

    $connection = new Zend_XmlRpc_Client('http://localhost/xmlrpc');
    $client = $connection->getProxy();
    $request = array(
        array(
            'methodName' => 'system.listMethods',
            'params'     => array()
        ),
        array(
            'methodName' => ' system.methodHelp',
            'params'     => array('md5Value')
        ),
        array(
            'methodName' => 'md5Value',
            'params'     => array(' system.listMethods')
    );

    $response = $client->system->multicall($request);

You should then receive an array with three elements, the first an array
of available method names, the second a string with the method
description for 'md5Value' (pulled from its docblock), and the last a
string with the md5sum of 'system.listMethods'.

> Matthew Weier O wrote:
> >
> > -- LetsSurf <[hidden email]> wrote
> > (on Monday, 23 April 2007, 01:46 PM -0700):
> >> Error Received
> >> Calling parameters do not match signature
> >>
> >>
> >> Server Code
> >> <code>
> >> <?php
> >> require_once 'Zend/XmlRpc/Server.php';
> >>
> >> /**
> >>  * Return the MD5 sum of a value
> >>  *
> >>  * @param string $value Value to md5sum
> >>  * @return string MD5 sum of value
> >>  */
> >> function md5Value($value)
> >> {
> >>     return md5($value);
> >> }
> >>
> >> $server = new Zend_XmlRpc_Server();
> >> $server->addFunction('md5Value');
> >> echo $server->handle();
> >> </code>
> >>
> >>
> >> Client Code
> >> <code>
> >> require_once 'Zend/XmlRpc/Client.php';
> >>
> >> $server = new Zend_XmlRpc_Client(' http://localhost/xmlrpc/server.php');
> >> $client = $server->getProxy();
> >> $client->md5Value('071641301627');
> >>
> >> </code>
> >>
> >>
> >> Description
> >> From what I can gather it's looking at the data type that the function
> >> md5Value takes, which is php default mixed. Then trying to match it up to
> >> the type provided by the XmlRpc which is string and failing.
> >>
> >> At the moment I've commented out the code that does the check lines 505 -
> >> 507 of \library\Zend\XmlRpc\Server.php
> >>
> >> P.S. if I force the value being passed to the server though
> >> $client->md5Value('071641301627'); to be of type struct then it works
> >> e.g.
> >> $client->md5Value(array('val'=>'071641301627');
> >
> > I just ran the code you provided as written above, and it worked
> > perfectly for me. Are you sure you didn't modify the sample you provided
> > here from what you were running?
> >
> > The XmlRpc server scans the docblocks of your functions/class methods
> > and uses the typehints you provide in order to build signatures against
> > which to match incoming requests. Having the "@param string $value"
> > above tells the server that it expects a string for the value passed to
> > it.
> >
> > I'm thinking that perhaps it saw the value you provided as a number,
> > however -- which would *not* match (though in my test it worked fine).
> >
> > Can you try testing with alphanumerics and see if it works.

--
Matthew Weier O'Phinney
PHP Developer            | [hidden email]
Zend - The PHP Company   | http://www.zend.com/

Reply | Threaded
Open this post in threaded view
|

Re: XmlRpc string decode into struct problem

ppafford
Sorry to re-open a old thread but I wanted to know if I could use the MethodName as the index key for the return array?

<code>
$connection = new Zend_XmlRpc_Client('http://localhost/xmlrpc');
    $client = $connection->getProxy();
    $request = array(
        array(
            'methodName' => 'system.listMethods',
            'params'     => array()
        ),
        array(
            'methodName' => ' system.methodHelp',
            'params'     => array('md5Value')
        ),
        array(
            'methodName' => 'md5Value',
            'params'     => array(' system.listMethods')
    );

    $response = $client->system->multicall($request);
    echo print_r($response,true);
</code>

Is returns something like this

<code>
Array
(
    [0] => Array
        (
            [0] => system.listMethods
            [1] => system.methodHelp
            [2] => system.methodSignature
            [3] => system.multicall
            [4] => md5Value
        )

    [1] => 0cff048a9159b57d3568e06ee6d5b454
)
</code>

How (If possible) can I get it to return something like this

<code>
Array
(
    [0] => Array
        (
            [0] => system.listMethods
            [1] => system.methodHelp
            [2] => system.methodSignature
            [3] => system.multicall
            [4] => md5Value
        )

    [md5Value] => 0cff048a9159b57d3568e06ee6d5b454
)
</code>

With the MethodName as the array index
Reply | Threaded
Open this post in threaded view
|

Re: XmlRpc string decode into struct problem

weierophinney
Administrator
-- ppafford <[hidden email]> wrote
(on Tuesday, 23 November 2010, 02:00 PM -0800):
> Sorry to re-open a old thread but I wanted to know if I could use the
> MethodName as the index key for the return array?

<snip -- multicall example>

> How (If possible) can I get it to return something like this
>
> <code>
> Array
> (
>     [0] => Array
>         (
>             [0] => system.listMethods
>             [1] => system.methodHelp
>             [2] => system.methodSignature
>             [3] => system.multicall
>             [4] => md5Value
>         )
>
>     [md5Value] => 0cff048a9159b57d3568e06ee6d5b454
> )
> </code>
>
> With the MethodName as the array index

It's not, as doing so would violate the XML-RPC multicall specification.

You could likely extend Zend_XmlRpc_Client to do that, but it won't be
something we do in the base library.

The approach you would take is to extend Zend_XmlRpc_Client, and modify
the call() method slightly. If I were to do it, I'd do something like
this:

    public function call($method, $params = array())
    {
        $response = parent::call($method, $params);
        if (!$method = 'system.multicall') {
            return $response;
        }

        $newResponse = array();
        foreach ($params as $index => $callParams) {
            $newResponse[$callParams['methodName']] = $response[$index];
        }
        return $newResponse;
    }

(Note: completely untested!)

--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc