<?php
/**
* Replaces file content with minimal disruption
* @param string $fileName
* @param string $content
*/
function replaceFileContent($fileName, $content)
{
$newFile = $fileName . '.new';
$backupFile = $fileName . '.old';
$dir = dirname($fileName);
if (!is_writable($dir)) {
throw new Exception('Directory ' . $dir . ' is not writable');
}
//write to .new to avoid affecting users while php is writing to file
if (@file_put_contents($newFile, $content) === FALSE) {
throw new Exception('Failed writing to ' . $newFile);
}
//copy old file to backup, original file stays in place
if (@copy($fileName, $backupFile) === FALSE) {
throw new Exception('Failed copying ' . $fileName . ' to ' . basename($backupFile));
}
//rename overwrites existing file quickly
if (@rename($newFile, $fileName) === FALSE) {
//failed to overwrite file
if (!file_exists($fileName) || filesize($fileName) == 0) {
//restore from backup
if (!@rename($backupFile, $fileName)) {
throw new Exception('Holly shit, failed to restore ' . $fileName . ' from backup');
}
}
throw new Exception('Failed writing to ' . $fileName . ', restored from backup');
}
}