Вопрос

Я пишу PHP-приложение с «панелью управления», которая записывает файл настроек с определенными переменными.На каждом 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); 

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

Это было полезно?

Решение

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

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

\"; echo \"PWNED

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

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

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

$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, это в любом случае следует расценивать как серьезный сбой, и горстка пользователей, которые, вероятно, будут использовать эту функцию, чертовски быстро свяжутся с вами, если что-то пойдет не так.

Другие советы

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

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

$file = "phpsettings.php";
$handle = fopen( $file, 'w+' );
$str = "<?php \$pref1 = \"$mypref\"; ?>";
fwrite ($handle, $str); 
fclose ($handle);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top