PHP - 从 txt 文件中删除文本


PHP - delete text from a txt file

我的网站上有订阅功能,它由一个简单的表单组成,用户在其中键入他们的电子邮件并舍入以下PHP:

$database = "emails.txt"; 
$file = fopen($database, "a+");
$size = filesize($database);
$email = $_POST['email'];
if($_POST['submit']) fwrite($file, "$email,");
if($_POST['submit']) echo "<p style='color:white; margin-top:25px;'>*Check your inbox*</p>";
?>

如何设置取消订阅功能,让用户在表单中键入电子邮件,然后将其从.txt文件中删除?

这就是我会这样做的

$email = $_GET['email'];
$deletedFormat = "";
//read the entire string
$str=file_get_contents('emails.txt');
//replace something in the file string - this is a VERY simple example
$str=str_replace("$email", "$deletedFormat",$str);
file_put_contents('emails', $str);

使用像MySQL这样的数据库会容易得多。

您的解决方案依赖于"电子邮件.txt"文件,并且它有几个缺点:

  • 您应该考虑两个人想要同时取消订阅电子邮件的情况 - 您需要使用flock功能。
  • 如果您有很多电子邮件,那么阅读所有电子邮件,将它们写入临时文件,然后将临时文件重命名为原始文件可能需要很长时间。

您可以将所有内容读入数组,然后仅将不匹配的行写回文件。

$find = 'joe@bloggs.com';
$emails = file('emails.txt');
foreach ($emails as $email) {
    if ( !strstr($email, $find) ) {
        $result .= $email;
    } 
}
file_put_contents('emails.txt', $result);

实际上,您确实应该使用MySQL数据库来实现这样的事情。它使搜索和操作记录变得微不足道,更不用说下载文本文件的人的安全风险 - 这对订阅您服务的人来说是不负责任的。

最好

使用换行符而不是逗号:

if ($_POST['subscribe'])) {
    touch('emails.txt');
    $emails = file('emails.txt', FILE_IGNORE_NEW_LINES);
    if (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)
            && !in_array($_POST['email'], $emails)) {
        $emails[] = $_POST['email'];
        file_put_contents('emails.txt', explode("'n", $emails));
    }
} elseif ($_POST['unsubscribe']) {
    touch('emails.txt');
    $emails = file('emails.txt', FILE_IGNORE_NEW_LINES);
    if (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)
            && ($index = array_search($_POST['email'], $emails)) !== false) {
        unset($emails[$index]);
        file_put_contents('emails.txt', explode("'n", $emails));
    }
}

确保保护您的电子邮件.txt文件超出站点根目录。

您可能希望为此使用 SQLite 数据库:

$db = new PDO('sqlite:emails.sqlite');
$db->exec('CREATE TABLE IF NOT EXISTS subscriptions (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    email VARCHAR(64) NOT NULL UNIQUE
)');
if ($_POST['subscribe']) {
    if (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
        $stmt = $db->prepare('INSERT ON CONFLICT IGNORE subscriptions (email) VALUES (:email)');
        $stmt->bindValue(':email', $_POST['email']);
        $stmt->execute();
    }
} elseif ($_POST['unsubscribe']) {
    if (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
        $stmt = $db->prepare('DELETE FROM subscriptions WHERE email = :email');
        $stmt->bindValue(':email', $_POST['email']);
        $stmt->execute();
    }
}

它没有经过测试,但应该可以工作。确保同时保护站点根目录之外的 email.sqlite