Jump to content
natturefrk

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

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.

Share this post


Link to post
Share on other sites

Can you show us a sample portion of $highscores that you egt from the api call?

A point on data design - you have the user's name in the user table. You should not be repeating it in every row of the data table, they should contain the user's id value as a foreign key instead.

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

Strange there is nothing to say which of the 27 skills those numbers refer to.

Do you want the text that is in (..) also writing to the csv or just the number value?

Share this post


Link to post
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     |
                       +----------+

 

Share this post


Link to post
Share on other sites

.  Yeah oddly enuff it dont so thats what I am doing with $fields to add those labels for the values.Which by the way you asked that,  needs to include the labels for the skill values as well, am I right?

Edited by natturefrk
Clarify

Share this post


Link to post
Share on other sites

I still don't know what the data you are processing looks like.

Unless, if you echo $highscores, it gives

123456(rank compared to all other players), 58(level of the skill), 1234567(total xp in skill),

 

Share this post


Link to post
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

 

Edited by natturefrk
put the values in code brackets, clarify

Share this post


Link to post
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.

Edited by natturefrk

Share this post


Link to post
Share on other sites

Are those really spaces between each set of three values or are they linefeeds (\n)? HTML has a way treating all whitespace as a space.

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

We'll find out when I try to process it.

 

[edit]

I split the data you posted into lines of 3 values. You said 27 but there are 28 before it starts getting weird.

Capture.PNG

Edited by Barand

Share this post


Link to post
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) ;

 

Edited by Barand

Share this post


Link to post
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.

 

Edited by natturefrk

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • 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.