SQL haun tallentaminen taulukkoon - JSON sopivaan muotoon

Viestiketju alueella 'Ohjelmointi, pelikehitys ja muu sovelluskehitys' , aloittaja Jean_Sipulius, 15.10.2017.

  1. Jean_Sipulius

    Jean_Sipulius

    Viestejä:
    218
    Rekisteröitynyt:
    17.10.2016
    Minulla on ollut ongelmia tälläisen kanssa. Olen tähän mennessä tallentanut yksittäisiä hakuja tietokannasta ja tallentanut ne tähän tyylliin.

    Koodi:
    if ($function == "GetData")
    {   
        $query = "SELECT * FROM DeathRunnerScores WHERE Seed like '$seed'";
        $result = $mysqli->query($query);
       
            while ($row=mysqli_fetch_row($result))
            {
                $nameSQL = $row[1]; // 1 is Name   
                $distanceSQL = $row[2]; // 2 is distance       
                $ScoreUpdatedSuccessful["DataSuccesfullyGet"] = true;
                $ScoreUpdatedSuccessful["Distance"] = $distanceSQL;
                $ScoreUpdatedSuccessful["Name"] = $nameSQL;
               
            } 
       
        header("Content-Type: application/json");
        $encode = json_encode($ScoreUpdatedSuccessful);
        echo $encode; // Print out Json
    
    Ne tulee ulos tähän muotoon:
    Koodi:
    {"DataSuccesfullyGet":true,"Distance":"244,2","Name":"CrazyHead"}
    Eli saan yksittäisen rivin otettua, josta imen tiedot pelimoottoriin purkamalla kyseisen Jsonin. Miten minun tulee menetellä jos haluan ottaa kaikki rivit tietokannasta ja tallentaa ne samaan tyyliin Json muotoon, josta voisin ottaa ne talteen pelimoottorissa? Eli luultavammin ne pitäisi tallentaa jotenkin Json taulukkoon? Tarkoitus siis ottaa tiedot isoa Hi-Score listaa varten. Kai siihen joku komento on, mutta en ole onnistunut sen löytämisessä. Olisiko apuja täältä. Kiitoksia.
     
  2. jarif

    jarif

    Viestejä:
    294
    Rekisteröitynyt:
    01.01.2017
    Eikös tuo phpn jsonencode osaa php taulukkoa muuttaa joo taulukoksi? Luulisin että osaa koska ihan perusjuttu tuo on... Olen javaukko itse enkä phpta tunne.

    Lähetetty minun Nexus 6P laitteesta Tapatalkilla
     
  3. hsalonen

    hsalonen

    Viestejä:
    4 534
    Rekisteröitynyt:
    17.10.2016
    Jos kirjoitan $seediin arvon "'; DELETE FROM DeathRunnerScores; --", onnistun tuhoamaan tietokantasi. Ihan tiedoksi.
     
  4. Terro

    Terro

    Viestejä:
    387
    Rekisteröitynyt:
    19.10.2016
    Tee jotain tällaista:

    Koodi:
    if ($function == "GetData")
    {  
        $query = "SELECT * FROM DeathRunnerScores WHERE Seed like '".$mysqli->real_escape_string($seed)."'";
        $result = $mysqli->query($query);
        $scores = array();
    
            while ($row=mysqli_fetch_row($result))
            {
                $nameSQL = $row[1]; // 1 is Name  
                $distanceSQL = $row[2]; // 2 is distance 
                $ScoreUpdatedSuccessful = array();     
                $ScoreUpdatedSuccessful["DataSuccesfullyGet"] = true;
                $ScoreUpdatedSuccessful["Distance"] = $distanceSQL;
                $ScoreUpdatedSuccessful["Name"] = $nameSQL;
                $scores[] = $ScoreUpdatedSuccessful;
            }
      
        header("Content-Type: application/json");
        $encode = json_encode($scores);
        echo $encode; // Print out Json
    
     
    hsalonen tykkää tästä.
  5. Jean_Sipulius

    Jean_Sipulius

    Viestejä:
    218
    Rekisteröitynyt:
    17.10.2016
    Kiitos. Tuon avulla saan tiedot taulukkona, mutta tuo Unrealin Json purkaja haluaisi tuon taulukon nimen jonka sisällä nuo kaikki ovat, jotta tietää mitä käsitellä. Tuon avulla sellaista ei taida olla luotuna? Alla kuva tuosta funktiosta.

    serializer.png
     
  6. Terro

    Terro

    Viestejä:
    387
    Rekisteröitynyt:
    19.10.2016
    No sitten voit tehdä näin (FieldName on alla olevassa esimerkissä siis "values"):

    Koodi:
    if ($function == "GetData")
    { 
        $query = "SELECT * FROM DeathRunnerScores WHERE Seed like '".$mysqli->real_escape_string($seed)."'";
        $result = $mysqli->query($query);
        $scores = array("values"=>array());
    
            while ($row=mysqli_fetch_row($result))
            {
                $nameSQL = $row[1]; // 1 is Name 
                $distanceSQL = $row[2]; // 2 is distance
                $ScoreUpdatedSuccessful = array();    
                $ScoreUpdatedSuccessful["DataSuccesfullyGet"] = true;
                $ScoreUpdatedSuccessful["Distance"] = $distanceSQL;
                $ScoreUpdatedSuccessful["Name"] = $nameSQL;
                $scores["values"][] = $ScoreUpdatedSuccessful;
            }
     
        header("Content-Type: application/json");
        $encode = json_encode($scores);
        echo $encode; // Print out Json
    
     
    mhkuas tykkää tästä.
  7. Jean_Sipulius

    Jean_Sipulius

    Viestejä:
    218
    Rekisteröitynyt:
    17.10.2016
    Kätevää! Kiitos paljon!
     
  8. Xiyng

    Xiyng

    Viestejä:
    940
    Rekisteröitynyt:
    19.10.2016
    Aiheeseen liittyvä XKCD
     
  9. Jean_Sipulius

    Jean_Sipulius

    Viestejä:
    218
    Rekisteröitynyt:
    17.10.2016
    Toimi tuo Terron antama ohje. Nyt on nätisti koko tietokanta taulukkoon pakattuna ja siitä on helppo purkaa se sitten. Tuo Json on kyllä kätevä systeemi. Pitää tutustua tosiaan tuohon pahaan puutteeseen, joka on tuolla SQL:ssä tällä hetkellä. Mitään osviittaa mistä lähteä katsomaan tuota sanitointia tuohon minun tapaukseen?
     
  10. hsalonen

    hsalonen

    Viestejä:
    4 534
    Rekisteröitynyt:
    17.10.2016
    @Terro korjasi jo sen kyselyn, eikä edes sanonut mitään :) Hiljaisesti vain auttoi. Paljon hyödyllisempi oli, kuin minä tässä threadissä.

    edit: siis olen tietokantojen kanssa tekemisissä päivittäin töissäni, mutta php:ta väkersin viimeeksi joskus kuusi vuotta sitten vapaa-ajalla.. en antaisi devaajan tehdä noin vaarallista koodia töissä, mutta yleensä frameworkit välissä estävät sen joka tapauksessa. Tuo real_escape_string() hoitaa homman..
     
    Viimeksi muokattu: 16.10.2017
  11. wex

    wex

    Viestejä:
    18
    Rekisteröitynyt:
    18.11.2016
    Pakko viilata pilkkua sen verran, että teoriassa näin, käytännössä taas ei. mysqli::query suorittaa vain ensimmäisen SQL-komennon. Jos taas käytössä olisi mysqli::multi_query, tulisi kyselystä syntaksivirhe, koska kommenttimerkkien jälkeen uupuu välilyönti.

    Mutta siitä ei päästä yli, eikä ympäri, että kyseessä on vaarallinen kysely, joka mahdollistaa koko tietokannan korkkaamisen hyvin pienellä vaivalla.

    PHP-maailmassa PDO on melko mukava ystävä:
    Koodi:
    $pdo = new \PDO('mysql:host=localhost;dbname=test', 'username', 'password');
    
    $smt = $pdo->prepare('SELECT * FROM DeathRunnerScores WHERE Seed = ?');
    $smt->execute(array($seed));
    
    foreach ($smt as $row) {
        // ...
    }
    Hyvin pienellä säädöllä PDOStatement palauttaa myös suoraan objekteja, jotka voi kirjoittaa valitsemallaan striimaavalla JSON-kirjastolla ulos. Auttaa eteenkin, jos datamäärät ovat isoja, ja halutaan minimoida resurssien kulutus.

    Esimerkiksi GitHub - skolodyazhnyy/json-stream: JSON stream reader, writer and parser käytössä (todella karkea esimerkki):
    Koodi:
    class Result
    {
        public $DataSuccesfullyGet = true;
        public $Distance;
        public $Name;
    }
    
    $smt = $pdo->prepare('SELECT Distance, Name FROM DeathRunnerScores WHERE Seed = ?');
    $smt->execute(array($seed));
    
    $fh = fopen('php://stdout', "w");
    $writer = new Writer($fh);
    
    $writer->enter(Writer::TYPE_OBJECT);
    $writer->enter("values", Writer::TYPE_ARRAY);
    
    while ($row = $smt->fetchObject('Result')) {
        $writer->write(null, $row);
    }
    
    $writer->leave();
    $writer->leave();
    
    fclose($fh);
     
    nnaku tykkää tästä.
  12. jarif

    jarif

    Viestejä:
    294
    Rekisteröitynyt:
    01.01.2017
    bind-muuttujien käyttö SQL:ssa on ihan must tällaisissa, ja jos on jotain "SELECT sitä ja tätä" + mmsksm tms. eli dynaamista SQL:ää niin hylsy tulee.

    SQL-lause pitää aina olla staattinen niin ettei sitä editoida millään lailla koodissa. Jos on muuttujia niin se otenaan mukaan placeholderilla ? tai :name riitppuen työkalusta ja kielestä ja kirjastosta.

    Hyvin pitkälti SQL-injektiot on tällä hallulla ja sen ihmeempi sanitointi ei ole tarpeellista. Skriptikielet kuten PHP on vaarallisia kun ei ole staattista tyypistä ja todella tarkat kielet kuten Ada on ihan huippua. Se kieli aikoinaan tehtiin Nasaa ja ilmavoimia varten, ja hieno kieli onkin mutta jäänyt jo historiaan.
     
  13. speks

    speks

    Viestejä:
    313
    Rekisteröitynyt:
    31.10.2016
    Eikö tuo olisi kuitenki turvallisinta ottaa parametrisoituna prosarina ulos tietokannasta?