✨feature: Initial MVP
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// phpcs:disable PEAR.Commenting.FileComment,PEAR.Commenting.ClassComment
|
||||
|
||||
/**
|
||||
* Atomic file writing support.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace IronKanban\Support;
|
||||
|
||||
/**
|
||||
* Writes files using a temporary file swap.
|
||||
*/
|
||||
final class AtomicWriter
|
||||
{
|
||||
/**
|
||||
* Atomically write contents to a file.
|
||||
*
|
||||
* @param string $path Destination path.
|
||||
* @param string $contents File contents.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function write(string $path, string $contents): void
|
||||
{
|
||||
ensure_directory(dirname($path));
|
||||
|
||||
$tmpPath = $path . '.tmp-' . bin2hex(random_bytes(4));
|
||||
$handle = fopen($tmpPath, 'wb');
|
||||
|
||||
if ($handle === false) {
|
||||
throw new \RuntimeException('Unable to open temp file: ' . $tmpPath);
|
||||
}
|
||||
|
||||
try {
|
||||
if (fwrite($handle, $contents) === false) {
|
||||
throw new \RuntimeException('Unable to write temp file: ' . $tmpPath);
|
||||
}
|
||||
|
||||
fflush($handle);
|
||||
} finally {
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
if (!rename($tmpPath, $path)) {
|
||||
@unlink($tmpPath);
|
||||
throw new \RuntimeException('Unable to move temp file into place: ' . $path);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user