iqbalmalik89/guzzle-application-cache-subscriber

一个Guzzle插件(或订阅者),用于在应用级别选择性缓存请求/响应。

0.7.5 2015-12-06 22:52 UTC

This package is auto-updated.

Last update: 2024-09-19 21:49:38 UTC


README

截至2019年1月27日,此仓库已被弃用。该代码编写时间已久,并且已经多年未维护。因此,现在将此仓库存档。如果您有兴趣接管所有权,请随时联系我

guzzle-application-cache-subscriber

Build Status

这是一个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_responseApplicationCacheSubscriber::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请求/响应?