Menu

#10 Need help for xmlrpc array of rooms

v1.0_(example)
open
nobody
None
1
2018-09-19
2018-09-14
Anonymous
No

Hello everyone, i'm using library xmlrpc but i cant understand this error

Fatal error: Call to a member function serialize() on integer in /web/htdocs/www.site.xxx/dir/phpxmlrpc-4.0.0/src/Value.php on line 290

my php code is

    $roomdays =
      array(
             'id'=>'12',
             'days' =>
                   array(
                        array(
                            'avail'=>5,
                            'no_ota'=>1
                        ), 'struct')
      );

    $args = array(new xmlrpcval('12121xxxxxxx.xxxx', 'string'), new xmlrpcval('1231654', 'int'), new xmlrpcval('16/09/2018', 'string'), new xmlrpcval($roomdays, 'array'));
    $message = new xmlrpcmsg('update_avail', $args);
    $struct = $server->send($message)->value(); 

json_encode($roomdays) response of $roomdays is:

{"id":"12","days":[{"avail":5,"no_ota":1},"struct"]}

but should be (as this guide says: https://tdocs.wubook.net/wired/avail.html#using-update-avail)

roomdays= [
  # The first room:
  {'id': 1, 'days': [{'avail': 1}, {}, {'no_ota': 0}],
  # The second room:
  {'id': 2, 'days': [{'price': 120}, {'closed': 1}, {}],
]

printing $roomdays i obtain

(
    [id] => 12
    [days] => Array
        (
            [0] => Array
                (
                    [avail] => 5
                    [no_ota] => 1
                )

            [1] => struct
        )
)

xmlrpcval object is:

Array
(
    [0] => xmlrpcval Object
        (
            [me] => Array
                (
                    [string] => 12121xxxxxxx.xxxx
                )

            [mytype] => 1
            [_php_class] =>
        )

    [1] => xmlrpcval Object
        (
            [me] => Array
                (
                    [int] => 1231654
                )

            [mytype] => 1
            [_php_class] =>
        )

    [2] => xmlrpcval Object
        (
            [me] => Array
                (
                    [string] => 16/09/2018
                )

            [mytype] => 1
            [_php_class] =>
        )

    [3] => xmlrpcval Object
        (
            [me] => Array
                (
                    [array] => Array
                        (
                            [id] => 12
                            [days] => Array
                                (
                                    [0] => Array
                                        (
                                            [avail] => 5
                                            [no_ota] => 1
                                        )

                                    [1] => struct
                                )

                        )

                )

            [mytype] => 2
            [_php_class] =>
        )

)

Could You please help me understanding why i can not be able to send rooms array?
Thank You so much. Daniele.

Discussion

  • Gaetano Giunta

    Gaetano Giunta - 2018-09-14

    Hello Daniele.

    The error in your code is that you assume that the construct "new xmlrpcval($roomdays, 'array')" will work on an arbitrarily nested php array.
    It will not: the constructor for your xmlrpcval object assumes that $roomdays is an array of values which are pre-encoded xmlrpcvals themselves, eg:

    new xmlrpcval(array('id' => new xmlrpcval(12, 'int'), ...))
    

    This forces you to write the code so that the xmlrpc values are built in a specific order, and can be tedious or constraining.
    The easy way to achieve recursive encoding of nested php data into xmlrpc values is to use the function "php_xmlrpc_encode", which works like json_encode.

    NB: apart from that, I am not sure from your comment if the way you structure data in $roomdays is correct, as you seem to say that even using json_encode you obtain the wrong structure?

    PS: In case you prefer speaking italian rather than english: be my guest ;-)

     
  • Gaetano Giunta

    Gaetano Giunta - 2018-09-14

    PPS: not too important, but this project has moved to github, and all tickets should be opened there going forward...

     
  • Danielix18

    Danielix18 - 2018-09-15

    Ciao Gaetano e tante grazie per la tua risposta. A seguito di questa tua indicazione ho provato a procedere in questo modo.
    1. array $roomsday lasciato identico
    2. modifica variabile $args

    $args= array(new xmlrpcval(1511561.3212, 'string'), new xmlrpcval('1852', 'int'), new xmlrpcval('16/09/2018', 'string'), new xmlrpcval(**php_xmlrpc_encode($roomdays)**,'array'));
    

    Ora non mi viene mostrato più alcun errore ma, come avevi profetizzato, non riesco ancora a inviare il valore avail.

    Può dipendere ancora dal passaggio variabile tramite la libreria?
    Come posso capire se i valori vengono inviati correttamente e con quale struttura al webservice?

    Facendo var_dump($args); ottengo questo:

    : array(4) { [0]=> object(xmlrpcval)#5 (3) { ["me"]=> array(1) { ["string"]=> string(15) "2687332539.6974" } ["mytype"]=> int(1) ["_php_class"]=> NULL } [1]=> object(xmlrpcval)#4 (3) { ["me"]=> array(1) { ["int"]=> string(10) "1425294281" } ["mytype"]=> int(1) ["_php_class"]=> NULL } [2]=> object(xmlrpcval)#6 (3) { ["me"]=> array(1) { ["string"]=> string(10) "16/09/2018" } ["mytype"]=> int(1) ["_php_class"]=> NULL } [3]=> object(xmlrpcval)#7 (3) { ["me"]=> array(1) { ["array"]=> object(PhpXmlRpc\Value)#15 (3) { ["me"]=> array(1) { ["struct"]=> array(2) { ["id"]=> object(PhpXmlRpc\Value)#9 (3) { ["me"]=> array(1) { ["int"]=> int(98970) } ["mytype"]=> int(1) ["_php_class"]=> NULL } ["days"]=> object(PhpXmlRpc\Value)#14 (3) { ["me"]=> array(1) { ["array"]=> array(2) { [0]=> object(PhpXmlRpc\Value)#12 (3) { ["me"]=> array(1) { ["struct"]=> array(2) { ["avail"]=> object(PhpXmlRpc\Value)#10 (3) { ["me"]=> array(1) { ["int"]=> int(5) } ["mytype"]=> int(1) ["_php_class"]=> NULL } ["no_ota"]=> object(PhpXmlRpc\Value)#11 (3) { ["me"]=> array(1) { ["int"]=> int(1) } ["mytype"]=> int(1) ["_php_class"]=> NULL } } } ["mytype"]=> int(3) ["_php_class"]=> NULL } [1]=> object(PhpXmlRpc\Value)#13 (3) { ["me"]=> array(1) { ["string"]=> string(6) "struct" } ["mytype"]=> int(1) ["_php_class"]=> NULL } } } ["mytype"]=> int(2) ["_php_class"]=> NULL } } } ["mytype"]=> int(3) ["_php_class"]=> NULL } } ["mytype"]=> int(2) ["_php_class"]=> NULL } } PhpXmlRpc\Value Object ( [me] => Array ( [array] => Array ( [0] => PhpXmlRpc\Value Object ( [me] => Array ( [int] => -100 ) [mytype] => 1 [_php_class] => ) [1] => PhpXmlRpc\Value Object ( [me] => Array ( [string] => Invalid Input ) [mytype] => 1 [_php_class] => ) ) ) [mytype] => 2 [_php_class] => )
    

    alla fine si nota un «Invalid Input» ma credo che non riguardi la struttura che cerco di inviare.

    Grazie ancora.

     

    Last edit: Danielix18 2018-09-15
  • Danielix18

    Danielix18 - 2018-09-17

    Salve Gaetano, ha avuto modo di analizzare la mia situazione :-) ?

     
  • Gaetano Giunta

    Gaetano Giunta - 2018-09-17

    Allora:

    1- penso ci sia ancora un errore nel codice mostrato, quello corretto dorebbe essere:

    $args = array(
        new xmlrpcval(1511561.3212, 'string'),
        new xmlrpcval('1852', 'int'),
        new xmlrpcval('16/09/2018', 'string'),
        php_xmlrpc_encode($roomdays)
    );
    

    2- il modo migliore per debuggare la comunicazione col server e vedere se l'encoding dei paramteri ha funzionato come atteso e' utilizzare il metodo setDebug della classe xmlrpc_client, pe:

    $client = new xlmlrpc_client(...);
    $client->setDebug(2);
    $args = array(...);
    $message = new xmlrpcmsg('update_avail', $args);
    $response = $client->send($message);
    

    Questo fa si che verranno stampati a schermo sia l'xml inviato as server che quello ricevuto come risposta.

    3- non ne sono sicuro al, ma se stai usando ancora la versione 3 della libreria sei caldamente incoraggiato a passare all'ultima versione, che trovi su github. Al momento e' la 4.3.1. La nuova versione apporta molti bugfix oltre a un API piu' moderna, mantenendo al tempo stesso la vecchia api disponibile e compatibile al 100%.

     
  • Gaetano Giunta

    Gaetano Giunta - 2018-09-17

    PS: per vedere l'xml prodotto, senza tentare di contattare il server, basta fare:

    $args = array(...);
    $message = new xmlrpcmsg('update_avail', $args);
    var_dump($message->serialize());
    
     
  • Gaetano Giunta

    Gaetano Giunta - 2018-09-17

    Altra nota: mi sembra che l'esmpio di chiamata che si trova alla pagina https://tdocs.wubook.net/wired/intro.html#data-types-and-xml-representations per il php non sia a prova di proiettile, poiche' manca la verifica che la risposta ricevuta non sia di tipo errore.

    Una versione migliore sarebbe:

    <?php
      include("xmlrpc.inc");
      $server = new xmlrpc_client($url);
      $args = array(new xmlrpcval($user, 'string'), new xmlrpcval($pass, 'string'), new xmlrpcval($pkey, 'string'));
      $message = new xmlrpcmsg('acquire_token', $args);
      $reponse = $server->send($message);
      if (!$reponse->faultCode()) {
        $struct = $response->value();
        ...
      } else {
        // gestione dell'errore
      }
    
     
  • Danielix18

    Danielix18 - 2018-09-18

    AND THE WINNER IS:????? GAETANO GIUNTA!!!

    Infinite grazie Gaetano, grazie alle ultime indicazioni ho concluso questo lavoro ed ero alle primissime armi con Xmlrpc. Il suo aiuto è stato preziosissimo per me.

    nota 1: sto usando la versione 4.0.0, passo all'ultima?
    nota 2: per puntare al massimo - come suggerito nella sua risposta - ho scritto questo codice, inviando un id camera errato ma il faultCode non viene rilevato.

    $response = $server->send($message);
    
          if (!$response->faultCode()) {
            $struct = $server->send($message)->value();
          } else {
            // gestione dell'errore
            echo "ERRORE ---";
          }
    

    il debug mi restituisce invece:

    <methodResponse>
    <params>
    <param>
    <value><array><data>
    <value><int>-9</int></value>
    <value><string>Invalid Rooms for the selected property</string></value>
    </data></array></value>
    </param>
    </params>
    </methodResponse>
    
     
  • Anonymous

    Anonymous - 2018-09-19

    Hello

    Nota 1: il passaggio dalla versione 4 alla 4.3 non e' obbligatorio ma consigliato: ci sono comunque un buon numero di bachi minori corretti tra le due.

    Nota 2: in effetti il codice che hai scritto per la gestione dell'errore e' quello piu' sicuro/corretto, in quanto verifica una serie di errori di vario tipo, come p.e.: timeout della chiamata http, indirizzo errato del server web che contatti, server che risponde inviando una pagina web al posto di una risposta xml, server che risponde con del codice xml che non e' valido secondo lo standard xmlrpc, etc...
    L'errore che tu ricevi ( codice -9 ) non viene pero' rilevato utilizzando un test per $response->faultCode() in quanto tecnicamente il server manda una risposta xmlrpc che e' corretta e "senza errore". Si tratta di una scelta degli sviluppatori della API che tu chiami, di incapsulare il codice applicativo di successo/errore all'interno di una risposta xmlrpc valida.
    Nel tuo codice devi quindi aggiungere una seconda condizione all'interno del primo IF, e verificare che non ci siano codici di errore applicativi (vedi https://tdocs.wubook.net/wired/return.html), ovvero:
    . il valore ritornato sia un array con 2 elementi
    . il 1o elemento dell'array sia di tipo intero e valga 0

    Piccola parentesi: questo approccio viene spesso scelto per le API di tipo REST, mentre il protocollo xmlrpc prevede gia' nativamente un suo 'codice di errore', che pero' in questo caso non sembra essere utilizzato.
    Se vogliamo analizzare in dettaglio la comunicazione client <-> server, possiamo vedere che si tratta di una piramide, con vari livellli di protocolli impilati uno sull'altro, semplificando potremmo distinguere: livello 1. elettrico / 2. tcp-ip / 3. http / 4. xmlrpc / 5. applicazione.
    Il primo IF serve a verificare gli errori di livello 2, 3 e 4, la seconda condizione gli errori di livello 5.

     

Anonymous
Anonymous

Add attachments
Cancel