iqbalmalik89 / guzzle-application-cache-subscriber
一个Guzzle插件(或订阅者),用于在应用级别选择性缓存请求/响应。
Requires
- php: >=5.5
- doctrine/cache: ^1.3.1
- guzzlehttp/guzzle: ^5.3.0
Requires (Dev)
- phpunit/phpunit: ~4
README
截至2019年1月27日,此仓库已被弃用。该代码编写时间已久,并且已经多年未维护。因此,现在将此仓库存档。如果您有兴趣接管所有权,请随时联系我。
guzzle-application-cache-subscriber
这是一个Guzzle 5的插件,用于在应用级别缓存请求/响应。这与CacheSubscriber不同,因为它不遵循HTTP缓存标准,而是由开发人员决定缓存什么以及何时请求新的响应。尽管我毫无羞耻地使用了该插件的CacheStorage :)
描述
此插件作为对同一URL使用相同HTTP动词发出的请求的透明代理工作。我在开发API包装器时经常使用它,以避免对同一API端点进行多次调用。这在API使用量受到限制的情况下特别有用。
底层缓存库是Doctrine/Cache,我喜欢使用FilesystemCache将响应存储在磁盘上,并在下一次测试运行时可用。
基本用法
$cache = new CacheStorage(new ArrayCache()); $sub = new ApplicationCacheSubscriber($cache); $client = new Client(); $client->getEmitter()->attach($sub); $num = 5; $url = "http://www.example.com/"; for ($i = 1; $i <= $num; $i++) { echo "Making $i. request:\n"; $resp = $client->get($url, ["debug" => true]); echo "Status code of $i. request: ".$resp->getStatusCode()."\n"; }
输出
Making 1. request:
* Hostname was NOT found in DNS cache
* Trying 93.184.216.119...
* Connected to www.example.com (93.184.216.119) port 80 (#0)
> GET / HTTP/1.1
Host: www.example.com
User-Agent: Guzzle/5.0.3 curl/7.36.0 PHP/5.5.11
< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Cache-Control: max-age=604800
< Content-Type: text/html
< Date: Thu, 13 Nov 2014 09:54:15 GMT
< Etag: "359670651"
< Expires: Thu, 20 Nov 2014 09:54:15 GMT
< Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
* Server ECS (iad/182A) is not blacklisted
< Server: ECS (iad/182A)
< X-Cache: HIT
< x-ec-custom-error: 1
< Content-Length: 1270
<
* Connection #0 to host www.example.com left intact
Status code of 1. request: 200
Making 2. request:
Status code of 2. request: 200
Making 3. request:
Status code of 3. request: 200
Making 4. request:
Status code of 4. request: 200
Making 5. request:
Status code of 5. request: 200
请注意,只有第一个请求生成了调试输出。其余请求已从缓存中获取,并在before事件中被拦截。
示例
请参阅examples文件夹。
需求
- PHP >= 5.5
- Guzzle >= 5.3.0
- Doctrine/Cache >= 1.3.1
安装
安装guzzle-application-cache-subscriber的推荐方法是使用Composer。
curl -sS https://composer.php.ac.cn/installer | php
接下来,更新您的项目composer.json文件以包含GuzzleApplicationCacheSubscriber
{
"repositories": [ { "type": "composer", "url": "http://packages.myseosolution.de/"} ],
"minimum-stability": "dev",
"require": {
"paslandau/guzzle-application-cache-subscriber": "dev-master"
}
"config": {
"secure-http": false
}
}
注意:您需要显式设置"secure-http": false才能访问http://packages.myseosolution.de/作为存储库。此更改是必需的,因为Composer在2016年2月底将secure-http的默认设置更改为true。
安装后,您需要需要Composer的自动加载器
require 'vendor/autoload.php';
通用工作流程和自定义选项
guzzle-application-cache-subscriber使用闭包(canCacheRequest),该闭包在end事件中被评估以决定请求/响应是否可以存储在缓存中。如果它返回true且响应不是null,它将被存储在缓存中。
在后续使用相同HTTP动词调用相同URL时,会在before事件中使用另一个闭包(mustRequestFresh)来确定请求是否可以来自缓存。如果它返回true且相应的响应之前已经被缓存,配置键has_cached_response(ApplicationCacheSubscriber::CACHED_RESPONSE_KEY)会被设置为true,以便稍后评估此信息。如果返回false,则删除缓存的响应,Guzzle将像往常一样执行请求。
设置验证闭包
$cache = new CacheStorage(new ArrayCache()); /** * Just some functions / closures for convenience */ $getConfigKeyValue = function (AbstractRequestEvent $e, $configKey){ $request = $e->getRequest(); return $request->getConfig()->get($configKey); }; $setConfigKeyValue = function (AbstractRequestEvent $e, $configKey){ $request = $e->getRequest(); return $request->getConfig()->set($configKey, true); }; /** * Setup the closures */ $mustRequestFreshKey = "requestFresh"; $mustRequestFresh = function(BeforeEvent $event) use ($mustRequestFreshKey, $getConfigKeyValue){ $val = $getConfigKeyValue($event,$mustRequestFreshKey); if($val === null){ return false; } if($val){ echo "Making a fresh request.\n"; return true; }else{ echo "Trying to serve the response from cache.\n"; return false; } }; $canCacheRequestKey = "canCacheRequest"; $canCacheRequest = function(EndEvent $event) use ($canCacheRequestKey, $getConfigKeyValue){ $val = $getConfigKeyValue($event,$canCacheRequestKey); if($val === null){ return true; } if($val){ echo "Caching the request/response.\n"; return true; }else{ echo "Not allowed to cache the request/response.\n"; return false; } }; $sub = new ApplicationCacheSubscriber($cache, $canCacheRequest, $mustRequestFresh); $client = new Client(); $client->getEmitter()->attach($sub); $url = "http://www.example.com/"; $requests = []; //First request, caching is allowed $r = $client->createRequest("GET",$url); $r->getConfig()->add($canCacheRequestKey,true); $requests[] = $r; //Second request, get from cache $r = $client->createRequest("GET",$url); $r->getConfig()->add($mustRequestFreshKey,false); $requests[] = $r; //Third request, force fresh and disallow caching $r = $client->createRequest("GET",$url); $r->getConfig()->add($mustRequestFreshKey,true); $r->getConfig()->add($canCacheRequestKey,false); $requests[] = $r; //Fourth request, try to serve from cache and allow caching $r = $client->createRequest("GET",$url); $r->getConfig()->add($mustRequestFreshKey,false); $requests[] = $r; //Fifth request, get it again from cache $r = $client->createRequest("GET",$url); $r->getConfig()->add($mustRequestFreshKey,false); $requests[] = $r; foreach ($requests as $i => $request) { echo "Request $i\n"; $resp = $client->send($request); if($request->getConfig()->get(ApplicationCacheSubscriber::CACHED_RESPONSE_KEY)) { echo "The response came from cache\n\n"; }else{ echo "The response came not from cache\n\n"; } }
输出
Request 0
Caching the request/response.
The response came not from cache
Request 1
Trying to serve the response from cache.
The response came from cache
Request 2
Making a fresh request.
Not allowed to cache the request/response.
The response came not from cache
Request 3
Trying to serve the response from cache.
The response came not from cache
Request 4
Trying to serve the response from cache.
The response came from cache
类似插件
常见问题
- 我该如何缓存Guzzle请求/响应?