Created
August 25, 2015 03:19
-
-
Save jlem/43f719d668bdf50e4043 to your computer and use it in GitHub Desktop.
Eloquent model caching
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Member extends Model implements CurrentMember | |
{ | |
use ModelCache; | |
public function getLeaguePlayer(SectionInterface $section) | |
{ | |
return $this->cache(function(SectionInterface $section) { | |
return $this->leaguePlayers() | |
->where('section_id', $section->getID()) | |
->first(); | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
trait ModelCache | |
{ | |
protected $dataCache = []; | |
/** | |
* Gets the cached result by key, or executes the closure if cache key does not exist | |
* @param \Closure $closure | |
* @return mixed | |
*/ | |
public function cache(\Closure $closure) | |
{ | |
// This is so we know the name of the function call, and the arguments | |
// We want to md5 serialize these so the cache is unique to the arguments | |
$backtrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT,2)[1]; | |
$key = $backtrace['function']; | |
$args = $backtrace['args']; | |
$key = $key . '.' . md5(serialize($args)); | |
if (!array_key_exists($key, $this->dataCache)) { | |
$this->dataCache[$key] = call_user_func_array($closure, $args); | |
} | |
return $this->dataCache[$key]; | |
} | |
/** | |
* Returns the entire cache | |
* @return array | |
*/ | |
public function getCache() | |
{ | |
return $this->dataCache; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note that this is not a cache as in a time-based cache - it's just a registry cache, so that subsequent calls to
$member->getLeaguePlayer($section)
in the remainder of the request cycle don't result in repeated queries.This is identical in behavior to how Eloquent relations cache their results instead of repeating queries.
It would be great to have something more baked into Eloquent such that you don't have to do gross wrapping in a callback function all the time.
Perhaps an array property like: