-3

I'm trying to create a scoring system using flat file (I know, I'd prefer to use mysql too). I have managed to create enough so that the variables are pulled out of the game (username and score) and put into said text file. I can also output this text file in a formatted table. However i cannot get the scores to sort in any order - ideally i want descending. After searching the web the best i could find is in the attached code however this doesn't seem to actually do anything at the moment. I know its probably a stupid mistake somewhere but i could do with a fresh pair of eyes to look over it. Many Thanks, Harry

<?php
echo '<table width="5%" border="5"><tr><th>Your Score</th><th>Your Name</th></tr>';
echo '<tr><td>'.$_POST["m_score"].'</td><td>'.$_POST["name"].'</td></tr>';
echo '</table>';
echo "<br />";


$data=$_POST["m_score"].",".$_POST["name"].",";
      $filename = "./highscores.txt";
      $handle = fopen($filename, "a");

      if (!$handle)
      {
           print "There were problems opening the file";
           exit();
      }

      fwrite($handle, $data);
      fclose($handle);

      $handle = fopen($filename, "r");
      $datain = fread($handle, filesize($filename));
      $value = explode(",",$datain);        
      $row = floor(count($value)/2);
      $count = 0;


      $filename = file("./highscores.txt");
      sort($filename);
      file_put_contents("./highscores.txt", implode($filename));


    echo '<table width="5%" border="1"><tr><th>Top Scores</th><th>Top Users</th></tr>';
    for ($i=0;$i<$row;$i++)
    {
        echo '<tr>';
        for($x=0;$x<2;$x++){
            echo "<td>$value[$count]</td>";
            $count++;
        }
        echo "</tr>";
    }
    echo '</table>';

    fclose($handle);

?>
  • Your code is open to XSS in every way + your using implode with only 1 param it needs 2, plus the notice undefined variables, enable `error_reporting(E_ALL)`!!! why are you not using a database even just sqlite? – Lawrence Cherone May 15 '12 at 15:17
  • Webbiedave, The only code that i have copied is the sort($filename) segment, which i got from this site, but kudos on the attitude! Really makes me think it was worth signing up. Lawrence, XSS is not a massive concern in this piece of code, it is meant to be a very low level (as I'm sure you've guessed from my poor attempt) piece of work. I would quite happily use an alternative database and in fact (annoyingly) wrote it using mysql originally. However, it has to be written using a flat file approach - something which is a first for me. – user1396515 May 15 '12 at 15:25

1 Answers1

0

I whacked up an example you can look at to learn from, if your really not into having a fully fledged mySQL server handle your datas then here's how you can do it with the built in sqlite2 functions, super simple and useful for small data as any type of sql will always be faster to query and easyier to insert then flat files. Hope it helps:

<?php
//Create db or return connection
$db = setup('scores.db');

//form so you can enter data
echo '<h1>Put Score demo:</h1>
<form method="POST" action="">
  <p>Name: <input type="text" name="name" size="20"></p>
  <p>Score: <input type="text" name="m_score" size="20"><input type="submit" value="Submit"></p>
</form>';
//Validate score as a number and the name is set
if(isset($_POST['m_score']) && is_numeric($_POST['m_score']) && !empty($_POST['name'])){

    $name = $_POST['name'];
    $m_score = $_POST['m_score'];

    //Put result into database
    database("INSERT INTO scores (id,name , m_score) VALUES (NULL,'".sqlite_escape($name)."',".(int)$m_score.")",'put',$db);

    //Show users score
    echo '<table width="5%" border="5"><tr><th>Your Score</th><th>Your Name</th></tr>';
    echo '<tr><td>'.htmlentities($m_score).'</td><td>'.htmlentities($name).'</td></tr>';
    echo '</table>';
    echo "<br />";

}else{
    //Get Results from database
    $result = database("SELECT DISTINCT name, m_score from scores ORDER BY m_score DESC",'get',$db);

    //Show global score
    echo '<table width="5%" border="1"><tr><th>Top Scores</th><th>Top Users</th></tr>';
    foreach ($result as $row){
        echo '<tr>';
        echo "<td>".htmlentities($row['m_score'])."</td>";
        echo "<td>".htmlentities($row['name'])."</td>";
        echo "</tr>";
    }
    echo '</table>';
}

/**
 * Simple function to setup the sqlite database or return a connection to that db
 *
 * @param string $db_name
 * @return mixed (Connection or setup success)
 */
function setup($db_name){
    global $db;
    if(file_exists($db_name)){
        if(isset($db)){return $db;}
        return sqlite_open($db_name, 0666, $error);
    }
    $db = sqlite_open($db_name, 0666, $error);
    (!$db)?die($error):null;
    //Create new db
    $query ="CREATE TABLE scores (id INTEGER PRIMARY KEY, name TEXT(255), m_score INTEGER)";
    $ok = sqlite_exec($db, $query, $error);
    (!$ok)?die("Cannot execute query. $error"):null;

    echo 'Setup completed, Refresh page.';
    die;
}

/**
 * A simple sqlite CRUD with U & D missing ;p
 *
 * @param (sql query) $query
 * @param (put|get) $do
 * @param (Connection resource) $db
 * @return result
 */
function database($query,$do,$db){
    $error=null;
    $return=null;
    switch($do){
        case "get":
            $result = sqlite_query($db, $query, $error);
            if (!$result) die("Cannot execute query {$query} ". $error);
            $i=0;
            while ($entry = sqlite_fetch_array($result, SQLITE_ASSOC)) {
                foreach($entry as $key=>$value){
                    $return[$i][$key]=$value;
                }
                $i++;
            }
            return $return;
            break;
        case "put":
            $result = sqlite_exec($db, $query, $error);
            if ($result==false){ die("Cannot execute statement {$query} ". $error);}else{ return sqlite_changes($db);}
            break;
        default:
            die("Missing 2nd argument for database function.");
            break;
    }
    return true;
}

/**
 * Function to escape user input for db
 *
 * @param unknown_type $data
 * @return unknown
 */
function sqlite_escape($data) {
    if(is_array($data)){return array_map("sqlite_escape_string", $data);}
    return sqlite_escape_string($data);
}
?>
Lawrence Cherone
  • 46,049
  • 7
  • 62
  • 106