我正在编写一个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)
?
答案 0 :(得分: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方法将isset调用包装到prefs数组。
function get_preference($name, &$prefs) {
if (isset($pref[$name]))
return $pref[$name];
return null;
}
var_dump(get_preference('mypref1', $prefs));
除了所提出的所有问题之外,现实情况是,使用你的应用程序,在不太可能发生的事情 错误的情况下,它应该被认为是一个严重的失败,如果出现问题,您可能会使用此功能的少数用户会非常快速地与您联系。
答案 1 :(得分:0)
为什么不直接使用fopen()的截断功能?我相信不是“r +”,你需要传递“w +”......然后如果文件存在,它将被截断,如果不存在,你只需要创建一个新文件。所以代码变成了:
$file = "phpsettings.php";
$handle = fopen( $file, 'w+' );
$str = "<?php \$pref1 = \"$mypref\"; ?>";
fwrite ($handle, $str);
fclose ($handle);
答案 2 :(得分:0)
最好将用户状态存储在会话中,并且只在需要时保持该状态。