0

我在我的网站上有订阅功能,它由一个简单的表单组成,用户在其中键入他们的电子邮件并围绕以下 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 文件中删除?

4

4 回答 4

2

我会这样做

$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);
于 2013-11-10T22:04:39.410 回答
1

使用 MySQL 之类的数据库会容易得多。

您的解决方案依赖于“emails.txt”文件,它有几个缺点:

  • 您应该考虑两个人想要同时取消订阅他们的电子邮件的场景 - 您需要使用flock函数。
  • 如果您有很多电子邮件,则可能需要很长时间才能阅读所有电子邮件,将它们写入临时文件,然后将临时文件重命名为原始文件。
于 2013-11-10T21:57:07.287 回答
0

您可以将其全部读入一个数组,然后只将不匹配的行写回文件。

$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 数据库用于类似的事情。它使搜索和操作记录变得微不足道,更不用说有人下载文本文件给您带来的安全风险——这对订阅您的服务的人来说是非常不负责任的。

于 2013-11-10T21:57:24.960 回答
0

你会更好地使用换行符而不是逗号:

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

确保在站点根目录之外保护您的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();
    }
}

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

于 2013-11-10T22:36:44.737 回答