PHP 8.1: New fsync
and fdatasync
functions
PHP 8.1 adds two new functions to the group of file system functions.
PHP already has fflush
function that flushes the potentially buffered data to the underlying operating system. fflush
function is often used after write operations (fwrite
calls), to make sure the PHP's internal buffers are flushed to the operating system.
The new fsync
and fdatasync
functions are similar to fflush
, but they also request the operating system to flush the operating systems write buffers to the actual storage media.
fsync
and fdatasync
functions can be useful in applications that consistent and persistent storage is important. These functions only return true
if the operating system indicates the data has been flushed to the storage media.
fsync
: Synchronizes changes to the file (including meta-data)fdatasync
: Synchronizes data (but not meta-data) to the file.
fsync
function
The fsync
function synchronizes changes to the file, including its meta-data. This is similar to fflush
, but it also instructs the operating system to write to the storage media.
Synopsis
/**
* @param resource $stream
*/
function fsync($stream): bool {}
Passing a non-resource causes a \TypeError
exception:
fsync('test.txt');
Fatal error: Uncaught TypeError: fsync(): supplied resource is not a valid stream resource in ...:...
If a resource
object is passed, but if it does not support fsync
operations, a warning will be raised:
$fh = fopen('memory://test');
fsync($fh);
Warning: fsync(): Can't fsync this stream! in ... on line ...
fdatasync
function
The fdatasync
function synchronizes stream contents to storage media, just like fsync
does, but it does not synchronize file meta-data. Note that this function is only effectively different in POSIX systems. In Windows, this function is aliased to fsync
.
Synopsis
/**
* @param resource $stream
*/
function fdatasync($stream): bool {}
Error handling is similar to the fsync
function.
Usage Example
$file = 'test.txt';
$fh = fopen($file, 'w');
fwrite($fh, 'test data');
fwrite($fh, "\r\n");
fwrite($fh, 'additional data');
fsync($fh);
fclose($fh);
The fsync
(or fdatasync
) call ensures the operating system is requested to write the data to the storage during the fsync
call, in case the data was buffered by PHP or the operating system. The function call will be blocked until the data is written to storage.
Stream Wrapper Support
PHP provides stream wrappers that abstracts internal implementation details. File system functions such as fopen
, fwrite
, and unlink
can then be used across all registered stream wrappers, without having to use different functions for each stream protocol.
Built-in stream wrappers
Only the built-in file
stream wrapper supports fsync
and fdatasync
functions.
Custom stream wrappers
Custom stream wrappers registered with stream_wrapper_register
cannot declare their own fsync
and fdatasync
implementations.
fflush
vs fsync
vs fdatasync
comparison
fflush |
fsync |
fdatasync |
|
---|---|---|---|
Availability | PHP >= 4.0.1 | PHP >= 8.1 | PHP >= 8.1 |
Functionality | Flushes buffers to OS for writing | Flushes to OS and requests to write to storage, and update meta-data | Flushes to OS and requests to write to storage, but only data |
Stream Wrapper support | ✔ | ✘ | ✘ |
Backwards Compatibility Impact
Both fsync
and fdatasync
functions are new functions added to the root namespace.
If there are any existing functions with fsync
or fdatasync
names, this change will cause a function re-declaration fatal error. The top 1,000 packages according to packagist.org download statistics, and a GitHub search shows that there are no existing packages that redeclare functions with fsync
or fdatasync
names.
The new fsync
and fdatasync
functions interact with the underlying operating system, and it is not possible to effectively polyfill these functions to older PHP versions.
However, the PECL extension eio
(pecl.php.net/GitHub) provides eio_fsync
and eio_fdatasync
functions that achieve similar results. Note that the function signatures are different, and may not be fully compatible with the implementation in PHP 8.1.