SQL haun tallentaminen taulukkoon - JSON sopivaan muotoon

Liittynyt
17.10.2016
Viestejä
486
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.
 
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.
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
 
Jos kirjoitan $seediin arvon "'; DELETE FROM DeathRunnerScores; --", onnistun tuhoamaan tietokantasi. Ihan tiedoksi.
 
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
 
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
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
 
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
 
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
Kätevää! Kiitos paljon!
 
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?
 
@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:
Jos kirjoitan $seediin arvon "'; DELETE FROM DeathRunnerScores; --", onnistun tuhoamaan tietokantasi. Ihan tiedoksi.

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);
 
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.
 
Eikö tuo olisi kuitenki turvallisinta ottaa parametrisoituna prosarina ulos tietokannasta?
 

Uusimmat viestit

Statistiikka

Viestiketjuista
261 839
Viestejä
4 548 782
Jäsenet
74 851
Uusin jäsen
hieunguyen

Hinta.fi

Back
Ylös Bottom