2011-12-30 94 views
-1

我运行一个小网站,我的用户请求我设置一个邮件列表。我发现了一个简单的免费脚本,将电子邮件地址受保护的文本文件,email.txt,CSV格式:PHP脚本从逗号分隔列表中删除电子邮件地址

[email protected],[email protected],blah,blah,blah 

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

我只想要一个简单的PHP脚本,显示一个文本框,以便用户可以输入他们的电子邮件地址,然后单击“取消通讯”按钮。该脚本应该搜索文本文件,找到给定的电子邮件地址并将其删除,并删除它的尾部逗号。

例如,说的email.txt内容是

[email protected],[email protected],[email protected] 

如果键入“[email protected]”成我想要的脚本中显示的文本框,我想这个文件,看起来像这样:

[email protected],[email protected] 

更新:我想这个代码:

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

这工作就去掉了E-mail地址去,但没有公布(回波)。我想根据脚本是否成功地在列表中找到$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消息是页面上执行的最后一个脚本。

+0

[PHPList(http://www.phplist.com/) – hakre 2011-12-30 16:14:21

+0

它看起来像你应该有一个解析器错误的'$ _POST ['email']'行。 – 2011-12-30 20:32:14

+0

你会如何建议我编码,以消除错误?感谢队友 – 2011-12-30 20:45:03

回答

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

编辑

我做了一些改进。我添加了:

$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."); 
} 
3

有什么理由不使用数据库吗?

CREATE TABLE `emails` (`address` VARCHAR(255) NOT NULL, PRIMARY KEY (`address`)) ENGINE=InnoDB 
INSERT INTO `emails` VALUES ('[email protected]') 
SELECT * FROM `emails` 
DELETE FROM `emails` WHERE `address`='[email protected]' 

这些只是无限更容易,比文本文件更有效率......

但是,如果你想用一个文本文件...

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

基本上它它爆炸由逗号,然后翻转阵列,这样的电子邮件是键(和它们的数字位置值,但是,这并不重要),然后将其删除您想要的电子邮件删除并最终重新组合文件。这样做的好处是,它也会去掉你可能拥有的任何重复项目。

您可以使用类似的方法添加电子邮件地址,只需将unset行更改为$file['[email protected]'] = -1;(以确保该号码与任何内容不冲突,因为这会干扰阵列翻转)。

+0

在第二个例子中,'str_replace($ email,'',$ emailtxt)'不可以用'str_replace(',,',',',$ emailtxt)'来清理吗?(或者我假设一个正则表达式,所以它都在一行...) – 2011-12-30 16:22:35

+0

我不使用数据库的原因是因为我有很多机器人试图访问访问日志中的随机phpmyadmin目录....这只是一个小站点,并且我知道php完全有能力处理平面文件以保存数据库的复杂性并被黑客攻击......。 – 2011-12-30 16:26:22

+0

是的,它会的,但我的方式始终保持重复。 – 2011-12-30 16:26:37

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(); 
} 
+0

喜mate ive有一些运气,但仍然卡住,编辑原始问题 – 2011-12-30 22:58:34

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(); 
} 
+0

我超出了问题的范围,但是我有一些想法,我觉得有义务通知您,并且不知道如何在代码中表达它们。 – 2011-12-31 08:00:00

+0

你是怎么学会打字这样的笑,它的天才:d# – 2011-12-31 11:56:24

+0

http://www.php.net/manual/en/language.oop5.basic.php它允许延长一个相当基本类中,除了构建通过创建一个新的处理器。我的理想是抽象你不想被关注的所有细节。通过这样做,我们将数据层排除在外,并专注于所需的功能。然后,我们返回并添加了必要的功能,通过添加一个简单的平面文件数据层来使其工作。 – 2011-12-31 12:11:02

相关问题