php中fopen错误的应急计划

发布于 2024-07-19 02:26:00 字数 699 浏览 2 评论 0原文

我正在编写一个 PHP 应用程序,它有一个“控制面板”,可以编写带有某些变量的首选项文件。 在每个 POST 上,如果文件不存在,则会创建它。 如果确实存在,则取消链接,并使用相同的文件名和新变量触及新文件。 然后,该文件包含在另一个页面上,并根据其中的变量显示内容。

$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)? 则填充默认变量集

I'm writing a PHP app that has a 'control panel' that writes a prefs file with certain variables. On every POST, if the file doesn't exist, it is created. If it does exist, it is unlinked and a new file is touched with the same filename and new variables. This file is then included on another page with displays content based on the variables inside it.

$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); 

Is this a safe way of writing preferences, provided this file will be overwritten many times per day? What is a good way of both alerting the user of this control panel if the file wasn't saved correctly, and in that case, what would be a good contingency plan to avoid breaking the page this prefs file is included on short of defining a default set of variables to fill if !(file_exists)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

魄砕の薆 2024-07-26 02:26:00

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

If you store your settings in an array, you can serialize() them and write to a text file, rather than writing raw php to a php file and including it.

If you're not sanitising your input for those preferences, and say $mypref1 represents someone's name, there's nothing stopping them from filling this out in the form field:

\"; echo \"PWNED

and your resulting PHP will become

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

So firstly, storing your preferences in an array and using serialize() is much safer:

$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"

In your question, you also mention that if the file does exist, it is unlinked. You can simply truncate it to zero length by passing "w" as the second argument to fopen - you don't need to manually delete it. This should set the mtime anyway, negating the need for the call to touch().

If the values being written to the file are preferences, surely each preference could have a default, unless there are hundreds? array_merge will allow you to overwrite on a per-key basis, so if you do something like this:

// 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);
    }
}

If the issue is that there are heaps, and you don't want to have to initialise them all, you could have a get_preference method which just wraps an isset call to the prefs array.

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

Beyond all of the questions this raises though, the reality is that with your app, in the unlikely event that something does go wrong with the fopen, it should be regarded as a serious failure anyway, and the handful of users you're likely to have making use of this feature are going to be contacting you pretty darn quick if something goes wrong.

独守阴晴ぅ圆缺 2024-07-26 02:26:00

最好将用户状态存储在会话中,并且仅在需要时保留该状态。

It is always better to store your users state in a session and only persist that state when needed.

謸气贵蔟 2024-07-26 02:26:00

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

$file = "phpsettings.php";
$handle = fopen( $file, 'w+' );
$str = "<?php \$pref1 = \"$mypref\"; ?>";
fwrite ($handle, $str); 
fclose ($handle);

Why not just use the truncation capabilities of fopen()? I believe instead of "r+", you'll need to pass "w+"... Then if the file exists, it will be truncated, if it doesn't you'll just create a new file. So the code becomes:

$file = "phpsettings.php";
$handle = fopen( $file, 'w+' );
$str = "<?php \$pref1 = \"$mypref\"; ?>";
fwrite ($handle, $str); 
fclose ($handle);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文