PhpSpreadsheet 使用大约每个单元格平均 1k 字节的内存(64位PHP上为 1.6k 字节),因此大型工作簿可以快速耗尽可用内存。单元格缓存提供了一种机制,允许 PhpSpreadsheet以更小的内存大小或离线(例如:在磁盘、APCu、memcache 或 redis )维护单元格对象。这使得您可以减少大型工作簿的内存使用,尽管访问单元格数据的代价是速度变慢。

默认情况下,PhpSpreadsheet 将所有单元格对象保留在内存中,但您可以通过提供自己的 PSR-16 实现来指定替代方案。PhpSpreadsheet 键会自动命名空间化并在使用后清理,因此单个缓存实例可以在多个 PhpSpreadsheet 使用场景甚至与其他缓存使用场景之间共享。

要启用单元格缓存,您必须提供自己的缓存实现,如下所示:

  1. $cache = new MyCustomPsr16Implementation();
  2. \PhpOffice\PhpSpreadsheet\Settings::setCache($cache);

每个单独的工作表都有一个独立的缓存,并根据您配置的设置在实例化工作表时自动创建。一旦开始读取工作簿或创建第一个工作表,就无法更改配置设置。

注意TTL(生存时间)

与常见的缓存概念不同,PhpSpreadsheet数据不能从头开始重新生成。如果某些数据被存储,但后来无法检索到,PhpSpreadsheet将抛出异常。

这意味着缓存中存储的数据不得由第三方或通过 TTL 机制删除。

因此,请确保TTL要么被禁用,要么足够长以覆盖整个 PhpSpreadsheet 的使用。

常见的使用案例

PhpSpreadsheet 不随附备选缓存实现。您需要根据您的环境选择最合适的实现。您可以从头开始实现 PSR-16,或者使用现有的库。

其中一个库是 PHP Cache,它提供了各种备选方案。请参阅他们的文档以获取详细信息,但这里是一些建议,应该能让您开始。

APCu

将这些包添加到您的项目中:

composer require cache/simple-cache-bridge cache/apcu-adapter

使用类似于以下内容配置 PhpSpreadsheet:

  1. $pool = new \Cache\Adapter\Apcu\ApcuCachePool();
  2. $simpleCache = new \Cache\Bridge\SimpleCache\SimpleCacheBridge($pool);
  3. \PhpOffice\PhpSpreadsheet\Settings::setCache($simpleCache);

Redis

通过 composer 安装对应的包

composer require cache/simple-cache-bridge cache/redis-adapter

如下所示配置 PhpSpreadsheet

  1. $client = new \Redis();
  2. $client->connect('127.0.0.1', 6379);
  3. $pool = new \Cache\Adapter\Redis\RedisCachePool($client);
  4. $simpleCache = new \Cache\Bridge\SimpleCache\SimpleCacheBridge($pool);
  5. \PhpOffice\PhpSpreadsheet\Settings::setCache($simpleCache);

Memcache

安装

composer require cache/simple-cache-bridge cache/memcache-adapter

配置 PhpSpreadsheet

  1. $client = new \Memcache();
  2. $client->connect('localhost', 11211);
  3. $pool = new \Cache\Adapter\Memcache\MemcacheCachePool($client);
  4. $simpleCache = new \Cache\Bridge\SimpleCache\SimpleCacheBridge($pool);
  5. \PhpOffice\PhpSpreadsheet\Settings::setCache($simpleCache);