如果将设置存储在数组中,则可以将它们序列化()并写入文本文件,而不是将原始 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 出现问题,无论如何它都应该被视为严重失败,并且您可能会遇到少数用户如果出现问题,使用此功能将很快与您联系。