План на случай непредвиденных обстоятельств при ошибке в php - PullRequest
0 голосов
/ 09 мая 2009

Я пишу приложение PHP, которое имеет «панель управления», которая записывает файл prefs с определенными переменными. На каждом POST, если файл не существует, он создается. Если он существует, то это unlinked, а новый файл - touched с тем же именем файла и новыми переменными. Этот файл затем включается в другую страницу с отображением содержимого на основе переменных внутри него.

$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); 

Это безопасный способ записи настроек, если этот файл будет перезаписываться много раз в день? Что является хорошим способом как предупредить пользователя этой панели управления, если файл не был сохранен правильно, и в этом случае, что было бы хорошим планом на случай непредвиденных обстоятельств, чтобы не сломать страницу, этот файл prefs включен после определения набор переменных по умолчанию для заполнения, если !(file_exists)?

Ответы [ 3 ]

2 голосов
/ 09 мая 2009

Если вы храните ваши настройки в массиве, вы можете сериализовать () их и записать в текстовый файл, вместо записи необработанного php в файл php и включения его.

Если вы не очищаете свой ввод для этих предпочтений и говорите, что $ mypref1 представляет чье-то имя, ничто не мешает ему заполнить это в поле формы:

\"; echo \"PWNED

и ваш получившийся PHP станет

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

Итак, во-первых, хранить ваши настройки в массиве и использовать serialize () гораздо безопаснее:

$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"

В вашем вопросе вы также упоминаете, что если файл существует, он не связан. Вы можете просто обрезать его до нулевой длины, передав «w» в качестве второго аргумента fopen - вам не нужно удалять его вручную. В любом случае это должно установить mtime, исключая необходимость вызова touch ().

Если значения, записываемые в файл, являются предпочтениями, наверняка у каждого предпочтения может быть значение по умолчанию, если только нет сотен? array_merge позволит вам перезаписывать данные для каждого ключа, поэтому если вы сделаете что-то вроде этого:

// 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);
    }
}

Если проблема в том, что существуют кучи, и вам не нужно инициализировать их все, у вас может быть метод get_preference, который просто оборачивает вызов isset в массив prefs.

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

Помимо всех вопросов, которые это поднимает, реальность такова, что с вашим приложением, в маловероятном случае, если что-то пойдет не так с fopen, это все равно следует рассматривать как серьезный сбой, горстка пользователей, которым вы, вероятно, воспользуетесь этой функцией, очень быстро свяжется с вами, если что-то пойдет не так.

0 голосов
/ 09 мая 2009

Всегда лучше хранить состояние пользователей в сеансе и сохранять его только при необходимости.

0 голосов
/ 09 мая 2009

Почему бы просто не использовать возможности усечения fopen ()? Я считаю, что вместо «r +» вам нужно будет передать «w +» ... Тогда, если файл существует, он будет усечен, если нет, вы просто создадите новый файл. Таким образом, код становится:

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