0

我正在编写一个 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); 

如果该文件每天将被覆盖多次,这是一种安全的编写首选项的方式吗?如果文件未正确保存,有什么好方法可以提醒此控制面板的用户,在这种情况下,避免破坏包含此首选项文件的页面的良好应急计划是什么?要填充的默认变量集 if !(file_exists)?

4

3 回答 3

2

如果将设置存储在数组中,则可以将它们序列化()并写入文本文件,而不是将原始 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 方法,它只包装对 prefs 数组的 isset 调用。

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

除了这引发的所有问题之外,现实情况是,对于您的应用程序,万一fopen 出现问题,无论如何都应该被视为严重失败,并且您可能会遇到少数用户如果出现问题,使用此功能将很快与您联系。

于 2009-05-09T15:22:23.173 回答
0

为什么不直接使用 fopen() 的截断功能呢?我相信你需要传递“w+”而不是“r+”......然后如果文件存在,它将被截断,如果不存在,你只需创建一个新文件。所以代码变成了:

$file = "phpsettings.php";
$handle = fopen( $file, 'w+' );
$str = "<?php \$pref1 = \"$mypref\"; ?>";
fwrite ($handle, $str); 
fclose ($handle);
于 2009-05-09T15:13:05.717 回答
0

将用户状态存储在会话中并仅在需要时保留该状态总是更好。

于 2009-05-09T15:18:34.053 回答