Music playlist via PHP. json_encode() array limit? - php

Im using PHP to create a playlist. Two random songs are chosen from a directory, and their name and location are stored in an array and then written to a file via json_encode().
$arraySongs[] = array('name' => $songName , 'mp3' => $webUrl);
This works great. I can make a very long playlist, two songs at a time. Id also like to remove songs, so I have an AJAX powered delete button, that posts the id of the track to be deleted, PHP then loads the whole tracklist...
$decoded = json_decode(file_get_contents($tracklist),true);
and removes the given song from the array, then re encodes and re writes the json text file. This all works great.
The problem comes whenever I try to delete anything with a playlist of more than 10 items.
Typically, my song.json file goes [{name:song1,mp3:song url},{name:song2,mp3:song2 url}]
However, when I have a list of more than 10 items, the re encoded playlist looks like this:
[{ ... },{name:song9,mp3:song9 url}],[10,{"name":song10,mp3:song10 url}]
Why is my re-encoded array get that strange [10,{"name"... [11,{"name"... [12,{"name"...
but everything below 10 is always fine?
Thanks for reading this! Any suggestions would be greatly appreciated, this is driving me nuts!
Here is the code im Using:
<?php
$json = "song.php";
$decoded = json_decode(file_get_contents($json),true);
$playlist = array();
$names = array();
// Now Get i From Javascript
$i=$_POST['id'];
//Select i's Array
$collect_array=$decoded[$i];
while (list ($key, $val) = each ($collect_array)) {
//Remove i's Values
//echo "<br />$key -> $val <br>";
unset($decoded[$i]);
}
//Take all the remaining arrays
$collect_array=$decoded;
while (list ($key, $val) = each ($collect_array)) {
$arraySongs[] = array($key , $val);
}
// Our New Array ready for json.
$jsonData = json_encode($arraySongs);
// open song.php and scribble it down
$tracklist = $json;
$fh = fopen($tracklist, 'w') or die("can't open filename: $tracklist");
fwrite($fh, $jsonData);
fclose($fh);
?>

try removing elements with unset
debug your code (not posted in the thread, so do it yourself) by adding a line where you var_dump or print_r the whole thing before json_encode
or it's a bug in json_encode which would not be nice...

Encode the track ID on 2 or even 3 digits using the php function sprintf with parameter %02d.
This worked fine for me.

Related

php - for loop repeating itself / going out of sequence

I'm very new to PHP, making errors and learning as I go. Please be gentle! :)
I want to access some data from Blizzard.com's API. For this particular data set, it's not a block of data in JSON, rather each object has it's own URL to access. I estimate that there are approx 150000 objects, however I don't know the start or end points of the number range. So I'm having to assume 1 and work past the highest number I know (269065)
To get the data, I need to access each object's data via a JSON file, which I read, get the contents of & drop in to a text file (this could be written as an insert in to a SQL db too, as I'm able to do this if it's the text file that's the issue). But to be honest, I would love to get to the bottom of why this is happening as much as anything!
I wasn't going to try and run ~250000 iterations in a for loop, I thought I'd try something I considered small, 2000.
The for loop starts with $a as 1, uses $a as part of the URL, loads & decodes the JSON, checks to see if the first field (ID) in the object is set, if it is, it writes a few fields to data.txt & if the first field (ID) isn't set it just writes $a to data.txt (so I know it's a null for other purposes not outlined here).
Simple! Or so I thought, after approx after 183 iterations, the data written to the text file goes awry as seen by the quote below. It is out of sequence and starts at 1 again, then back to 184 ad nauseam. The loop then seems to be locked in some kind of infinite loop of running, outputting in a random order until I close the page 10-20 minutes later.
I have obviously made a big mistake! But I have no idea what I have done wrong to have caused this. During my attempts I have rewritten the code with new variable names, so a new text does not conflict with code that could be running in memory.
I've tried resetting variables to blank at the end of the loop in case it something was being reused that was causing a problem.
If anyone could point out any errors in my code, or suggest something for me to look in to, to handle bigger loops that would be brilliant. I am assuming my issue may be a time out or memory problem. But I don't know where to start & was hoping I'd find some suggestions here.
If it's relevant, I am using 000webhostapp.com as my host provider for now, until I get some paid for hosting.
1 ... 182 183 1 184 2 3 185 4 186 5 187 6 188 7 189 190 8 191
for ($a = 1; $a <= 2000; $a++) {
$json = "https://eu.api.battle.net/wow/recipe/".$a."?locale=en_GB&<MYPRIVATEAPIKEY>";
$contents = file_get_contents($json);
$data = json_decode($contents,true);
if (isset($data['id'])) {
$file = fopen("data.txt","a");
fwrite($file,$data['id'].",'".$data['name']."'\n");
fclose($file);
} else {
$file = fopen("data.txt","a");
fwrite($file,$a."\n");
fclose($file);
}
}
The content of the file I'm trying to access is
{"id":33994,"name":"Precise Strikes","profession":"Enchanting","icon":"spell_holy_greaterheal"}
I scrapped the original plan and wrote this instead. Thank you again who took the time out of their day to help and offer suggestions!
$b = $mysqli->query("SELECT id FROM `static_recipes` order by id desc LIMIT 1;")->fetch_object()->id;
if (empty($b)) {$b=1;};
$count = $b+101;
$write = [];
for ($a = $b+1; $a < $count; $a++) {
$json = "https://eu.api.battle.net/wow/recipe/".$a."?locale=en_GB&apikey=";
$contents = #file_get_contents($json);
$data = json_decode($contents,true);
if (isset($data['id'])) {
$write [] = "(".$data['id'].",'".addslashes($data['name'])."','".addslashes($data['profession'])."','".addslashes($data['icon'])."')";
} else {
$write [] = "(".$a.",'a','a','a'".")";
}
}
$SQL = ('INSERT INTO `static_recipes` (id, name, profession, icon) VALUES '.implode(',', $write));
$mysqli->query($SQL);
$mysqli->close();
$write = [];
for ($a = 1; $a <= 2000; $a++) {
$json = "https://eu.api.battle.net/wow/".$a."?locale=en_GB&<MYPRIVATEAPIKEY>";
$contents = file_get_contents($json);
$data = json_decode($contents,true);
if (isset($data['id'])) {
$write [] = $data['id'].",'".$data['name']."'\n";
} else {
$write [] = $a."\n";
}
}
$file = fopen("data.txt","a");
fwrite($file, implode('', $write));
fclose($file);
Also, why you are think what some IDS isn't duplicated at several "https://eu.api.battle.net/wow/[N]" urls data?
Also if you are I wasn't going to try and run ~250000 think about curl_multi_init(): http://php.net/manual/en/function.curl-multi-init.php
I can't really see anything obviously wrong with your code, can't run it though as I don't have the JSON
It could be possible that there is some kind of race condition since you're opening and closing the same file hundreds of times very quickly.
File operations might seem atomic but not necessarily so - here's an interesting SO thread:
Does PHP wait for filesystem operations (like file_put_contents) to complete before moving on?
Like some others' suggested - maybe just open the file before you enter the loop then close the file when the loop breaks.
I'd try it first and see if it helps.
There's nothing in your original code that would cause that sort of behaviour. PHP will not arbitrarily change the value of a variable. You are opening this file in append mode, are you certain that you're not looking at old data? Maybe output some debug messages as you process the data. It's likely you'd run up against some rate limiting on the API server, so putting a pause in there somewhere may improve reliability.
The only substantive change I'd suggest to your code is opening the file once and closing it when you're done.
$file = fopen("data_1_2000.txt", "w");
for ($a = 1; $a <= 2000; $a++) {
$json = "https://eu.api.battle.net/wow/recipe/$a?locale=en_GB&<MYPRIVATEAPIKEY>";
$contents = file_get_contents($json);
$data = json_decode($contents, true);
if (!empty($data['id'])) {
$data["name"] = str_replace("'", "\\'", $data["name"]);
$record = "$data[id],'$data[name]'";
} else {
$record = $a;
}
fwrite($file, "$record\n");
sleep(1);
echo "$a "; if ($a % 50 === 0) echo "\n";
}
fclose($file);

Replace Array value with other preg_replaced value

i've got an array, which i know that its values would be JPGs from somewhere
i need to go to each value returned to that array and preg_replace some characters
then set the values of the returned values to some other value
here's the code and here's what i've tried
//first piece of code
$data['images'] = array();
foreach ($single['PictureURL'] as $ispec) {
$data['images'][] = $ispec;
$ispec = preg_replace('/\$_[0-9]+.JPG\b/i', '$_10.JPG', $ispec);
$file = 'C:\wamp64\www\mz\images1.txt';
file_put_contents ($file, $ispec, FILE_APPEND);
//images1.txt shows all images returned fine with modified strings
}
//second piece of code
$product->imageUrl = $data['images'][0];
unset($data['images'][0]);
$product->subImageUrl = $data['images'];
$file = 'C:\wamp64\www\mz\images3.txt';
file_put_contents ($file, $data['images'], FILE_APPEND);
//images3.txt shows all the images returned but without being modified?? WHY??!
the first piece of the code is working on all values and replacing is working just fine.
the second piece of the code is my issue, it is returning the values of the old none modified images, which i don't
i need to modify the images before its being written to
'$product->imageUrl & $product->subImageUrl'
The problem is very simple. You're modifying your data after you already
stored it in $data['images']. To solve this, just move this line to
after the preg_replace:
foreach ($single['PictureURL'] as $ispec) {
$ispec = preg_replace('/\$_[0-9]+.JPG\b/i', '$_10.JPG', $ispec);
$data['images'][] = $ispec;
$file = 'C:\wamp64\www\mz\images1.txt';
file_put_contents ($file, $ispec, FILE_APPEND);
}

Getting all from json api array using php

I wanna improve on how to fetch data from an API. In this case I want to fetch every app-id from the Steam API, and list them one per line in a .txt file. Do I need an infinite (or a very high-number) loop (with ++ after every iteration) to fetch everyone? I mean, counting up from id 0 with for example a foreach-loop? I'm thinking it will take ages and sounds very much like bad practice.
How do I get every appid {"appid:" n} from the response of http://api.steampowered.com/ISteamApps/GetAppList/v0001?
<?php
//API-URL
$url = "http://api.steampowered.com/ISteamApps/GetAppList/v0001";
//Fetch content and decode
$game_json = json_decode(curl_get_contents($url), true);
//Define file
$file = 'steam.txt';
//This is where I'm lost. One massive array {"app": []} with lots of {"appid": n}.
//I know how to get one specific targeted line, but how do I get them all?
$line = $game_json['applist']['apps']['app']['appid'][every single line, one at a time]
//Write to file, one id per line.
//Like:
//5
//7
//8
//and so on
file_put_contents($file, $line, FILE_APPEND);
?>
Any pointing just in the right direction will be MUCH appreciated. Thanks!
You don't need to worry about counters with foreach loops, they are designed to go through and work with each item in the object.
$file = "steam.txt";
$game_list = "";
$url = "http://api.steampowered.com/ISteamApps/GetAppList/v0001";
$game_json = file_get_contents($url);
$games = json_decode($game_json);
foreach($games->applist->apps->app as $game) {
// now $game is a single entry, e.g. {"appid":5,"name":"Dedicated server"}
$game_list .= "$game->appid\n";
}
file_put_contents($file, $game_list);
Now you have a text file with 28000 numbers in it. Congratulations?

parsing an array into a lightbox comment

ok guys need your help again,
previously you all introduced me lightbox which after some tweaking has been great. except while using my php code there doesn't seem to be a way to add a caption to the image. now a friend of my introduced me to array using a .txt file. now this is all fine and dandy but i can't seem to get the code that we came up with to read the file correctly. currently it is randomly pulling the letter "a" and the letter "p" and assigning that, which i have no clue where it is getting this.
now here is the code that i've come up with to get the contents of the file.
<?php
// process caption file into named array
//open the file
$myFile = "captions.txt";
$fh = fopen($myFile, 'r') or die("Can't open file");
$theData = explode(fread($fh, filesize($myFile)),"\n");
//close the file
fclose($fh);
//parse line by line until there is no data left.
foreach ($theData as $item => $line) {
$exploded = explode("=", $line);
if (count($exploded) == 2) {
$myFile[$exploded[0]] = $exploded[1];
}
}
?>
and then i'm using the code that auto-populates my image album in turn activating the lighbtox.
<?php
$images = glob('*.{jpg,jpeg,png,gif}', GLOB_BRACE);
foreach ($images as $image) {
if (file_exists("./thumbs/{$image}")){
echo "<img src=\"thumbs/{$image}\" alt=\"{$image}\" />";
}
}
?>
using this code generates no errors but doesn't properly read the captions file.
what i'm wanting to do is have the text file setup with the file name seperated by a = and then the caption.
here is a link to my test page if anyone wants to take a look.
http://outtamymindphoto.myftp.org/images/testalbum/testpage.php
You should start by fixing this line:
$theData = explode(fread($fh, filesize($myFile)),"\n");
According to the PHP Manual , the delimeter is the first parameter.
(array explode ( string $delimiter , string $string [, int $limit ] ))
(Read more about explode - http://php.net/manual/en/function.explode.php)
The right way:
$theData = explode("\n" , fread($fh, filesize($myFile)));
You'll also should try to output the variables in order to locate the problem.
For instance , use var_dump($var) to check $vars value.
Hope I helped you,
comment if you need further help.

Generating Graph with 2 Y Values from Text File

I have remade my original post as it was terribly formatted. Basically I would like some advice / tips on how to generate a line graph with 2 Y Axis (temperature and humidity) to display some information from my text file. It is contained in a textfile called temperaturedata.txt I have included a link to one of my posts from the JpGrapher forum only because it is able to display the code clearly.
I understand that since it is JpGraph problem I shouldn't post here however the community here is a lot more supportive and active. Many thanks for all your help guys in advance!
my code
I don't see any reason why you shouldn't post here about jpgraph. And I don't see why you shouldn't post your sample code and data here, either.
The code you've posted on the other site is broken. Check line #42.
Furthermore, you're passing JpGraph a single row (specifically, the last row) via $keyval. $data is where all your data is stored, though in a wrong format. A very quick fix was:
$keyval = array();
$keyval['time'] = array();
$keyval['count'] = array();
$keyval['temperature'] = array();
$keyval['humidity'] = array();
if ($file) {
while (!feof($file)) {
$line = trim(fgets($file));
if (strlen($line)) {
$fields = explode(":", $line);
$keyval['time'][] = $fields[0];
$keyval['count'][] = $fields[1];
$keyval['temperature'][] = $fields[2];
$keyval['humidity'][] = $fields[3];
}
}
fclose($file);
}
which transposed $data and renamed it $keyval. (Where it used to hold time data in $data[x]['time'], it now holds it in $keyval['time'][x].) And we're passing $keyval['temperature'], which is a simple array of temperature values.

Categories