initial: bootstrap from BukidBountyApp base
This commit is contained in:
127
app/Http/Controllers/Helpers/CacheHelper.php
Normal file
127
app/Http/Controllers/Helpers/CacheHelper.php
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Helpers;
|
||||
|
||||
use Hyperf\Coroutine\Coroutine;
|
||||
use Hypervel\Support\Facades\Cache;
|
||||
use Hyperf\Database\Model\Builder as ModelBuilder;
|
||||
use Hyperf\Database\Query\Builder as QueryBuilder;
|
||||
use Hypervel\Database\Eloquent\Model;
|
||||
|
||||
class CacheHelper
|
||||
{
|
||||
/**
|
||||
* Get data from cache.
|
||||
*
|
||||
* @param mixed $query Can be SQL string or Builder object
|
||||
* @param mixed $params Parameters to hash (array, object, or model)
|
||||
* @return mixed|null
|
||||
*/
|
||||
public static function get_cache($query, $params = [])
|
||||
{
|
||||
try {
|
||||
$key = self::generateKey($query, $params);
|
||||
return Cache::get($key);
|
||||
} catch (\Throwable $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data in cache using a background coroutine (fire-and-forget).
|
||||
*
|
||||
* @param mixed $query Can be SQL string or Builder object
|
||||
* @param mixed $params Parameters to hash
|
||||
* @param mixed $data Data to cache
|
||||
* @param int $ttl Time to live in seconds (default: 1 day)
|
||||
*/
|
||||
public static function set_cache($query, $data, $params = [], int $ttl = 86400)
|
||||
{
|
||||
$key = self::generateKey($query, $params);
|
||||
|
||||
// Fire-and-forget coroutine: we don't wait for completion
|
||||
Coroutine::create(function () use ($key, $data, $ttl) {
|
||||
try {
|
||||
Cache::put($key, $data, $ttl);
|
||||
} catch (\Throwable $e) {
|
||||
// Silently fail as cache operations are non-critical
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Erase a specific cache entry.
|
||||
*
|
||||
* @param mixed $query Can be SQL string or Builder object
|
||||
* @param mixed $params Parameters to hash
|
||||
*/
|
||||
public static function erase_cache($query, $params = [])
|
||||
{
|
||||
try {
|
||||
$key = self::generateKey($query, $params);
|
||||
Cache::forget($key);
|
||||
} catch (\Throwable $e) {
|
||||
// Silently fail
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the cache key using the specific format:
|
||||
* querycache:[queryhash]++++[parameterhash]
|
||||
*/
|
||||
public static function generateKey($query, $params): string
|
||||
{
|
||||
$sql = '';
|
||||
$parameterData = $params;
|
||||
|
||||
// Automatically handle Builder objects
|
||||
if ($query instanceof ModelBuilder || $query instanceof QueryBuilder) {
|
||||
$sql = $query->toSql();
|
||||
// If explicit params were not provided or empty, use the builder's bindings
|
||||
if (empty($params)) {
|
||||
$parameterData = $query->getBindings();
|
||||
}
|
||||
} else {
|
||||
$sql = (string) $query;
|
||||
}
|
||||
|
||||
$queryHash = md5($sql);
|
||||
$paramHash = md5(self::serializeParams($parameterData));
|
||||
|
||||
return "querycache:{$queryHash}++++{$paramHash}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Deep serialization of parameters for hashing.
|
||||
* Supports arrays, objects, and models.
|
||||
*/
|
||||
private static function serializeParams($params): string
|
||||
{
|
||||
if (is_array($params)) {
|
||||
$processed = [];
|
||||
foreach ($params as $key => $value) {
|
||||
$processed[$key] = self::serializeParams($value);
|
||||
}
|
||||
// Sort keys to ensure consistent hashing for the same associative array
|
||||
ksort($processed);
|
||||
return json_encode($processed);
|
||||
}
|
||||
|
||||
if (is_object($params)) {
|
||||
// Handle models specifically
|
||||
if ($params instanceof Model) {
|
||||
return get_class($params) . ':' . ($params->hashkey ?? $params->id ?? 'new');
|
||||
}
|
||||
|
||||
if (method_exists($params, 'toArray')) {
|
||||
return json_encode($params->toArray());
|
||||
}
|
||||
|
||||
return get_class($params) . ':' . spl_object_hash($params);
|
||||
}
|
||||
|
||||
return (string) $params;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user