Need help for xmlrpc array of rooms
Brought to you by:
ggiunta
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.
Anonymous
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:
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 ;-)
PPS: not too important, but this project has moved to github, and all tickets should be opened there going forward...
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
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:
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
Salve Gaetano, ha avuto modo di analizzare la mia situazione :-) ?
Allora:
1- penso ci sia ancora un errore nel codice mostrato, quello corretto dorebbe essere:
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:
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%.
PS: per vedere l'xml prodotto, senza tentare di contattare il server, basta fare:
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:
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.
il debug mi restituisce invece:
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.