我正在写一个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)
发布于 2009-05-09 15:22:23
如果您将设置存储在数组中,则可以序列化()它们并将其写入文本文件,而不是将原始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-09 15:13:06
为什么不直接使用fopen()的截断功能呢?我相信你需要传递“w+”而不是"r+“...如果文件存在,它将被截断,如果不存在,您只需创建一个新文件。因此代码变成:
$file = "phpsettings.php";
$handle = fopen( $file, 'w+' );
$str = "<?php \$pref1 = \"$mypref\"; ?>";
fwrite ($handle, $str);
fclose ($handle);发布于 2009-05-09 15:18:34
将用户状态存储在会话中并仅在需要时保存该状态总是更好的做法。
https://stackoverflow.com/questions/843464
复制相似问题