Search code examples
phpfile-permissionsfopen

File Opened With fopen($file, 'w') Is Not Writeable


Loading a text file into a form with fopen($file, 'w') but the file is not write-able and changes cannot be saved. Obviously a permissions issue but I do not want to change them to 777 for obvious security reasons. Is there a way to do it on the fly, then change it back after saving?

<?php $file = "$ServerRoot/text/test.txt";
// $ServerRoot is defined elsewhere and is to the root of the filesystem

// Retrieve the submitted changes and save to the file
if ($_SERVER['REQUEST_METHOD'] === "POST") :
    $fh = fopen($file, 'w') or die("Can't open file for writing.");
    fwrite($fh, $_POST['textfield']);
    fclose($fh);
    echo "Content saved.";
endif;

// FOR DIAGNOSTIC PURPOSES ONLY
$TestFile = (file_exists($file)) ? "The file exists\n" : "The file does <font color=\"red\">NOT</font> exist\n";
$TestFile .= (is_readable($file)) ? "The file is readable\n" : "The file is <font color=\"red\">NOT</font> readable\n";
$TestFile .= (is_writable($file)) ? "The file is writable\n" : "The file is <font color=\"red\">NOT</font> writable\n";
$TestFile = nl2br($TestFile);

// Read the textfile
$text = file_get_contents($file);?>

<div align="center">
<?=$TestFile;?>
    <form action="<?=$submitFormAction;?>" method="post">
        <div><input type="submit" value="Save File" />
        <input type="reset" value="Reset"/></div>
        <div><textarea name="textfield" rows="25" cols="85"><?=htmlspecialchars($text);?></textarea></div>
        <div><input type="submit" value="Save File" />
        <input type="reset" value="Reset"/></div>
    </form>
</div>

Solution

  • Never chmod files to 777. Not even temporarily. It's a security risk and shouldn't be needed on a server that's been setup properly.

    If PHP is unable to write to a file, it means the webserver is not the owner of the file or you've somehow revoked writing permissions from the owner as root / administrator. Verify the owner of the file in question. If you are using Apache as your webserver, the owner should probably be something like www-data. If it's not the correct owner, make sure to fix that issue by changing the owner.

    Keep in mind that if you've setup apache to serve multiple domains, the owner(s) are probably quite different, like client1, client2 etc.

    After you've made sure the correct owner is set, chmodding the file to 755 should be sufficient.