Italian SERVER che vai ... RISPOSTA che trovi ...

MARCO C.

Active Member
Licensed User
Buongiorno,
in riferimento al post

https://www.b4x.com/android/forum/threads/java-lang-runtimeexception-json-array-expected.112011/ e alla enorme pazienza e aiuto di @drgottjr

ho avuto dei messaggi di errore sul comando INSERT INTO e Delete .
Le prime prove/test le ho fatte su un server fornito da NETSONS , dove alla richiesta di un INSERT o DELETE il server risponde con " [] ". Tutto OK
Poi , terminati i vari test, passavo al server di lavoro definitivo su ARUBA, dove alla stessa richiesta di INSERT o DELETE il server mi risponde con un WARNING e con " [] ".
Al termine l'Insert o il Delete vanno comunque a buon fine .

Di seguito il messaggio di risposta del server di ARUBA

<br />
<b>Warning</b>: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given in <b>/web/htdocs/www.MIOSITO.it/home/file/connessione.php</b> on line <b>21</b><br />
[]<br />
<b>Warning</b>: mysqli_free_result() expects parameter 1 to be mysqli_result, boolean given in <b>/web/htdocs/www.MIOSITO.it/home/file/connessione.php</b> on line <b>26</b><br />

Qualcuno utilizza ARUBA e ne conosce la motivazione ?

Grazie
 

Attachments

  • connessione.php___.txt
    715 bytes · Views: 176

drgottjr

Expert
Licensed User
Longtime User
il problema è con lo scritto (script php). ecco la documentazione di mysqli_query():

"Returns FALSE on failure. For successful SELECT, SHOW, DESCRIBE or EXPLAIN queries mysqli_query()
will return a mysqli_result object.
For other successful queries mysqli_query() will return TRUE."

lo vedo chiaramente, ma non posso spiegarlo in italiano senza moltissime parole. veddiamo se lucams responde.
sicuro che capira il significato dopo vedere la documentazione. se non, io posso spiegarglielo in inglese.

e possibile ignorare l'avvertiemento, MA non c'e modo di sapire se INSERT o DELETE sono riusciti senza fare un
SELECT subito dopo. o lo script non si applica in questo caso (INSERT, DELETE) o lo script è mal scritto.
sicurissimo.
 

drgottjr

Expert
Licensed User
Longtime User
ecco lo script que hai mandato. non faccio php da molti anni, ma guarda il codice che aggiungio per evitare l'avvertimento e per
segnalare successo/fallimento con INSERT e DELETE. in caso di INSERT o DELETE, l'app aspetta un json oggetto. per un SELECT,
el jason array e aspettato.
questo codice oppure qualcosa come questo.
secondo la documentazione, mysqli_query rende un BOOL in caso di INSERT o DELETE. in caso di SELECT, rinde un json array.
prima, faccio un test per BOOL. se si tratta di BOOL, allora verifico se il suo valore e TRUE o FALSO. in caso di TRUE rendo successo,
in caso de FALSO, rendo fallimento.

B4X:
<?php

$databasehost = "xx.yy.zzz.kkk";
$databasename = "Sql1676646_5";
$databaseusername ="Sql1676646";
$databasepassword = "password";

$con = mysqli_connect($databasehost,$databaseusername,$databasepassword, $databasename) or die(mysqli_error($con));
mysqli_set_charset ($con , "utf8");
$query = file_get_contents("php://input");
$sth = mysqli_query($con, $query);

if (mysqli_errno($con)) {
   header("HTTP/1.1 500 Internal Server Error");
   echo $query.'\n';
   echo mysqli_error($con);
}
elseif (is_bool ( $sth )) {
   if ($sth == TRUE) {
      $json = '{ "result":"OK" }';
   }
   else {
      $json = '{ "result":"FAIL" }';
   }
   echo $json;
}
else
{
   $rows = array();
   while($r = mysqli_fetch_assoc($sth)) {
     $rows[] = $r;
   }
   $res = json_encode($rows);
    echo $res;
    mysqli_free_result($sth);
}
mysqli_close($con);
?>
 

LucaMs

Expert
Licensed User
Longtime User
Premesso che con php ho smanettato pochiiiiiissimo...

1577396949741.png


mi pare di capire che il comando non necessita di parametri (void) in "modalità object oriented", mentre ne richiede uno (mysqli_result) in modalità "procedurale".

Credo che dipenda dalla versione PHP installata sul server, se sia OO o no e, a quanto pare, su Aruba non lo è (magari è possibile scegliere quale versione PHP usare).
 

drgottjr

Expert
Licensed User
Longtime User
d'accordo, ma la versione usata e la versione disponibile... se marco ha accesso a lo script php, potrebbe cambiarlo. il problema non e con fetch_assoc(), ma con mysqli_query($con, $query). ho cercato di spiegarlo nel miglior modo possibile. marco ha pubblicato lo script sul forum. credo che sarebbe possibile cambiarlo.
null non è bool. l'avviso si referisce a bool. mysqli_query rende un bool in caso di insert. fetch_assoc() non ha nulla a che vedere con un insert. lo script non deve fare un fetch_assoc() in caso di insert. non si applica. lo script manca qualcosa. o altra versione, come dici. no credo che fetch_assoc() senza parametri
evita l'avviso.
ma di maggiore importanza, avvertimento o no, non e possibile sapere se un insert o delete ha stato riuscito. il server rende un json array vuoto. un json array e la risposta a un select, non a un insert o delete. lo dice la documentazione. il server sta contestando "altra domanda".
 

LucaMs

Expert
Licensed User
Longtime User
su aruba il "motore php" è aggiornato al'ultima versione, smanettando magari facendosi aiutare dal'assistenza è possibile fare un non consigliabile downgrade
Non penso che serva un downgrade, suppongo che la versione OO sia più recente di quella procedurale.
Probabilmente deve solo selezionare il "motore php" giusto o la modalità (scegliendo appunto quella OO).
 

drgottjr

Expert
Licensed User
Longtime User
Ma si riferisce ad un parametro, non al valore restituito.
no,no. guarda el codice dello scritto. $sth è il valore reso da mysqili_query() e dopo passato a fetch_assoc(). se questo valore è bool, fetch_assoc() lancia l'avviso:
B4X:
$sth = mysqli_query($con, $query);

e dopo:
B4X:
   while($r = mysqli_fetch_assoc($sth)) {
      ...
   }

un bool non va come parametro a fetch_assoc(). fetch_assoc() non funciona con un bool come parametro. guarda l'avviso. le lighe riferite nel avviso si riferiscono a $sth. prima de passare $sth a fetch_assoc(), si deve sapere se $sth è un bool oppure un result. quindi ho messo un test per bool
 

drgottjr

Expert
Licensed User
Longtime User
su aruba il "motore php" è aggiornato al'ultima versione, smanettando magari facendosi aiutare dal'assistenza è possibile fare un non consigliabile downgrade
esattamente. quando ho suggerito di chiedere perché ci fosse un avvertimento, intendevo chiedere ad amministratore
 

MARCO C.

Active Member
Licensed User
ecco lo script que hai mandato. non faccio php da molti anni, ma guarda il codice che aggiungio per evitare l'avvertimento e per
segnalare successo/fallimento con INSERT e DELETE. in caso di INSERT o DELETE, l'app aspetta un json oggetto. per un SELECT,
el jason array e aspettato.
questo codice oppure qualcosa come questo.
secondo la documentazione, mysqli_query rende un BOOL in caso di INSERT o DELETE. in caso di SELECT, rinde un json array.
prima, faccio un test per BOOL. se si tratta di BOOL, allora verifico se il suo valore e TRUE o FALSO. in caso di TRUE rendo successo,
in caso de FALSO, rendo fallimento.

B4X:
<?php

$databasehost = "xx.yy.zzz.kkk";
$databasename = "Sql1676646_5";
$databaseusername ="Sql1676646";
$databasepassword = "password";

$con = mysqli_connect($databasehost,$databaseusername,$databasepassword, $databasename) or die(mysqli_error($con));
mysqli_set_charset ($con , "utf8");
$query = file_get_contents("php://input");
$sth = mysqli_query($con, $query);

if (mysqli_errno($con)) {
   header("HTTP/1.1 500 Internal Server Error");
   echo $query.'\n';
   echo mysqli_error($con);
}
elseif (is_bool ( $sth )) {
   if ($sth == TRUE) {
      $json = '{ "result":"OK" }';
   }
   else {
      $json = '{ "result":"FAIL" }';
   }
   echo $json;
}
else
{
   $rows = array();
   while($r = mysqli_fetch_assoc($sth)) {
     $rows[] = $r;
   }
   $res = json_encode($rows);
    echo $res;
    mysqli_free_result($sth);
}
mysqli_close($con);
?>

Buonasera,
idea fantastica quella di aggiungere dei controlli nel caso mi restituisca un valore booleano .

Ho modificato il mio script con le nuove righe di codice

PHP:
elseif (is_bool ( $sth )) {

   if ($sth == TRUE) {
      $json = '{ "result":"OK" }';
   }
   else {
      $json = '{ "result":"FAIL" }';
   }
   echo $json;

}

Solo un problema ( che esiste anche se lo faccio dal PHPMyAdmin, non mi restituisce l'errore) :
ho simulato è ho lanciato volutamente lo stesso DELETE 2 volte:
se cerco di cancellare un riga che non esiste ... comunque mi restituisce TRUE !!

A questo punto, forse , l'unico modo è quello di controllare un INSERT o DELETE, tramite un SELECT successivo alla operazione richiesta.

Grazie
 

drgottjr

Expert
Licensed User
Longtime User
che cosa e TRUE? mostrami. fai una foto o cattura di schermo. qualcosa non è ancora giusto. ci sarebbero 2 TRUE cuando fai un delete/insert. di quale stai parlando? (c'e solo un TRUE cuando fai un select.)

quello di fare un SELECT dopo INSERT/DELETE e chiamato un "workaround" - funziona mentre aspetti una correzione, ma non e decisamente ideale. possiamo lasciarlo cosi o seguire fino alla soluzione (se esiste). coraggio!

conviene sapere tutti i valore restuiti. catturali in qualche modo. vorrei verderli
 

MARCO C.

Active Member
Licensed User
che cosa e TRUE? mostrami. fai una foto o cattura di schermo. qualcosa non è ancora giusto. ci sarebbero 2 TRUE cuando fai un delete/insert. di quale stai parlando? (c'e solo un TRUE cuando fai un select.)

quello di fare un SELECT dopo INSERT/DELETE e chiamato un "workaround" - funziona mentre aspetti una correzione, ma non e decisamente ideale. possiamo lasciarlo cosi o seguire fino alla soluzione (se esiste). coraggio!

conviene sapere tutti i valore restuiti. catturali in qualche modo. vorrei verderli
Ok , mi metto a lavoro e ti inoltro , ma dalle prove che ho fatto non entra mai nella sezione "Fail".
Ti aggiorno

Grazie
 

drgottjr

Expert
Licensed User
Longtime User
interessante.
conosci STDERR?

fwrite(STDERR, "$sth is a %s\n", gettype($sth));
fwrite(STDERR, “$sth = %s\n”, $sth);

non conosco bene la sintassi in php, ma sara come vedi qui.
ci interessa $sth dopo ogni funzione in quale figura.

c'e una funzione gettype() in php per vedere che cosa e $sth.
non mi referisco al suo valore ma al suo tipo. in verita, mi
interessano il valore e il tipo

inserisci queste righe dopo ogni funzione per seguire $sth
 

drgottjr

Expert
Licensed User
Longtime User
pare che mysql sempre dice TRUE anche se non esiste il record... e necessario fare un select dopo il delete come dicevamo. l'ho appena letto in vari siti. peccato.
 

MARCO C.

Active Member
Licensed User
interessante.
conosci STDERR?

fwrite(STDERR, "$sth is a %s\n", gettype($sth));
fwrite(STDERR, “$sth = %s\n”, $sth);

non conosco bene la sintassi in php, ma sara come vedi qui.
ci interessa $sth dopo ogni funzione in quale figura.

c'e una funzione gettype() in php per vedere che cosa e $sth.
non mi referisco al suo valore ma al suo tipo. in verita, mi
interessano il valore e il tipo

inserisci queste righe dopo ogni funzione per seguire $sth

Scusa ma PHP non è il mio forte :
ho provato ad inserire le 2 righe , ma insiste a darmi vari errori .
Ho provato a sostituire la virgola con il punto pensando fosse un errore di scrittura

fwrite(STDERR, "$sth is a %s\n", gettype($sth)); ---> fwrite(STDERR, "$sth is a %s\n" . gettype($sth));

ma non riesco ad andare avanti.
A questo ho pensato che STDOUT non si possa utilizzare cosi facilmente , quindi ho inserito una semplice frase di test

fwrite(STDOUT , “hello world\n”);

ma anche questa mi segnala
<b>Parse error</b>: syntax error, unexpected 'world' (T_STRING) in <b>/web/htdocs/www.MIOSITO.it/home/file/connessione.php</b> on line <b>11</b><br />
:eek:

Ho provato anche con
fprintf(STDOUT,
con gli stessi risultati

PHP:
....
$con = mysqli_connect($databasehost,$databaseusername,$databasepassword, $databasename) or die(mysqli_error($con));
mysqli_set_charset ($con , "utf8");
$query = file_get_contents("php://input");
$sth = mysqli_query($con, $query);

fprintf(STDOUT , “hello world\n”);
fprintf((STDOUT , "$sth is a %s\n", gettype($sth));
fprintf((STDOUT , “$sth = %s\n”, $sth);


if (mysqli_errno($con))
{   header("HTTP/1.1 500 Internal Server Error");
  echo $query.'\n'; 
 echo mysqli_error($con);
}
elseif (is_bool( $sth ))  { 
   if ($sth == TRUE)
   {     
    $json = '[OK]';   
    //echo "json =ok";
   }   
   else
   {     
   $json = '[FAIL]';   
    //echo "json =fail";
   }   
   echo $json;
   }

 else

 { 
 //echo "non boolean sono su array ";
 $rows = array();   
 while($r = mysqli_fetch_assoc($sth))
 {     
 $rows[] = $r;   
 }
  $res = json_encode($rows);
   echo $res;   
mysqli_free_result($sth);
}
mysqli_close($con);
?>
 

drgottjr

Expert
Licensed User
Longtime User
lasciamo stderr per un altro dia. non importa.
se mysql risponde TRUE cuando elimini un record che non esiste (pare che funziona cosi),
alloro l'unica soluzione e fare un SELECT dopo aver fatto un DELETE/INSERT/UPDATE.

le righe: $json = '[OK]'; e $json = '[FAIL]'; che hai fatto sono sbagliate, almeno come json.
son testo, ma non json. ossia, un json array o e vuoto o contiene oggetti json. un json array
non contiene OK cosi. [{"result":"OK"}] sarebbe un json array.

se insisti sull'uso di '[OK]' o '[FAIL]' allora, l'app deve fare questo:

B4X:
dim text as string = wjob.getstring
wjob.release

if text.startswith ("[OK]") or text.startswith("[FAIL]") then
   ' fai un SELECT per verificare DELETE/INSERT/UPDATE
   ' ...
else   ' il testo non comincia con [OK] o [FAIL], dunque si tratta di un array json normale
   ' fai il normale per un array json ...
end if
 

MARCO C.

Active Member
Licensed User
...
se insisti sull'uso di '[OK]' o '[FAIL]' allora, l'app deve fare questo:

B4X:
dim text as string = wjob.getstring
wjob.release

if text.startswith ("[OK]") or text.startswith("[FAIL]") then
   ' fai un SELECT per verificare DELETE/INSERT/UPDATE
   ' ...
else   ' il testo non comincia con [OK] o [FAIL], dunque si tratta di un array json normale
   ' fai il normale per un array json ...
end if

Esatto , la mia intenzione era proprio quella : se nel controllo mi accorgo che sta arrivando un valore booleano ( e quindi non un vettore ) , allora controllo OK o FAIL
 

drgottjr

Expert
Licensed User
Longtime User
avanti! vedremo.
 
Top