Jump to content

store csv data coming from api to put in a csv file to later save in db


natturefrk

Recommended Posts

0
 

What is the best way to store this data coming from the api into a csv file to later put into the db. Output: rank, level, xp, rank, level, xp, etc. This api produces about 60 rows of data per name ran and x that by about roughly 300 names that equals a lot of data. Pretty much with my current code I am pretty much creating a endless loop almost that would take a long time to execute so updating said data would be a nightmare i would think. Is there a way to accomplish the same thing without the loop or I am not sure how to go about this. My current code is a mess that much I know I am gonna be told. This code works, just not efficiently. I am thinking there may be a better way to do this.

$query = $conn->prepare("SELECT name FROM users LIMIT 1");
$query->execute();

while($row = $query->fetch(PDO::FETCH_ASSOC)){
  $name = $row['name'];
  $url = 'https://secure.runescape.com/m=hiscore/index_lite.ws?player='. 
  $name . '';//api that the csv data is coming from 
  $highscores = file_get_contents($url);
  $fields = array("Name", "Rank", "Level", "Xp");//this is to add the headers 
 // for the csv files
  $implode1 = implode($fields, ",");//turn into csv format, not sure this is 
  //even needed
  $implode1 .= "\n";/*this is to add a line break so that the explode below 
   will properly put it into its own element*/
   //otherwise data starts joining togather
  $extra_data = array("$name");/*This is to add the name that the data
  pertains too*/
  $implode2 = implode($extra_data, ",");//turn into csv format
  $highscores =  $implode1 . $implode2 . $highscores;//join as one array    
  $highscores = explode("\n", $highscores);//turn each csv into an element of 
  //its own element
  a bunch of unsets to remove unwanted data. Omitted them to condense the code
  $i = 1;
  header('Content-Type: text/csv');
  header('Content-Disposition: attachment; filename="name.csv"');

  $data = $highscores;

  $fp = fopen('highscores/' . $name . '.csv', 'wb');
  foreach ( $data as $line ) {
     $val = explode(",", $line);
     fputcsv($fp, $val);
 }
   fclose($fp); 

The pdo part I was gonna include but the way I have it setup now wouldn't work. I was thinking that I would use mysql's LOAD DATA INFILE to insert the csv data to database. The end goal here is to be able to search for player stats and to use said data to keep track of xp earned during a xp competition. I PRAY that i have included enough info... I would really appreciate any feedback if possible.

Link to comment
Share on other sites

Example output of highscores is as follows

123456(rank compared to all other players), 58(level of the skill), 1234567(total xp in skill), and just keeps repeating for all 27 skills. Ill have to look into what you suggested... not sure what you mean but pretty sure something that google search can fix.

Link to comment
Share on other sites

To make the data you load useful yo need the skill and a date the scores applied.

+------------+                               +-------------+
|  user      |                               |  skill      |
+------------+                               +-------------+
| user_id(PK)|---+                    +------| skill_id(PK)|
| name       |   |                    |      | description |
| etc        |   |                    |      +-------------+
+------------+   |     +----------+   |
                 |     | score    |   |
                 |     +----------+   |
                 +----<| user_id  |   |
                       | skill_id |>--+
                       | rank     |   
                       | level    |   
                       | xp       |   
                       | date     |
                       +----------+

 

Link to comment
Share on other sites

This is the raw data before any other changes that comes from $highscores. Rank, level, xp. All the negative vaules are what i am using the unsets for

172102,2367,204035949 244450,95,9326803 226715,99,13062902 314759,91,6351956 136596,99,24777093 112931,99,18388160 239587,94,8152884 57077,99,31947197 295686,85,3556200 269974,89,5121646 290728,85,3285716 238074,87,4161271 363824,80,2052681 169699,90,5581814 225138,85,3511420 241013,83,2701620 206930,94,8228281 162026,86,3972264 251269,73,1059054 147798,99,13294540 244330,73,1089646 166327,85,3457238 178831,82,2666078 208122,80,2176205 163361,96,10535979 215228,85,3479524 162388,84,3214554 138413,70,8883223 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 -1,-1 167565,4200 158618,1 -1,-1 233517,1 -1,-1 -1,-1

 

Link to comment
Share on other sites

irrelevant side note but wanted to point it out.. now I understand you point on database design, I am stupid uggh. Maybe I need to go back to the basics and learn proper database design apparently, not being snarky to you but to myself, because my approach was always to echo the name in each table. Actually I just learned about foreign keys, which I actually knew about but never knew what it was called or why you would use? I really really really thank you for pointing that for me. I also wanted to apologize for thinking generalizing the data from $highscores would help you understand how the data is being outputted and thinking it was a good idea instead of actually providing an actual example. I also wanted to thank you for you patience. I also learned the value of doing your own research as it helped me avoid asking a question on here in the past.

Link to comment
Share on other sites

I believe they are linefeeds because 

<?php 
	$highscores = explode("\n", $highscores);
	//here is a example of what it exactly produces: 
	/*Array(
   [0] => "name, rank, level, xp"
   [1] => "natturefrk"
   [2] => "12345(number for rank), 100(number for level), 1234567(number of rank) 
	etc .... for 27 skills*/
?>

so am i right in my assumption or am I off

Link to comment
Share on other sites

Give this a try

// CREATE OUTPUT TABLE score
$db->exec("CREATE TABLE IF NOT EXISTS score (
            score_id int not null auto_increment primary key,
            user_id int,
            skill_id int,
            rank bigint(12) ,
            level bigint(12) ,
            xp  bigint(12) ,
            date date
            )
           ");
           
           
$query = $conn->query("SELECT user_id, name FROM users LIMIT 1");
$row = $query->fetch(PDO::FETCH_ASSOC);
$uid = $row['user_id'];
$anme = $row['name'];
$url = 'https://secure.runescape.com/m=hiscore/index_lite.ws?player='. $name ;   //api that the csv data is coming from

$highscores = file_get_contents($url);             // <--- substituting data from forum post

$placeholders = [];
$values = [];

$lines = explode("\n", $highscores);
$skill = 0;
foreach ($lines as $line) {
    if (strpos($line, '-1')!==false) continue;     // ignore lines with -1 value
    if (trim($line) == '') continue;
    $linevals = array_filter(explode(',', $line));
    $placeholders[] = "(?,?,?,?,?,?)";
    array_push($values, $uid, ++$skill, date('Y-m-d'), ...$linevals);
}

// INSERT ALL 29 ROWS WITH SINGLE INSERT QUERY
$insert = $db->prepare("INSERT INTO score (user_id, skill_id, date, rank, level, xp) VALUES " . implode(',', $placeholders));
$insert->execute($values) ;

 

Link to comment
Share on other sites

sorry for late reply i just got off work about an hour ago, so I was trying to see if I see why its doing this but I get a sql error say that the user_id column doesn't exist when in fact it does. The only edit I made to the code was deleting the create table code as i just did it manually because for some reason I was getting a sql error on that one too, but I checked and everything was fine.

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.