PHP RFC: Modern Compression
- Version: 1.0
- Date: 2025-02-18
- Author: Jordi Boggiano (j.boggiano@seld.be), Kévin Dunglas (kevin@dunglas.fr)
- Status: Under Discussion
- First Published at: http://wiki.php.net/rfc/modern_compression
Introduction
Integrating zstd (Zstandard) and brotli compression formats into PHP's core would significantly enhance the language's data compression capabilities.
These modern algorithms offer superior compression ratios and speeds compared to gzip. By embedding them directly into PHP, developers would have access to efficient, web-native compression methods without relying on external extensions. Integrating these would also pave the way for tools like Composer and Symfony AssetMapper that cannot reasonably require PECL extensions or external commands to leverage these formats.
Proposal
We propose including the zstd and brotli extensions. The implementation involves incorporating the stable, mature C libraries of zstd and brotli, and exposing their functionalities through new PHP functions. Since these libraries are well-established and their APIs are stable, the maintenance overhead would be minimal.
Benefits:
- Enhanced Performance: Both Zstandard and Brotli offer higher compression ratios and faster decompression times compared to legacy algorithms, leading to reduced storage requirements and faster data transmission.
- Web-Native Formats: As these formats are supported by modern web browsers and servers, their inclusion aligns PHP with current web standards and practices.
- Minimal Maintenance: The libraries are stable, and the PHP extensions are straightforward wrappers around the C APIs, ensuring low maintenance demands.
- Composer Integration: Native support would allow Composer to utilize these algorithms for package compression, resulting in smaller package sizes and quicker installations.
- Assets pre-compression: Modern web servers such as Caddy/FrankenPHP and NGINX (with modules) support serving pre-compressed static files instead of compressing them on the fly, saving CPU-time and decreasing latency. Tools such as Symfony AssetMapper are adding support for assets pre-compression and would benefit from not requiring external PECL extensions or system commands.
Although Zstandard is in most cases more efficient than Brotli, Zstandard is not currently supported by Safari and - at the highest compression level - Brotli produces smaller files than Zstandard. As browsers negotiate which format to use according to their capabilities, we propose adding support for both formats to PHP.
Zstandard
The zstd implementation includes a few global functions as well as namespaced ones
zstd_compress — Zstandard compression zstd_uncompress — Zstandard decompression zstd_compress_dict — Zstandard compression using a digested dictionary zstd_uncompress_dict — Zstandard decompression using a digested dictionary namespace Zstd; function compress( $data [, $level = \ZSTD_COMPRESS_LEVEL_DEFAULT ] ) function uncompress( $data ) function compress_dict ( $data, $dict ) function uncompress_dict ( $data, $dict )
There is also support for output compression and a stream wrapper (compress.zstd
scheme).
Brotli
The brotli implementation includes a few global functions as well as namespaced ones
brotli_compress — Compress a string brotli_uncompress — Uncompress a compressed string brotli_compress_init — Initialize an incremental compress context brotli_compress_add — Incrementally compress data brotli_uncompress_init — Initialize an incremental uncompress context brotli_uncompress_add — Incrementally uncompress data namespace Brotli; function compress( $data [, $quality = \BROTLI_COMPRESS_LEVEL_DEFAULT, $mode = \BROTLI_GENERIC ] ) function uncompress( $data [, $length = 0 ] ) function compress_init( [ $quality = \BROTLI_COMPRESS_LEVEL_DEFAULT, $mode = \BROTLI_GENERIC ] ) function compress_add( resource $context, string $data [, $mode = \BROTLI_FLUSH] ) function uncompress_init() function uncompress_add( resource $context, string $data [, $mode = \BROTLI_FLUSH] )
There is also support for output compression and a stream wrapper (compress.brotli
scheme).
Backward Incompatible Changes
None beyond new global function names being taken.
Proposed PHP Version(s)
Next PHP minor release (8.5)
RFC Impact
To SAPIs
None.
To Existing Extensions
None.
To Opcache
None.
New Constants
Constant | Description |
---|---|
ZSTD_COMPRESS_LEVEL_MIN | Minimal compress level value |
ZSTD_COMPRESS_LEVEL_MAX | Maximal compress level value |
ZSTD_COMPRESS_LEVEL_DEFAULT | Default compress level value |
LIBZSTD_VERSION_NUMBER | libzstd version number |
LIBZSTD_VERSION_STRING | libzstd version string |
BROTLI_COMPRESS_LEVEL_MIN | Minimal compress level value |
BROTLI_COMPRESS_LEVEL_MAX | Maximal compress level value |
BROTLI_COMPRESS_LEVEL_DEFAULT | Default compress level value |
BROTLI_GENERIC | Default compression mode |
BROTLI_TEXT | UTF-8 format text input compression mode |
BROTLI_FONT | WOFF 2.0 font compression mode |
BROTLI_FLUSH | For incremental compression, produce output for all processed input |
BROTLI_PROCESS | For incremental compression, process input, encoder may postpone producing output, until it has processed enough input |
BROTLI_FINISH | For incremental compression, finalize the stream |
php.ini Defaults
Both extensions provide basic ini settings for output compression that are disabled by default.
zstd.output_compression default 0 zstd.output_compression_level default -1 zstd.output_compression_dict default "" brotli.output_compression default 0 brotli.output_compression_level default -1
Open Issues
None.
Unaffected PHP Functionality
No existing functionality should be affected.
Future Scope
None.
Proposed Voting Choices
Yes or no vote. 2/3 required to pass.
Patches and Tests
Inclusion in core will be done by Kévin Dunglas (unless someone else volunteers) once the RFC approved.
Implementation
After the project is implemented, this section should contain
- the version(s) it was merged into
- a link to the git commit(s)
- a link to the PHP manual entry for the feature
- a link to the language specification section (if any)
References
zstd/brotli extension maintainer approval https://github.com/kjdev/php-ext-zstd/issues/72