2011-12-30 99 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

相關問題