Android Question JSON Array expected

Discussion in 'Android Questions' started by ilan, Aug 4, 2019.

  1. ilan

    ilan Expert Licensed User

    hi

    i am trying to get the entires from my mysql db via php but what i get is an error saying JSON array expected...

    this is the log:

    this is the code:

    Code:
    Sub loadalljobs As ResumableSub
        jobsclv.Clear
       
        
    Dim j As HttpJob
        j.Initialize(
    "", Me)
        j.Download2(
    "http://www.sagital.net/msjobs4.php"Array As String ("action""getjobs"))
        
    Wait For (j) JobDone(j As HttpJob)
        
    If j.Success Then
            
    Log(UnescapeUnicode(j.GetString))
           
            
    Dim parser As JSONParser
            parser.Initialize(UnescapeUnicode(j.GetString))
            
    Dim root As List = parser.NextArray
            
    Log(root.Size)
        
    End If
        j.Release

        
    Return True
    End Sub


    Sub UnescapeUnicode(s As StringAs String
        
    Dim sb As StringBuilder
        sb.Initialize
        
    Dim i As Int
        
    Do While i < s.Length
            
    Dim c As Char = s.CharAt(i)
            
    If c = "\" And i < s.Length - 1 And s.CharAt(i + 1) = "u" Then
                
    Dim unicode As StringBuilder
                unicode.Initialize
                i = i + 
    2
                
    Do While i < s.Length
                    
    Dim cc As String = s.CharAt(i)
                    
    Dim n As Int = Asc(cc.ToLowerCase)
                    
    If (n >= Asc("0"And n <= Asc("9")) Or (n >= Asc("a"And n <= Asc("f")) Then
                        unicode.Append(s.CharAt(i))
                    
    Else
                        i = i - 
    1
                        
    Exit
                    
    End If
                    i = i + 
    1
                
    Loop
                sb.Append(
    Chr(Bit.ParseInt(unicode.ToString, 16)))
            
    Else
                sb.Append(c)
            
    End If
            i = i + 
    1
        
    Loop
        
    Return sb.ToString
    End Sub
    and php code:

    Code:
    Case "getjobs":
            $q = mysqli_query($con, 
    "SELECT * FROM $table ORDER BY id");
            $rows = 
    array();
            
    while($r = mysqli_fetch_assoc($q))
            {
                $rows[] = $r;
            
    }
            print json_encode($rows);
            mysqli_free_result($q);
        break;
    what am i doing wrong?

    thanx
     
  2. emexes

    emexes Well-Known Member Licensed User

    I don't know, it looks good to me. FWIW, if I run this code in B4J using data downloaded from your website via Chrome browser on a PC:
    Code:
    Dim JSONData As String = $"[{"id":"3","title":"\u05d3\u05e8\u05d5\u05e9\u05d9\u05dd \u05db\u05d5\u05d5\u05e0\u05d9\u05dd CNC \u05dc\u05db\u05e8\u05e1\u05d5\u05dd \u05d5\u05d7\u05e8\u05d9\u05d8\u05d4","date":"30-07-2019","fav":"0","title2":"\u05d2\u05d5\u05dc\u05d3\u05d1\u05e8\u05d2\u05e8 \u05d8\u05db\u05e0\u05d5\u05dc\u05d5\u05d2\u05d9\u05d5\u05ea","jobexp":"\u05dc\u05d7\u05d1\u05e8\u05ea \u05d2\u05d5\u05dc\u05d3\u05d1\u05e8\u05d2\u05e8 \u05d8\u05db\u05e0\u05d5\u05dc\u05d5\u05d2\u05d9\u05d5\u05ea \u05d4\u05de\u05de\u05d5\u05e7\u05de\u05ea \u05d1\u05d0.\u05ea \u05d1\u05e8 \u05dc\u05d1 (\u05dc\u05d9\u05d3 \u05db\u05e8\u05de\u05d9\u05d0\u05dc), \u05d3\u05e8\u05d5\u05e9\u05d9\u05dd \u05db\u05d5\u05d5\u05e0\u05d9\u05dd CNC \u05dc\u05db\u05e8\u05e1\u05d5\u05dd \u05d5\u05d7\u05e8\u05d9\u05d8\u05d4.\r\n*\u05de\u05e9\u05e8\u05d4 \u05de\u05dc\u05d0\u05d4.\r\n*\u05d0\u05d5\u05d5\u05d9\u05e8\u05d4 \u05e0\u05e2\u05d9\u05de\u05d4 \u05d5\u05d0\u05d9\u05db\u05d5\u05ea\u05d9\u05ea!\r\n*\u05ea\u05e0\u05d0\u05d9\u05dd \u05d8\u05d5\u05d1\u05d9\u05dd \u05de\u05d0\u05d3 \u05dc\u05de\u05ea\u05d0\u05d9\u05de\u05d9\u05dd.","jobneeds":"- \u05e0\u05d9\u05e1\u05d9\u05d5\u05df \u05e7\u05d5\u05d3\u05dd - \u05d7\u05d5\u05d1\u05d4.\r\n- \u05e8\u05d0\u05e9 \u05d2\u05d3\u05d5\u05dc, \u05de\u05d5\u05e1\u05e8 \u05e2\u05d1\u05d5\u05d3\u05d4 \u05d5\u05d7\u05e8\u05d9\u05e6\u05d5\u05ea.\r\n*\u05d4\u05de\u05e9\u05e8\u05d4 \u05de\u05d9\u05d5\u05e2\u05d3\u05ea \u05dc\u05e0\u05e9\u05d9\u05dd \u05d5\u05d2\u05d1\u05e8\u05d9\u05dd \u05db\u05d0\u05d7\u05d3.","experience":"1-2","category":"CNC, \u05db\u05e8\u05e1\u05dd - \u05d7\u05e8\u05d8","place":"\u05e6\u05e4\u05d5\u05df","period":"\u05de\u05e9\u05e8\u05d4 \u05de\u05dc\u05d0\u05d4","price":"0","publisher":"\u05d2\u05d5\u05dc\u05d3\u05d1\u05e8\u05d2\u05e8","pubemail":"reut@gmt.co.il","pubid":"1","startdatetime":"00000000000","enddatetime":"00000000000","status":"0"}]"$
    Log(JSONData.Length)
    Log("|" & JSONData & "|")

    Dim JSONDataUnicode As String = UnescapeUnicode(JSONData)
    Log(JSONDataUnicode.Length)
    Log("|" & JSONDataUnicode & "|")

    Dim parser As JSONParser
    parser.Initialize(JSONDataUnicode)
    Dim root As List = parser.NextArray
    Log(root.Size)
    Dim branch As Object = root.Get(0)
    Log(branch)
    then I get this log:
    Code:
    1877
    |[{
    "id":"3","title":"\u05d3\u05e8\u05d5\u05e9\u05d9\u05dd \u05db\u05d5\u05d5\u05e0\u05d9\u05dd CNC \u05dc\u05db\u05e8\u05e1\u05d5\u05dd \u05d5\u05d7\u05e8\u05d9\u05d8\u05d4","date":"30-07-2019","fav":"0","title2":"\u05d2\u05d5\u05dc\u05d3\u05d1\u05e8\u05d2\u05e8 \u05d8\u05db\u05e0\u05d5\u05dc\u05d5\u05d2\u05d9\u05d5\u05ea","jobexp":"\u05dc\u05d7\u05d1\u05e8\u05ea \u05d2\u05d5\u05dc\u05d3\u05d1\u05e8\u05d2\u05e8 \u05d8\u05db\u05e0\u05d5\u05dc\u05d5\u05d2\u05d9\u05d5\u05ea \u05d4\u05de\u05de\u05d5\u05e7\u05de\u05ea \u05d1\u05d0.\u05ea \u05d1\u05e8 \u05dc\u05d1 (\u05dc\u05d9\u05d3 \u05db\u05e8\u05de\u05d9\u05d0\u05dc), \u05d3\u05e8\u05d5\u05e9\u05d9\u05dd \u05db\u05d5\u05d5\u05e0\u05d9\u05dd CNC \u05dc\u05db\u05e8\u05e1\u05d5\u05dd \u05d5\u05d7\u05e8\u05d9\u05d8\u05d4.\r\n*\u05de\u05e9\u05e8\u05d4 \u05de\u05dc\u05d0\u05d4.\r\n*\u05d0\u05d5\u05d5\u05d9\u05e8\u05d4 \u05e0\u05e2\u05d9\u05de\u05d4 \u05d5\u05d0\u05d9\u05db\u05d5\u05ea\u05d9\u05ea!\r\n*\u05ea\u05e0\u05d0\u05d9\u05dd \u05d8\u05...
    627
    |[{
    "id":"3","title":"דרושים כוונים CNC לכרסום וחריטה","date":"30-07-2019","fav":"0","title2":"גולדברגר טכנולוגיות","jobexp":"לחברת גולדברגר טכנולוגיות הממוקמת בא.ת בר לב (ליד כרמיאל), דרושים כוונים CNC לכרסום וחריטה.\r\n*משרה מלאה.\r\n*אווירה נעימה ואיכותית!\r\n*תנאים טובים מאד למתאימים.","jobneeds":"- ניסיון קודם - חובה.\r\n- ראש גדול, מוסר עבודה וחריצות.\r\n*המשרה מיועדת לנשים וגברים כאחד.","experience":"1-2","category":"CNC, כרסם - חרט","place":"צפון","period":"משרה מלאה","price":"0","publisher":"גולדברגר","pubemail":"reut@gmt.co.il","pubid":"1","startdatetime":"00000000000","enddatetime":"00000000000","status":"0"}]|
    1
    {date=30-07-2019, period=משרה מלאה, pubemail=reut@gmt.co.il, jobneeds=- ניסיון קודם - חובה.
    - ראש גדול, מוסר עבודה וחריצות.
    *המשרה מיועדת לנשים וגברים כאחד., title2=גולדברגר טכנולוגיות, jobexp=לחברת גולדברגר טכנולוגיות הממוקמת בא.ת בר לב (ליד כרמיאל), דרושים כוונים CNC לכרסום וחריטה.
    *משרה מלאה.
    *אווירה נעימה ואיכותית!
    *תנאים טובים מאד למתאימים., title=דרושים כוונים CNC לכרסום וחריטה, experience=1-2, price=0, pubid=1, enddatetime=00000000000, publisher=גולדברגר, fav=0, id=3, place=צפון, category=CNC, כרסם - חרט, startdatetime=00000000000, status=0}
     
    ilan and Shelby like this.
  3. Erel

    Erel Administrator Staff Member Licensed User

    If you still get this error then save the string to a file and upload it.
     
    ilan likes this.
  4. ilan

    ilan Expert Licensed User

    Thanx i will try it out
     
  5. amidgeha

    amidgeha Member Licensed User

    Invalid character at the very first character, I deleted [ and retyped [ then it works
    go to
     
    ilan likes this.
  6. amidgeha

    amidgeha Member Licensed User

    Yes, it works your way. to prove it I used this and this I just deleted the [ character and the retyped it then all is ok
    SCREENSHOT
     
    Last edited: Aug 5, 2019
    ilan likes this.
  7. ilan

    ilan Expert Licensed User

    thank you very much, i will try it when i get home.
    so all i need is to remove the [] chars before parsing it via json parser?
     
  8. amidgeha

    amidgeha Member Licensed User

    No, I just wanted to point out that there is something before the [ character . Note that Hebrew is double byte character language
     
  9. emexes

    emexes Well-Known Member Licensed User

    Perhaps it is a byte order mark. It is a bit unkind that it isn't removed for you when the return result is converted to a string (and presumably this is why I didn't experience the problem: Chrome cleaned it off for me).

    Simplest solution is probably to do a .SubString from the "[" onwards.
     
    ilan likes this.
  10. ilan

    ilan Expert Licensed User

    Code:
    Dim j As HttpJob
        j.Initialize(
    "", Me)
        j.Download2(
    "http://sagital.net.cp-25.webhostbox.net/" & "msjobs.php"Array As String ("action""getjobs"))
        
    Wait For (j) JobDone(j As HttpJob)
        
    If j.Success Then
            
    Dim str As String = UnescapeUnicode(j.GetString)
            
    Log(str)
            
            
    Dim size As Int = str.IndexOf2("[",0)
            
    Log(size)

    '        Dim parser As JSONParser
    '        parser.Initialize(str)
    '        Dim root As List = parser.NextArray
    '        Log(root.Size)
    '        Dim branch As Object = root.Get(0)
    '        Log(branch)
            
        
    End If
        j.Release
    logs:

    you are right. there are 2 chars (invisible chars) that are before the char [ what breaks the JSON parsing. really weird. what could be the reason for that?
    is something in my PHP code wrong?

    I will probably do the str.indexof2() to remove everything before [ but why is that happening?

    thanx
     
  11. emexes

    emexes Well-Known Member Licensed User

    The first two characters of the returned data are Byte Order Marks = Unicode 0xFEFF = three bytes EF BB BF when encoded by UTF-8. Why there are two of them is a bit of mystery - I am guessing there were some Unicode decoding problems in the pipeline back in the early days, and each time BOMs were added to fix the problem.

    Or perhaps it was a cautious programmer having a bad day, who added two of them to be sure, to be sure ;-)

    upload_2019-8-6_8-1-29.png

    Personally I think they should be removed when the string comes out the other end of the UTF-8 pipeline and is converted back into discrete atomic Unicode characters where byte order has no meaning.

    Having thought a bit harder, a simpler way to remove single and multiple BOMs is probably:
    Code:
    '''Dim DirtyString As String = UnescapeUnicode(j.GetString)
    Dim CleanString As String = UnescapeUnicode(j.GetString).Replace(Chr(0xFEFF), "")    'remove BOMs if present
    although this will remove them from everywhere in the string, not just from at the beginning - but this is probably a good thing.
     
    Last edited: Aug 6, 2019
    ilan likes this.
  12. ilan

    ilan Expert Licensed User

    thanx, a lot @emexes for the explanation. I encounter another issue that I had a long time ago but did not know how to fix. I googled a lot but all the suggestions did not help. my problem is that after I update my MySQL DB with a new entry and I ask to receive all entries back I don't get the new entries. if I change the name of the PHP file in my FTP I get the new entries. if I wait for a while I also get the new entries so I think there is a cache file that loads the old entries but I am not sure. how can I always get immediately the new entries without renaming my PHP file or waiting a few minutes?

    I read this but I cant find the php.ini file https://stackoverflow.com/questions/11372704/php-file-will-not-update-in-browser
     
  13. emexes

    emexes Well-Known Member Licensed User

    I have a theory, went to test it using your server, got this:

    upload_2019-8-6_11-50-9.png

    If you could restore that php test page, that'd be great. Better yet, set up another test page that returns changing information - doesn't matter what: random, counter, current time all good.
     
    ilan likes this.
  14. Brandsum

    Brandsum Active Member Licensed User

    Yes that is a problem of web api. Either you can set no cache header at the very first line of your php file or you can send DateTime.Now as an extra query parameter to overcome this issue.
     
    ilan likes this.
  15. emexes

    emexes Well-Known Member Licensed User

    That was where I was heading, thus now no need to test.
     
    ilan likes this.
  16. ilan

    ilan Expert Licensed User

    i have renamed the file when i was testing yesterday
    this is the right link: http://www.sagital.net/msjobs.php?action=getjobs


    can you please give me tell me what i should write ? and also where. i am a big noob with php.

    thank you very much :)
     
  17. Brandsum

    Brandsum Active Member Licensed User

    PHP:
    <?php
    header
    ("Content-Type: application/json");
    header("Expires: on, 01 Jan 1970 00:00:00 GMT");
    header("Last-Modified: " gmdate("D, d M Y H:i:s") . " GMT");
    header("Cache-Control: no-store, no-cache, must-revalidate");
    header("Cache-Control: post-check=0, pre-check=0"false);
    header("Pragma: no-cache");

    //your code

    ?>
     
    DonManfred and ilan like this.
  18. ilan

    ilan Expert Licensed User

    thank you very much for your help and of course a big thanx to all members here. (great community :) )
     
  19. emexes

    emexes Well-Known Member Licensed User

    Where I was heading was that http requests are often cached at various places on the path from the source server to end user client or browser.

    I'm pretty sure that usually that caching is keyed on the URL, so all that should be necessary to bypass it is to request a different URL. I was going to just use a random numberm but this:
    is probably a nicer solution, could be useful for debugging too, eg, in your server logs of http request, you'll get an idea of how long the request took to get from the client to the server.

    Anyway, I just tried:

    http://www.sagital.net/msjobs.php?action=getjobs&random=123554

    and it returned the same data as without the extra random parameter, so that's a start.

    I did expect to see some cache-timeout line in the http header, but... there doesn't seem to be any (Age looks like a 3-minute countdown?):
    Code:
    HTTP/1.1 200 OK
    Date: Tue, 
    06 Au019 07:11:53 GMT
    Server: Apache/2.4.39 (cPanel) OpenSSL/1.0.2r mod_bwlimited/1.4 Phusion_Passenger/5.3.7
    X-Powered-By: PHP/
    5.4.45
    Vary: Accept-Encoding
    Content-
    Type: text/html
    X-Varnish: 
    229642900 224812425
    Age: 
    172
    Via: 
    1.1 varnish-v4
    Accept-Ranges: bytes
    Content-Length: 
    10104
    Connection: keep-alive

    [{
    "id":"3","title":"\u05d3\u05e8\u05d5\u05e9\u05d9\u05dd \u05db\ ...
     
    Last edited: Aug 6, 2019
    ilan likes this.
  20. ilan

    ilan Expert Licensed User

    so it is cached as i assumed. i will try the PHP snipped that @Brandsum posted and will see if it is updated immediately. thanx again for all your help and tests :)
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice