Json fetchen met php
Ik ben met een klein script bezig om een Json file te cachen.
Dit doordat je deze dan sneller op kunt laden. Hij zal er een md5 hash maken van de file die gefetched wordt (sorry als ik het fout schrijf :))
Nu moet die nog gereturned worden, waar ik een beetje vast loop.
Iemand tips :)
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
class Json
{
protected $url;
protected $hash;
public function MyJsondata($url)
{
$hash = md5($url);
if (file_exists('cache/' . $hash . '.json')) {
// Return json file
} else {
$json = file_get_contents($url);
file_put_contents('cache/' . $hash . '.json', $json);
}
}
}
class Json
{
protected $url;
protected $hash;
public function MyJsondata($url)
{
$hash = md5($url);
if (file_exists('cache/' . $hash . '.json')) {
// Return json file
} else {
$json = file_get_contents($url);
file_put_contents('cache/' . $hash . '.json', $json);
}
}
}
Verder doe je twee keer dit:
Die zou ik in een variabele stoppen.
Vervolgens, als de cache file bestaat, waarom niet hem dan gewoon includen in die if?
@Devian: Daarom zou ik ook de filemtime() van je cache bestand controleren. Als die bijvoorbeeld ouder is dan een uur ga je alsnog de URL ophalen (maar heb je toch mooi een uur lang met hetzelfde resultaat gedaan!).
En om bij je vraagstelling terecht te komen. Ik neem aan dat er JSON encoded data van die $url komt. Die sla je letterlijk op in die cache file, dus daar zit ook JSON in. Het ligt er nu een beetje aan wat je d'r mee wilt:
- Stuur je 'm door naar een stukje javascript, dan kun je 'm zo letterlijk 1:1 doorsturen. Via readfile(), of door een string te retourneren, en die later naar de output te schrijven.
- Wil je de data in PHP gebruiken, dan kun je met json_decode(file_get_contents("cache/$hash.json")) de JSON als een object gebruiken (of als een array, als je als 2e param voor json_decode() true meegeeft).
Rob Doemaarwat op 28/12/2017 22:08:28:
@Jan: Als je de hash op de file loslaat moet je alsnog elke keer de hele file ophalen om te kijken of de hash nog wel gelijk is. Dan kun je net zo goed gelijk het resultaat doorsturen. Hoef je niet te cachen.
"De hele file" valt erg mee hoor. Ik heb een caching systeem dat op die manier werkt, en dat gaat razendsnel. Wat bedoel je met "het resultaat"?
Beter nog: als je de $hash berekent op basis van de content, hoe kom je dan in eerst instantie bij het juiste cache bestand terecht? De uitvraag gaat op basis van URL. Op basis daarvan moet je een unieke cache naam kunnen reconstrueren om de data op te halen. Dan kun je daarna nog wel een hash van de data berekenen, maar daar heb je dan niet zo heel veel meer aan. Tenzij je deze wilt vergelijken met de hash van de live data (die je dan in "het resultaat" terug krijgt), maar dan ga je voorbij aan het doel van je cache (juist niet elke keer die live data ophalen).
Maar misschien begrijp ik het wel verkeerd, dus kun je evt. kort uitleggen hoe je cache systeem werkt (met bovenstaande situatie: dus je hebt een URL, en wilt het resultaat van die URL cachen)?
@ Rob: het lijkt me offtopic om hier mijn cachesysteem te gaan uitleggen. Laten we even de reacties van de topicstarter afwachten ;-)
https://github.com/doctrine/cache ), omdat je daar heel eenvoudig van backend kunt wisselen (ontwikkelomgeving vs productie, maar ook opschalen naar bijv een memcache oid). Daar zou je zoiets doen:
Vrij simpel, en geen gedoe met zelf een filename verzinnen (Doctrine maakt overigens ook een hash van het $id in het geval van een FileSystem cache).
Nou ja, het is altijd leuk om van een ander te leren. Ook voor de TS. Zelf gebruik ik de Doctrine Cache ( Code (php)
1
2
3
4
5
6
2
3
4
5
6
$data = $cache->fetch($id = 'json-data-' . $url); //boeit dus niet dat er "rare" tekens in het $id zitten
if($data === false){ //cache niet gevonden of verlopen
$data = file_get_contents($url)
$cache->save($id,$data,3600); //data in cache opslaan voor een uur
}
//doe ding met $data
if($data === false){ //cache niet gevonden of verlopen
$data = file_get_contents($url)
$cache->save($id,$data,3600); //data in cache opslaan voor een uur
}
//doe ding met $data
Vrij simpel, en geen gedoe met zelf een filename verzinnen (Doctrine maakt overigens ook een hash van het $id in het geval van een FileSystem cache).
Rob Doemaarwat op 28/12/2017 22:08:28:
@Devian: Daarom zou ik ook de filemtime() van je cache bestand controleren. Als die bijvoorbeeld ouder is dan een uur ga je alsnog de URL ophalen (maar heb je toch mooi een uur lang met hetzelfde resultaat gedaan!).
En om bij je vraagstelling terecht te komen. Ik neem aan dat er JSON encoded data van die $url komt. Die sla je letterlijk op in die cache file, dus daar zit ook JSON in. Het ligt er nu een beetje aan wat je d'r mee wilt:
- Stuur je 'm door naar een stukje javascript, dan kun je 'm zo letterlijk 1:1 doorsturen. Via readfile(), of door een string te retourneren, en die later naar de output te schrijven.
- Wil je de data in PHP gebruiken, dan kun je met json_decode(file_get_contents("cache/$hash.json")) de JSON als een object gebruiken (of als een array, als je als 2e param voor json_decode() true meegeeft).
@Devian: Daarom zou ik ook de filemtime() van je cache bestand controleren. Als die bijvoorbeeld ouder is dan een uur ga je alsnog de URL ophalen (maar heb je toch mooi een uur lang met hetzelfde resultaat gedaan!).
En om bij je vraagstelling terecht te komen. Ik neem aan dat er JSON encoded data van die $url komt. Die sla je letterlijk op in die cache file, dus daar zit ook JSON in. Het ligt er nu een beetje aan wat je d'r mee wilt:
- Stuur je 'm door naar een stukje javascript, dan kun je 'm zo letterlijk 1:1 doorsturen. Via readfile(), of door een string te retourneren, en die later naar de output te schrijven.
- Wil je de data in PHP gebruiken, dan kun je met json_decode(file_get_contents("cache/$hash.json")) de JSON als een object gebruiken (of als een array, als je als 2e param voor json_decode() true meegeeft).
Nouja ik wil deze gewoon kunnen returnen, als dit nodig is. vaak gaat dit om json data van een bepaalde API. Denk hierbij aan een Twitter API. Waar je Json terug krijgt. Later wil je deze weer op kunnen halen
Toevoeging op 28/12/2017 23:03:47:
Rob Doemaarwat op 28/12/2017 22:34:35:
@Jan: De $hash wordt nu gebruikt om een "veilige" bestandsnaam aan te maken (zonder alle "leestekens" van de URL). Die is dus "uniek" voor de URL, ongeacht welke data die URL retourneerde (daar heb je een cache voor, om daar juist een uur niet naar om te hoeven kijken). Ik zie de meerwaarde dan niet om de hash op basis van de content te maken. Je hebt dan nog steeds een cache systeem wat je geforceerd (bijvoorbeeld elk uur) moet verversen, maar dan afhankelijk van de inhoud een andere cache bestandsnaam (wat toch niet uitmaakt, omdat je daar pas achter komt als je de brondata opnieuw opgehaald hebt, en je cache dus toch al ververst hebt - ook als je gewoon steeds dezelfde cache bestandsnaam gebruikt, op basis van de URL).
Beter nog: als je de $hash berekent op basis van de content, hoe kom je dan in eerst instantie bij het juiste cache bestand terecht? De uitvraag gaat op basis van URL. Op basis daarvan moet je een unieke cache naam kunnen reconstrueren om de data op te halen. Dan kun je daarna nog wel een hash van de data berekenen, maar daar heb je dan niet zo heel veel meer aan. Tenzij je deze wilt vergelijken met de hash van de live data (die je dan in "het resultaat" terug krijgt), maar dan ga je voorbij aan het doel van je cache (juist niet elke keer die live data ophalen).
Maar misschien begrijp ik het wel verkeerd, dus kun je evt. kort uitleggen hoe je cache systeem werkt (met bovenstaande situatie: dus je hebt een URL, en wilt het resultaat van die URL cachen)?
Beter nog: als je de $hash berekent op basis van de content, hoe kom je dan in eerst instantie bij het juiste cache bestand terecht? De uitvraag gaat op basis van URL. Op basis daarvan moet je een unieke cache naam kunnen reconstrueren om de data op te halen. Dan kun je daarna nog wel een hash van de data berekenen, maar daar heb je dan niet zo heel veel meer aan. Tenzij je deze wilt vergelijken met de hash van de live data (die je dan in "het resultaat" terug krijgt), maar dan ga je voorbij aan het doel van je cache (juist niet elke keer die live data ophalen).
Maar misschien begrijp ik het wel verkeerd, dus kun je evt. kort uitleggen hoe je cache systeem werkt (met bovenstaande situatie: dus je hebt een URL, en wilt het resultaat van die URL cachen)?
Nouja het plan was om de data eenmalig op te halen (de tijdsduur doet nu nog niet helemaal terzake). De url daar dient een hash gemaakt van te worden en op de server opgeslagen te worden. Als ik een hash maakte van de content mijn fout, haha.
Toevoeging op 28/12/2017 23:06:31:
Jan Koehoorn op 28/12/2017 22:40:06:
@ Rob: het lijkt me offtopic om hier mijn cachesysteem te gaan uitleggen. Laten we even de reacties van de topicstarter afwachten ;-)
Nouja kan altijd tips gebruiken :)
Gewijzigd op 28/12/2017 23:11:11 door Daan s