用于从逗号分隔列表中删除电子邮件地址的PHP脚本

时间:2011-12-30 16:11:45

标签: php mailing-list

我运行了一个小型网站,我的用户要求我设置一个邮件列表。我找到了一个简单的免费脚本,它以CSV格式将电子邮件地址添加到受保护的文本文件email.txt中:

email1@yahoo.com,email2@yahoo.com,blah,blah,blah

脚本完美无瑕。但是,当用户取消列表订阅时,通过文件手动删除电子邮件地址是一件麻烦事。我需要创建一个删除电子邮件地址的简单脚本。

我想要的只是一个简单的PHP脚本,它显示一个文本框,以便用户输入他们的电子邮件地址并单击“取消新闻稿”按钮。该脚本应搜索文本文件,查找给定的电子邮件地址并将其删除及其尾随逗号。

例如,假设email.txt的内容是

john@yahoo.com,peter@yahoo.com,steve@yahoo.com

如果我在所需脚本显示的文本框中输入“peter@yahoo.com”,我希望文件看起来像这样:

john@yahoo.com,steve@yahoo.com

更新:我试过这段代码:

<?php
        function showForm() {
            echo '
            <form method="post" action="">
            Email Address: <input type="text" name="email"> <br />
            <input type="submit" value="Cancel Newsletter" name="submit">
            </form>
            ';
        }

        $_POST['email']

        $to_delete = 'email';
        $file = array_flip(explode(",",file_get_contents("email.txt")));
        unset($file[$to_delete]);
        file_put_contents("email.txt",implode(",",array_flip($file));

        if(!$file_put_contents) {
            die('Error occured');
        } else {
            echo 'Your subscription has been cancelled. You will not receive any further emails from us.';
        }
    }
} else {
    showForm();
}
?>

此代码甚至不显示表单。

更新2

编写此脚本的另一种尝试:

<?php
    $email = $_POST["email"];
    $text = file_get_contents("email.txt");
    $oldWord = "$email";
    $newWord = "";
    $text = str_replace($oldWord , $newWord , $text);
    $fp = fopen('email.txt', 'w');
    fwrite($fp, $text);
    fclose($file);
?>

这可以删除电子邮件地址,但没有公告(回声)。我想根据脚本是否成功找到列表中的$email并将其删除来说“电子邮件未订阅”或“您已被删除”。

更新3 2011年12月31日:

我尝试了高级代码,只是得到一个空白页面,所以我回到了我的版本。这是我现在的代码:

<html>
    <body>
        <form method="post" action="">
            <p>Email Address: <input type="text" name="email"></p>
            <input type="submit" value="Cancel Newsletter" name="submit">
        </form>

        <?php
            $email = $_POST["email"];
            $basetext = file_get_contents("email.txt");
            $oldWord = "$email";
            $newWord = "";
            $text = str_replace($oldWord , $newWord , $basetext);
            $str1 = $basetext;
            // echo strlen($str1);
            $str2 = $text;
            // echo strlen($str2);
            $fp = fopen('email.txt', 'w');
            fwrite($fp, $text);
            if ($str1 > $str2) { // This part handles the success/fail message
                echo ("Success!");
            } else {
                echo ("Fail!");
            }
            fclose($file);
        ?>
    </body>
</html>

这完美无缺。但是,在按下提交按钮后,它会在加载页面时显示“失败”消息,而不是在触发加载时显示。

如果可能,我想保留原始代码,只需重新排列,以便只显示“成功!”或“失败!”一旦它执行了代码。

我希望echo消息是页面上执行的最后一个脚本。

5 个答案:

答案 0 :(得分:3)

你有没有理由不使用数据库?

CREATE TABLE `emails` (`address` VARCHAR(255) NOT NULL, PRIMARY KEY (`address`)) ENGINE=InnoDB
INSERT INTO `emails` VALUES ('user1@example.com')
SELECT * FROM `emails`
DELETE FROM `emails` WHERE `address`='user1@example.com'

这些比文本文件更容易,更有效......

但是如果你想使用文本文件......

$to_delete = 'user1@example.com';
$file = array_flip(explode(",",file_get_contents("email.txt")));
unset($file[$to_delete]);
file_put_contents("email.txt",implode(",",array_flip($file));

基本上它用逗号进行爆炸,然后翻转数组以便电子邮件是键(并且它们的数字位置是值,但这无关紧要),然后它删除要删除的电子邮件,最后重新组装文件。这样做的好处是它也会删除你可能拥有的任何副本。

您可以使用类似的方法添加电子邮件地址,只需将unset行更改为$file['user1@example.com'] = -1;(以确保该数字不会与任何内容冲突,因为这会干扰数组翻转)

答案 1 :(得分:2)

此答案最初由OP附加到问题正文中。

首先,我将表单移至/cancel.html并使用<form action="/cancel_submit.html">

(我编写.html的地方,只是为了演示,因为我的服务器配置为不使用页面扩展,并且还在.html页面上解析PHP。)

然后我将PHP代码放入页面/cancel_submit.html并移动

if ($str1 > $str2) {
    echo ("You Have Successfully Unsubscribed From Our Newsletter....<br>You Will Not Receive Any More Emails From Us.");
} else {
    echo ("The Email Address You Specified Is Not In Our Mailing List.");
}

到另一组PHP括号。

这意味着电子邮件地址已通过POST发送到另一页,然后从列表中执行实际删除的电子邮件地址,然后检查地址是否已删除以提供确认消息

我还在$oldword = "$email";添加了两个逗号,使其成为$oldword = ",$email,";,这样只有在任何一方都有逗号的情况下,它才会找到输入电子邮箱的文本。这解决了有人提交一半电子邮件地址的情况。

我还将$newWord = "";更改为$newWord = ",";,这样如果脚本删除了每边都带逗号的电子邮件地址,则它旁边的两个电子邮件地址将不会被分隔一个逗号。

以下是我现在对这两个页面的代码:

  1. cancel.html

    <p>To cancel our Newsletter please enter your email address below....</p>
    <p>
    <form method="post" action="/cancel_submit.html">
    <p>Email Address: <input type="text" name="email"></p>
    <input type="submit" value="Cancel Newsletter" name="submit">
    </form>
    
  2. cancel_submit.html

    <?php
        $email = $_POST["email"];
        $basetext = file_get_contents("email.txt");
        $oldWord = ",$email,";
        $newWord = ",";
        $text = str_replace($oldWord , $newWord , $basetext);
        $str1 = $basetext;
        // echo strlen($str1);
        $str2 = $text;
        // echo strlen($str2);
        $fp = fopen('email.txt', 'w');
        fwrite($fp, $text);
        fclose($file);
    ?>
    <?php
        if ($str1 > $str2) {
            echo ("You Have Successfully Unsubscribed From Our Newsletter....<br>You Will Not Receive Any More Emails From Us.");
        } else {
            echo ("The Email Address You Specified Is Not In Our Mailing List.");
        }
    ?>
    <p>
        <p>Please wait to be re-directed or <a href="http://the-flying-shuttle.com/"><u>CLICK HERE.</u></a>
        </p>
    
  3. 修改

    我做了一些改进。我补充说:

    $email = strtolower($email);
    

    同时发送电子邮件添加脚本和电子邮件删除脚本。这将所有输入到任一形式的字符转换为小写;以前,它不会删除与大名单不同的案例中输入的电子邮件。

    这弄乱了确认消息命令,因此我将其更改为

    if (str_replace($oldWord , $newWord , $basetext)) {
        echo ("You Have Successfully Unsubscribed From Our Newsletter....<br>You Will Not Receive Any More Emails From Us.");
    } else {
        echo ("The Email Address You Specified Is Not In Our Mailing List.");
    }
    

答案 2 :(得分:0)

建议研究:

http://us.php.net/manual/en/function.explode.php
http://us3.php.net/manual/en/function.file-put-contents.php
编辑添加: http://us3.php.net/manual/en/function.file-get-contents.php

如果您最终获得第三方服务,请不要付费给Aweber。转到MailChimp。如果您的邮件列表不是很大,他们就有免费的计划。

答案 3 :(得分:0)

在您的示例中,您引用变量$_POST['email']而不分配或测试该值。此外,您可能希望清理此变量。

我看到的另一个问题是$to_delete = 'email';,您只是在寻找“电子邮件”的条目。

您的$file_put_contents未被分配。

} else { showForm(); }未与if语句配对。

<?php
function showForm() {
    echo '<form method="post" action="">' . PHP_EOL
       . 'Email Address: <input type="text" name="email"> <br />' . PHP_EOL
       . '<input type="submit" value="Cancel Newsletter" name="submit">' . PHP_EOL
       . '</form>';
}

if($_POST['email']) {

    $to_delete = $_POST['email'];
    $file = array_flip(explode(",",file_get_contents("email.txt")));
    unset($file[$to_delete]);
    $file_put_contents = file_put_contents("email.txt",implode(",",array_flip($file));

    if(!$file_put_contents) {
        die('Error occured');
    } else {
        echo 'Your subscription has been cancelled. You will not receive any further emails from us.';
    }
} else {
    showForm();
}

答案 4 :(得分:0)

如果我理解你的问题,这就是你想要实现的目标。

  • 检查用户是否已从表单发布。
    • 收到电子邮件。 (你应该确保在这一步中它是一个理智的值)
    • 检索会员数据。
    • 检查用户是否在列表中。
      • 删除用户并保存数据(如果适用)。
    • 输出功能结果。
  • 显示包含要提交给自己的表单的邮件。

我知道这可以作为一项非常简单的任务完成,但我不相信这种方法。此外,我认为任何与永久存储数据交互的内容都应该有一些轻度到中等的抽象形式。

我会这样接近这个任务。

class MailingList {

    const EMAIL_OK = 1;
    const ERR_EMAIL_EXISTS = -1;
    const ERR_EMAIL_INVALID = -2;
    const ERR_EMAIL_NOTFOUND = -3;

    protected $_db_src;
    protected $_db_opt;
    protected $members = array(); // An array intended to hold members.

    public function email_exists($email) {
        return array_key_exists($this->members, $email);
    }

    public function remove_email($email) {
        $this->_sanitize_email($email);

        if ($email) {
            if (array_key_exists($this->members, $email)) {
                unset($this->members[$email]);
                $this->_update_members();
                return self::EMAIL_OK;
            } else {
                return self::ERR_EMAIL_NOTFOUND;
            }
        } else {
            return self::ERR_EMAIL_INVALID;
        }
    }

    public function add_email($email) {
        $this->_sanitize_email($email);

        if ($email) {
            if (array_key_exists($this->members) {
                return self::ERR_EMAIL_EXISTS;
            } else {
                $this->members[$email] = -1;
                $this->_save_members();
                $this->_load_members();
                return self::EMAIL_OK;
            }
        } else {
            return self::ERR_EMAIL_INVALID;
        }
    }

    // We expect a data source and options for the
    //     data source upon instantiation.
    // This is to prepare this class for abstraction and allow it to be
    //     extended to databases.

    public function __construct($data_source = "flatfile", $data_options = "email.txt") {
        $this->_db_src = $data_source;
        $this->_db_opt = $data_options;

        $this->_load_members();
    }

    protected function _load_members() {
        // Create the function name to ensure it exists.
        $data_function = "handle_" . $this->_db_src;
        if (!method_exists(&$this, $this->_db_src)) {
            throw new Exception('Invalid data source');
        }

        // Build our array of parameters to be sent to our handler function.
        $parameters = array_merge(array('load'), (array) $this->_db_opt);

        // This calls our data function with a load action parameter.
        // This is written to expect the data function to populate $this->members.
        return call_user_func_array(array(&$this, $data_function), $parameters);
    }

    // Most of this is similar to the constructor as far as data handling goes.
    protected function _save_members() {
        // Create the function name to ensure it exists.
        $data_function = "handle_" . $this->_db_src;
        if (!method_exists(&$this, $this->_db_src)) {
            throw new Exception('Invalid data source');
        }

        // Set up our data options with a save action.
        $parameters = array_merge(array('save'), (array) $this->_db_opt);

        return call_user_func_array(array(&$this, $data_function), $parameters);
    }

    // The heart of the storage engine, designed for CSV data.
    protected function handle_flatfile($action, $filename) {
        switch ($action) {
            case "load":
                // Make sure we can load members.
                if (!is_readable($filename)) {
                    throw new Exception("File: $filename, is not readable");
                }
                // Open our data file and load the information.
                // Populate $this->members as an array just the way we expect it.
                $this->members = array_flip(explode(',', file_get_contents($filename)));
                break;
            case "save":
                // Make sure we can write to the file before we move forward.
                if (!is_writeable($filename)) {
                    throw new Exception("File $filename, is now writable");
                }
                // Convert our array back to a CSV string and write it to the file.
                $status = file_put_contents($filename, implode(',', array_flip($this->members)));
                // If we failed to write to the file make sure something is done before we continue.
                if (!$status) {
                    throw new Exception("Writing to file failed!");
                }
                break;
            default:
                throw new Exception("Unknown action called on data handler.");
        }
    }

    // converts email addresses to lowercase to avoid duplication.
    // should add a regex filter here to ensure that we have a valid address
    protected function _sanitize_email(&$email) {
        $email = strtolower($email);
    }

}

function show_form() {
    echo '<form method="post" action="">' . PHP_EOL
       . 'Email Address: <input type="text" name="email"> <br />' . PHP_EOL
       . '<input type="submit" value="Cancel Newsletter" name="submit">' . PHP_EOL
       . '</form>';
}

if (isset($_POST) && isset($_POST['email'])) {
    $list = new MailingList();
    $status = $list->remove_email($_POST['email']);

    switch ($status) {
        case MalingList::EMAIL_OK:
            echo "<p class='success'>Your email was successfully removed.<p>";
            break;
        case MailingList::ERR_EMAIL_INVALID:
            echo "<p class='error'>The email address provided was invalid.</p>";
        case MailingList::ERR_EMAIL_NOTFOUND:
            echo "<p class='error'>The email address provided was not registered.</p>";
        default:
            show_form();
    }
} else {
    show_form();
}