Skip to content

Commit

Permalink
Refactor CachedObjectStorage to PSR-16
Browse files Browse the repository at this point in the history
This drop a lot of non-core features code and delegate their maintainance
to third parties. Also it open the door to any missing implementation
out of the box, such as Redis for the moment.

Finally this consistently enforce a constraint where there can be one and
only one active cell at any point in time in code. This used to be true for
non-default implementation of cache, but it was not true for default
implementation where all cells were kept in-memory and thus were never
detached from their worksheet and thus were all kept functionnal at any
point in time.

This inconsistency of behavior between in-memory and off-memory could
lead to bugs when changing cache system if the end-user code was badly
written. Now end-user will never be able to write buggy code in the first
place, avoiding future headache when introducing caching.

Closes #3
  • Loading branch information
PowerKiKi committed Apr 14, 2017
1 parent 2d630fb commit fd9c925
Show file tree
Hide file tree
Showing 39 changed files with 1,077 additions and 3,275 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"ext-iconv": "*",
"ext-xml": "*",
"ext-xmlwriter": "*",
"ext-zip": "*"
"ext-zip": "*",
"psr/simple-cache": "^1.0"
},
"require-dev": {
"mpdf/mpdf": "^6.1",
Expand Down
53 changes: 51 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

108 changes: 108 additions & 0 deletions docs/topics/memory_saving.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Memory saving

PhpSpreadsheet uses an average of about 1k per cell in your worksheets, so
large workbooks can quickly use up available memory. Cell caching
provides a mechanism that allows PhpSpreadsheet to maintain the cell
objects in a smaller size of memory, or off-memory (eg: on disk, in APCu,
memcache or redis). This allows you to reduce the memory usage for large
workbooks, although at a cost of speed to access cell data.

By default, PhpSpreadsheet holds all cell objects in memory, but
you can specify alternatives by providing your own
[PSR-16](http://www.php-fig.org/psr/psr-16/) implementation. PhpSpreadsheet keys
are automatically namespaced, and cleaned up after use, so a single cache
instance may be shared across several usage of PhpSpreadsheet or even with other
cache usages.

To enable cell caching, you must provide your own implementation of cache like so:

``` php
$cache = new MyCustomPsr16Implementation();

\PhpOffice\PhpSpreadsheet\Settings::setCache($cache);
```

A separate cache is maintained for each individual worksheet, and is
automatically created when the worksheet is instantiated based on the
settings that you have configured. You cannot change
the configuration settings once you have started to read a workbook, or
have created your first worksheet.

## Beware of TTL

As opposed to common cache concept, PhpSpreadsheet data cannot be re-generated
from scratch. If some data is stored and later is not retrievable,
PhpSpreadsheet will throw an exception.

That means that the data stored in cache **must not be deleted** by a
third-party or via TTL mechanism.

So be sure that TTL is either de-activated or long enough to cover the entire
usage of PhpSpreadsheet.

## Common use cases

PhpSpreadsheet does not ship with alternative cache implementation. It is up to
you to select the most appropriate implementation for your environnement. You
can either implement [PSR-16](http://www.php-fig.org/psr/psr-16/) from scratch,
or use [pre-existing libraries](https://packagist.org/search/?q=psr-16).

One such library is [PHP Cache](http://www.php-cache.com/) which
provides a wide range of alternatives. Refers to their documentation for
details, but here are a few suggestions that should get you started.


### APCu

Require the packages into your project:

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

Configure PhpSpreadsheet with something like:

```php
$pool = new \Cache\Adapter\Apcu\ApcuCachePool();
$simpleCache = new \Cache\Bridge\SimpleCache\SimpleCacheBridge($pool);

\PhpOffice\PhpSpreadsheet\Settings::setCache($simpleCache);
```

### Redis

Require the packages into your project:

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

Configure PhpSpreadsheet with something like:

```php
$client = new \Redis();
$client->connect('127.0.0.1', 6379);
$pool = new \Cache\Adapter\Redis\RedisCachePool($client);
$simpleCache = new \Cache\Bridge\SimpleCache\SimpleCacheBridge($pool);

\PhpOffice\PhpSpreadsheet\Settings::setCache($simpleCache);
```

### Memcache

Require the packages into your project:

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

Configure PhpSpreadsheet with something like:

```php
$client = new \Memcache();
$client->connect('localhost', 11211);
$pool = new \Cache\Adapter\Memcache\MemcacheCachePool($client);
$simpleCache = new \Cache\Bridge\SimpleCache\SimpleCacheBridge($pool);

\PhpOffice\PhpSpreadsheet\Settings::setCache($simpleCache);
```
29 changes: 28 additions & 1 deletion docs/topics/migration-from-PHPExcel.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,38 @@ $rendererName = \PhpOffice\PhpSpreadsheet\Settings::PDF_RENDERER_MPDF;
## PclZip and ZipArchive

Support for PclZip were dropped in favor of the more complete and modern
PHP extension ZipArchive. So the following were removed:
[PHP extension ZipArchive](http://php.net/manual/en/book.zip.php).
So the following were removed:

- `PclZip`
- `PHPExcel_Settings::setZipClass()`
- `PHPExcel_Settings::getZipClass()`
- `PHPExcel_Shared_ZipArchive`
- `PHPExcel_Shared_ZipStreamWrapper`


## Cell caching

Cell caching was heavily refactored to leverage
[PSR-16](http://www.php-fig.org/psr/psr-16/). That means most classes
related to that feature were removed:

- `PHPExcel_CachedObjectStorage_APC`
- `PHPExcel_CachedObjectStorage_DiscISAM`
- `PHPExcel_CachedObjectStorage_ICache`
- `PHPExcel_CachedObjectStorage_Igbinary`
- `PHPExcel_CachedObjectStorage_Memcache`
- `PHPExcel_CachedObjectStorage_Memory`
- `PHPExcel_CachedObjectStorage_MemoryGZip`
- `PHPExcel_CachedObjectStorage_MemorySerialized`
- `PHPExcel_CachedObjectStorage_PHPTemp`
- `PHPExcel_CachedObjectStorage_SQLite`
- `PHPExcel_CachedObjectStorage_SQLite3`
- `PHPExcel_CachedObjectStorage_Wincache`

In addition to that, `\PhpOffice\PhpSpreadsheet::getCellCollection()` was renamed
to `\PhpOffice\PhpSpreadsheet::getCoordinates()` and
`\PhpOffice\PhpSpreadsheet::getCellCacheController()` to
`\PhpOffice\PhpSpreadsheet::getCellCollection()` for clarity.

Refer to [the new documentation](./memory_saving.md) to see how to migrate.
Loading

0 comments on commit fd9c925

Please sign in to comment.