-1

我经营一个小型网站,我的用户要求我建立一个邮件列表。我找到了一个简单的免费脚本,可以将电子邮件地址添加到email.txtCSV 格式的受保护文本文件中:

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我希望它根据脚本是否成功在列表中找到并删除它来说“未订阅该电子邮件”或“您已被删除” 。

2011 年 12 月 31 日更新 3 :

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

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

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

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

我希望回显消息成为页面上执行的最后一个脚本。

4

5 回答 5

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;(以确保数字不会与任何内容冲突,因为这会干扰数组翻转)。

于 2011-12-30T16:18:42.200 回答
2

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

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

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

然后我将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. 取消.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>
    

编辑

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

$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.");
}
于 2012-02-24T20:51:21.403 回答
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

如果您最终获得第 3 方服务,请不要支付 Aweber。去MailChimp。如果您的邮件列表不是很大,他们会提供免费计划。

于 2011-12-30T16:22:24.313 回答
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();
}
于 2011-12-30T20:44:27.710 回答
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();
}
于 2011-12-31T07:55:35.703 回答