承接 laragear/cache-query 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

laragear/cache-query

Composer 安装命令:

composer require laragear/cache-query

包简介

Remember your query results using only one method. Yes, only one.

README 文档

README

Latest Version on Packagist Latest stable test run Codecov coverage Maintainability Sonarcloud Status Laravel Octane Compatibility

Remember your query results using only one method. Yes, only one.

Articles::latest('published_at')->cache()->take(10)->get();

Become a sponsor

Your support allows me to keep this package free, up-to-date and maintainable. Alternatively, you can spread the word in social media

Requirements

  • PHP 8.3
  • Laravel 12 or later

Installation

You can install the package via composer:

composer require laragear/cache-query

How does it work?

This library wraps the database connection into a proxy object. It proxies all method calls to it except select() and selectOne().

Once a SELECT statement is executed through the aforementioned methods, it will check if the results are in the cache before executing the query. On cache hit, it will return the cached results, otherwise it will continue execution, save the results using the cache configuration, and return them.

Usage

Use the cache() method to remember the results of a query for a default of 60 seconds.

use Illuminate\Support\Facades\DB;
use App\Models\Article;

DB::table('articles')->latest('published_at')->take(10)->cache()->get();

Article::latest('published_at')->take(10)->cache()->get();

The next time you call the same query, the result will be retrieved from the cache instead of running the SELECT SQL statement in the database, even if the results are empty, null or false. You may also desire to not cache empty results.

It's eager load aware. This means that it will cache an eager loaded relation automatically (but you may also disable this).

use App\Models\User;

$usersWithPosts = User::where('is_author')->with('posts')->cache()->paginate();

Time-to-live

By default, results of a query are cached by 60 seconds, which is mostly enough when your application is getting hammered with the same query results.

You're free to use any number of seconds from now, or a DateTimeInterface like Carbon.

use Illuminate\Support\Facades\DB;
use App\Models\Article;

DB::table('articles')->latest('published_at')->take(10)->cache(120)->get();

Article::latest('published_at')->take(10)->cache(now()->addHour())->get();

You can also use null, ever or forever to set the query results forever.

use App\Models\Article;

Article::latest('published_at')->take(10)->cache('forever')->get();

Stale while revalidate

You may take advantage of Laravel Flexible Caching mechanism by issuing an array of values as first argument. (...) The first value in the array represents the number of seconds the cache is considered fresh, while the second value defines how long it can be served as stale data before recalculation is necessary.

use App\Models\Article;

Article::latest('published_at')->take(200)->cache([300, 60])->get();

The above example will refresh the query results if there is 60 seconds lefts until the data dies.

Advanced caching

You may use a callback to further change the query caching. The callback receives a Laragear\CacheQuery\Cache instance that allows to change how to cache the data.

use Laragear\CacheQuery\Cache;
use App\Models\User;

User::query()->where('cool', true)->cache(function (Cache $cache) {
    $cache->ttl([300, 60])->regenWhen(true);
})->get();

Alternatively, you can create and configure an instance outside the query, and then pass it as an argument. You can do this with the for() method or flexible() method

use Laragear\CacheQuery\Cache;
use App\Models\User;
use App\Models\Post;

$cacheUser = Cache::for(30)->regenWhen(true);

User::query()->where('cool', true)->cache($cacheUser)->get();

$cachePost = Cache::flexible(300, 50)->as('frontend-posts');

Post::query()->latest()->limit(10)->cache($cachePost)->get();

Conditional Regeneration

You may want to forcefully regenerate the queried cache when the underlying data changes, or because other reason. For that, use the regenWhen() and a condition that evaluates to true, and regenUnless() for a condition that evaluates to false. If you pass a callback, it will be executed before retrieving the results from the cache.

use Laragear\CacheQuery\Cache;

Cache::for([300, 50])->regenWhen(true);

Cache::for(50)->regenUnless(fn() => false);

Cache except empty results

By default, the cache() method will cache any result from the query, empty or not. You can disable this with the exceptEmpty() method, which will only cache non-empty results.

use Laragear\CacheQuery\Cache;

Cache::for(300)->exceptEmpty();

Eager loaded queries

You may disable caching Eager Loaded Queries with the exceptNested() method. With that, only the query that invokes the cache() method will be cached.

use Laragear\CacheQuery\Cache;

Cache::for(300)->exceptNested();

For example, in this query, only the User query will be cached, while the posts won't.

use App\Models\User;
use App\Models\Post;
use Laragear\CacheQuery\Cache;

User::where('cool', true)
    ->cache(fn(Cache $cache) => $cache->exceptNested())
    ->with('posts', fn ($query) => $query->where('published_at', '<', now())
    ->get();

Custom Store

By default, the cached results use your application default cache store. You may change the default store using the store() method.

use Laragear\CacheQuery\Cache;

Cache::for(300)->store('redis');

Forgetting cached results

If you plan to remove a query from the cache, you will need to identify the query with the as() method and an identifiable key name.

use Laragear\CacheQuery\Cache;

Cache::for(300)->as('latest_articles');

Once done, you can later delete the query results using the CacheQuery facade.

use Laragear\CacheQuery\Facades\CacheQuery;

CacheQuery::forget('latest_articles');

Or you may use the cache-query:forget command with the name of the key from the CLI.

php artisan cache-query:forget latest_articles

# Successfully removed [latest_articles] from the [file] cache store. 

You may use the same key for multiple queries to group them into a single list you can later delete in one go.

use App\Models\Article;
use App\Models\Post;
use Laragear\CacheQuery\Facades\CacheQuery;
use Laragear\CacheQuery\Cache;

$cache = Cache::for(300)->as('latest_articles');

Article::latest('published_at')->with('drafts')->take(5)->cache($cache)->get();
Post::latest('posted_at')->take(10)->cache($cache)->get();

CacheQuery::forget('latest_articles');

Tip

This functionality does not use cache tags, so it will work on any cache store you set, even the file driver!

Custom Hash Function

You can set your own function to hash the incoming SQL Query. Just register your function in the $queryHasher static property of the CacheAwareConnectionProxy class. The function should receive the database Connection, the query string, and the SQL bindings in form of an array.

This can be done in the register() method of your AppServiceProvider.

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Laragear\CacheQuery\Proxy;

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        Proxy::$queryHasher = function ($connection, $query, $bindings) {
            // ...
        }
    }
}

Configuration

To further configure the package, publish the configuration file:

php artisan vendor:publish --provider="Laragear\CacheQuery\CacheQueryServiceProvider" --tag="config"

You will receive the config/cache-query.php config file with the following contents:

<?php

return [
    'store' => env('CACHE_QUERY_STORE'),
    'prefix' => 'cache-query',
    'commutative' => false
];

Cache Store

return  [
    'store' => env('CACHE_QUERY_STORE'),
];

The default cache store to put the queried results. When not issued in the query, this setting will be used. If it's empty or null, the default cache store of your application will be used.

You can easily change this setting using your .env file:

CACHE_QUERY_STORE=redis

Prefix

return  [
    'prefix' => 'cache-query',
];

When storing query hashes and query named keys, this prefix will be appended, which will avoid conflicts with other cached keys. You can change in case it collides with other keys.

Commutative operations

return [
    'commutative' => false
]

When hashing queries, the default hasher function will create different hashes even on visually different queries.

User::query()->cache()->whereName('Joe')->whereAge(20)->first();
// Cache key: "cache-query|/XreUO1yaZ4BzH2W6LtBSA"

User::query()->cache()->whereAge(20)->whereName('Joe')->first();
// Cache key: "cache-query|muDJevbVppCsTFcdeZBxsA"

By setting commutative to true, the function will always sort the query elements so similar queries share the same hash.

User::query()->cache()->whereName('Joe')->whereAge(20)->first();
// Cache key: "cache-query|muDJevbVppCsTFcdeZBxsA"

User::query()->cache()->whereAge(20)->whereName('Joe')->first();
// Cache key: "cache-query|muDJevbVppCsTFcdeZBxsA"

Tip

This can be also overridden using your own custom hash function.

PhpStorm stubs

For users of PhpStorm, there is a stub file to aid in macro autocompletion for this package. You can publish them using the phpstorm tag:

php artisan vendor:publish --provider="Laragear\CacheQuery\CacheQueryServiceProvider" --tag="phpstorm"

The file gets published into the .stubs folder of your project. You should point your PhpStorm to these stubs.

Laravel Octane compatibility

  • There are no singletons using a stale application instance.
  • There are no singletons using a stale config instance.
  • There are no singletons using a stale request instance.
  • There are no static properties written during a request.

There should be no problems using this package with Laravel Octane.

Upgrading

Security

If you discover any security related issues, please email darkghosthunter@gmail.com instead of using the issue tracker.

License

This specific package version is licensed under the terms of the MIT License, at time of publishing.

Laravel is a Trademark of Taylor Otwell. Copyright © 2011-2024 Laravel LLC.

laragear/cache-query 适用场景与选型建议

laragear/cache-query 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 146.78k 次下载、GitHub Stars 达 272, 最近一次更新时间为 2022 年 02 月 16 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 laragear/cache-query 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 laragear/cache-query 我们能提供哪些服务?
定制开发 / 二次开发

基于 laragear/cache-query 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 146.78k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 272
  • 点击次数: 35
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 272
  • Watchers: 2
  • Forks: 16
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2022-02-16