Contingency plan for fopen error in php

I am writing a PHP application with a "control panel" that writes a prefs file with certain variables. On each POST

, if the file does not exist, it is created. If it exists, it is unlinked

, and a new file touched

with the same file name and new variables. This file is then included in another page, displaying content based on the variables within it.

$file = "phpsettings.php";

if (!file_exists($file)) {
   touch($file);
  $handle = fopen ($file, 'r+'); 
$str = "<?php \$pref1 = \"$mypref\"; ?>";

} else {

unlink($file);
   touch($file);
   $handle = fopen ($file, 'r+'); 
   $str = "<?php \$pref1 = \"$mypref\"; ?>";

}

fwrite ($handle, $str); 
fclose ($handle); 

      

Is this a safe way to write preferences if this file gets overwritten many times a day? Which is a good way how to warn the user of this control panel if the file was not saved correctly, in which case, which would be a good contingency plan to avoid breaking the page, this prefs file is not included before defining a set of defaults for filling if !(file_exists)

?

0


a source to share


3 answers


If you store your settings in an array, you can serialize () them and write them to a text file, instead of writing the original php to a php file and including it.

If you don't sanitize your input for those preferences and say that $ mypref1 represents someone's name, there's nothing stopping them from filling it in in the form field:

\"; echo \"PWNED

      

and your resulting PHP becomes

<?php \$pref1 = \"$mypref\"; echo \"PWNED\"; ?>

      

So first, storing your preferences in an array and using serialize () is much safer:

$prefs = array('mypref1' => 'somethingorother');
$handle = fopen ($file, 'w'); 
fwrite($handle, serialize($prefs));
fclose($h);

// example code demonstrating unserialization
$prefs2 = unserialize(file_get_contents($file));
var_dump($prefs == $prefs2); // should output "(bool) true"

      



You also note in your question that if the file exists, it is not connected. You can simply truncate it to zero length by passing "w" as the second argument to fopen - you don't need to manually remove it. This should set mtime anyway, negating the need to call touch ().

If the values ​​written to the file are preferences, surely each preference can have a default if there aren't hundreds? array_merge will allow you to overwrite based on the key, so if you do something like this:

// array of defaults
$prefs = array(
    'mypref1' => 'pants',
    'mypref2' => 'socks',
);
if (file_exists($file)) {
    // if this fails, an E_NOTICE is raised. are you checking your server error
    // logs regularly?
    if ($userprefs = unserialize(file_get_contents($file))) {
        $prefs = array_merge($prefs, $userprefs);
    }
}

      

If the problem is that heaps exist and you don't want to initialize them, you can get a get_preference method that just wraps the isset call to the prefs array.

function get_preference($name, &$prefs) {
    if (isset($pref[$name]))
        return $pref[$name];
    return null;
}
var_dump(get_preference('mypref1', $prefs));

      

Apart from all the questions that come up, however, the reality is that with your application, in the unlikely event that something goes wrong with fopen, it should still be considered a major glitch, and multiple users are more likely to use this feature. contacting you pretty quickly if something goes wrong.

+2


a source


Why not just use the truncation functions fopen ()? I believe instead of "r +" you have to pass "w +" ... Then if the file exists it will be truncated, if not you just create a new file. So the code becomes:



$file = "phpsettings.php";
$handle = fopen( $file, 'w+' );
$str = "<?php \$pref1 = \"$mypref\"; ?>";
fwrite ($handle, $str); 
fclose ($handle);

      

0


a source


It is always best to keep the state of your users in session and only save that state when needed.

0


a source







All Articles