Skip to content

Instantly share code, notes, and snippets.

@rlerdorf
Last active March 22, 2021 15:18
Show Gist options
  • Save rlerdorf/75524a93c4fa3f8bb52efd7439881886 to your computer and use it in GitHub Desktop.
Save rlerdorf/75524a93c4fa3f8bb52efd7439881886 to your computer and use it in GitHub Desktop.
<?php
class Endpoint {
function __construct(public string $url, ?callable $dfunc=null, array $opts = []) {
$this->context = stream_context_create($opts);
$this->dfunc = $dfunc ? $dfunc : fn($x)=>$x;
}
}
class Api {
static public ?weakMap $cache = null;
static public function fetch(Endpoint $ep): string|object {
if(!self::$cache) self::$cache = new weakMap;
return self::$cache[$ep] ??= $ep->dfunc->call($ep, file_get_contents($ep->url, context:$ep->context));
}
}
$xkcd = new Endpoint("http://xkcd.com/info.0.json", fn($x)=>json_decode($x, associative:false));
$joke = new Endpoint("https://icanhazdadjoke.com/", opts:['http'=>['header'=>"Accept: text/plain"]]);
echo '<img src="'.Api::fetch($xkcd)->img.'" alt="'.Api::fetch($xkcd)->alt.'">'."\n";
echo Api::fetch($joke) . "\n";
echo Api::$cache->count() . "\n"; // 3
unset($xkcd);
echo Api::$cache->count() . "\n"; // 2
echo Api::fetch($joke) . "\n"; // Same bad joke
$joke = new Endpoint("https://icanhazdadjoke.com/", opts:['http'=>['header'=>"Accept: text/plain\r\n"]]);
echo Api::fetch($joke) . "\n"; // New bad joke
echo Api::$cache->count() . "\n"; // 3?
gc_collect_cycles(); // Force gc
echo Api::$cache->count() . "\n"; // 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment