2011-10-11 133 views
-1

我知道有很多類似於我的問題,是的,我看過其中的一些,他們都沒有回答我的問題。電子郵件SQL附件問題

基本上我爲客戶端創建了一個腳本,它創建了數據庫的轉儲並通過電子郵件發送給他們,我將發佈下面的代碼,現在通過腳本生成數據庫信息並且沒有創建物理sql文件在服務器上,而是將其全部添加到變量中,然後使用該變量將數據庫信息附加到電子郵件標題。

另請注意我以前使用過電子郵件附件的代碼,它工作正常,但在那種情況下,文件確實存在,所以我開始認爲這是問題。

<?php 

    //Script configuration section. 
    $D_hostname = 'localhost'; # Database hostname. 
    $D_username = 'username'; # Database username. 
    $D_password = 'password'; # Database password. 
    $D_database = 'database'; # Database name. 

    $E_from = '{BLOG BACKUP} <[email protected]>'; # From header. 
    $E_subject = '[' . date('d-m-Y') . ']: This weeks database backup.'; # Email subject. 
    $E_content = 'This weeks database backup has been created, please find it attached to this email. Remember to save a copy and retain this email too!<br />'; #Email content. 
    $E_filename = date('d-m-Y') . '_blog_backup.sql'; #Attachment filename. 
    $E_filetype = 'application/octet-stream'; # Attachment type. 
    $E_recipients = '[email protected], [email protected]'; #Email recipients. 

    //Connect to the database. 
    $connection = mysql_connect($D_hostname, $D_username, $D_password); 

    //Select the database 
    mysql_select_db($D_database, $connection); 

    //Set up an empty array. 
    $tables = array(); 

    //Get a list of all the databases tables. 
    $Q_show_tables = mysql_query('SHOW TABLES'); 

    //Add each table to the array. 
    while($R_show_tables = mysql_fetch_row($Q_show_tables)){ 
     $tables[] = $R_show_tables[0]; 
    } 

    //Get all rows for each table and create a mySQL query. 
    foreach($tables as $table) { 

     //Get all rows from the table. 
     $Q_get_rows = mysql_query('SELECT * FROM '.$table); 
     $C_get_rows = mysql_num_fields($Q_get_rows); 

     //Add a drop clause for the table 
     $data_row .= 'DROP TABLE ' . $table . ';'; 

     //Get create table info. 
     $Q_create_table = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table)); 

     //Add the create table clause to the query. 
     $data_row.= "\n\n" . $Q_create_table[1] . ";\n\n"; 

     //Now gather all of the rows. 
     for ($int_01 = 0; $int_01 < $C_get_rows; $int_01++) { 
      while($R_get_rows = mysql_fetch_row($Q_get_rows)) { 

       //Add the insert clause. 
       $data_row .= 'INSERT INTO ' . $table . ' VALUES ('; 

       //For each field write out a row. 
       for($int_02 = 0; $int_02 < $C_get_rows; $int_02++) { 
        $R_get_rows[$int_02] = addslashes($R_get_rows[$int_02]); 
        $R_get_rows[$int_02] = ereg_replace("\n","\\n",$R_get_rows[$int_02]); 
        if (isset($R_get_rows[$int_02])) { 
         $data_row .= '"'.$R_get_rows[$int_02].'"' ; 
        } else { 
         $data_row .= '""'; 
        } 
        if ($int_02 < ($num_fields-1)) { 
         $data_row .= ','; 
        } 
       } 
      $data_row .= ");\n"; 
      } 
     } 
     $data_row .="\n\n\n"; 
    } 

    //Split and encode the data. 
    $data_split = chunk_split(base64_encode($data_row)); 

    //Create a unique boundary 
    $new_boundary = md5(time()); 

    //This is your basic header information such as who the email is from and the date it was sent. 
    $mail_header .= 'From: ' . $E_from . "\r\n"; 
    $mail_header .= 'Date: ' . date('r') . "\r\n"; 

    //This part of the header first defines to the email client that it is a multipart message and adds the emails content/body. 
    $mail_header .= 'Content-Type: multipart/mixed; boundary="' . $new_boundary . '"' . "\r\n\r\n"; 
    $mail_header .= 'MIME-Version: 1.0' . "\r\n"; 
    $mail_header .= 'This is a multi-part message in MIME format' . "\r\n"; 
    $mail_header .= '--' . $new_boundary . "\r\n"; 
    $mail_header .= 'Content-Type:text/html; charset="iso-8859-1"' . "\r\n"; 
    $mail_header .= 'Content-Transfer-Encoding: 7bit' . "\r\n\r\n"; 
    $mail_header .= $E_content . "\r\n\r\n"; 

    //This part of the header is for the attachment and includes the contents of the file, the files name and other information. 
    $mail_header .= '--' . $new_boundary . "\r\n"; 
    $mail_header .= 'Content-Type: ' . $E_filetype . '; name="' . $E_filename . '"' . "\r\n"; 
    $mail_header .= 'Content-Transfer-Encoding: base64' . "\r\n"; 
    $mail_header .= 'Content-Disposition: attachment; filename="' . $E_filename . '"' . "\r\n\r\n"; 
    $mail_header .= $data_split . "\r\n\r\n"; 

    //This is needed to stop any rendering errors by email clients and signifies the end of the emails header. 
    $mail_header .= '--' . $new_boundary . '--' . "\r\n"; 

    //This mails out all of the above. 
    mail($E_recipients, $E_subject, '', $mail_header); 

?> 

問題:當電子郵件被髮送附件和郵件內容不部落郵件客戶端或Hotmail顯示在所有,但它在Gmail中正常工作。我猜這是郵件標題的問題,但我無法看到任何錯誤。

任何人都可以看到電子郵件標題的任何問題?如果是的話,你可以告訴我如何解決這個問題?

一如既往,非常感謝幫助。

+0

我還應該注意,它在Gmail中顯示正常,但在Hotmail或Horde中不顯示。我還沒有嘗試任何其他郵件客戶端。 – RobFos

+0

作爲一個旁註,電子郵件不是通信的最安全的手段,發送你的數據庫與我看起來很危險 –

+0

這不是一個解決方案,但是當我看你的代碼,我真的不得不建議你看看[ ezMail](http://ezcomponents.org/docs/tutorials/Mail),它可以輕鬆快速地處理通過PHP發送郵件的所有問題。沒有必要重新發明輪子。 –

回答

1

聖潔的莫里!

用mime對象創建格式正確的電子郵件並不是一項簡單的任務。我已經黑了metamail代碼,但不會夢想編寫我自己的PHP代碼來處理它。如果我沒有本地實現一個可以從PHP(metamail,mutt)調用的支持MIME的郵件客戶端,我會使用一個免費的庫來處理它(phpmailer,swiftmailer是明顯的候選者)。

我傾向於避免的另一件事是在PHP腳本中創建內存中的數據庫備份表示。

一些其他的事情我不會做是:使用和addslashes逃脫DB輸入

  • 與因果關係的性質篡改

    • 忌用模塊化編程,那裏有被分隔
    • 關注
    • 通過電子郵件傳輸潛在的非常大的文件(大多數MTA會限制電子郵件的大小)

    我建議重新開始 - 設置一個cron作業以將備份提取到本地文件,然後編寫一個PHP來訪問該文件 - 並通過電子郵件向用戶發送鏈接,以便他們可以下載備份。

  • +0

    是的,我想這將是處理事情的最佳方式,我想我是善良的我喜歡將數據庫通過電子郵件發送給客戶端的想法,我不必擔心他們不會去我的服務器上的數據庫存儲庫,然後在出現問題時向我抱怨,而且他們沒有備份。即使這不會是我的錯,我寧願不做對抗和分歧。但是,我會寫一個新的腳本來處理這一切,而不用通過電子郵件發送數據庫。感謝你的回答! – RobFos

    0

    你應該把身體放在身體裏。它可能是一個MIME消息,因此包含頭文件,但它在技術上仍然是消息的主體,並且這是它應該去的地方。

    此外,你有一些不必要的\r\n序列在那裏 - 這些不應該已打破它,但最好不包括他們。嘗試下面的代碼建設/發送消息:

    //Split and encode the data. 
    $data_split = chunk_split(base64_encode($data_row)); 
    
    //Create a unique boundary 
    $new_boundary = '-------'.md5(time()).'-----'; 
    
    //This is your basic header information such as who the email is from and the date it was sent. 
    $mail_header = 'From: ' . $E_from . "\r\n"; 
    $mail_header .= 'Date: ' . date('r') . "\r\n"; 
    
    //This part of the header first defines to the email client that it is a multipart message and adds the emails content/body. 
    $mail_header .= 'Content-Type: multipart/mixed; boundary="' . $new_boundary . '"' . "\r\n"; 
    $mail_header .= 'MIME-Version: 1.0' . "\r\n"; 
    
    // The body (multipart message) starts here: 
    $mail_body = 'This is a multi-part message in MIME format' . "\r\n"; 
    
    // HTML content of the email 
    $mail_body .= "$new_boundary\r\n"; 
    $mail_body .= 'Content-Type: text/html; charset="iso-8859-1"' . "\r\n"; 
    $mail_body .= 'Content-Transfer-Encoding: 7bit' . "\r\n\r\n"; 
    $mail_body .= $E_content . "\r\n"; 
    
    // This part of the body is for the attachment and includes the contents of the file, the files name and other information. 
    $mail_body .= "$new_boundary\r\n"; 
    $mail_body .= 'Content-Type: ' . $E_filetype . '; name="' . $E_filename . '"' . "\r\n"; 
    $mail_body .= 'Content-Transfer-Encoding: base64' . "\r\n"; 
    $mail_body .= 'Content-Disposition: attachment; filename="' . $E_filename . '"' . "\r\n\r\n"; 
    $mail_body .= $data_split . "\r\n"; 
    
    //This is needed to stop any rendering errors by email clients and signifies the end of the email's body. 
    $mail_body .= "$new_boundary--"; 
    
    //This mails out all of the above. 
    mail($E_recipients, $E_subject, $mail_body, $mail_header); 
    
    +0

    他正在添加到身體。是的,他不知道這段代碼做了什麼,但是這段代碼將body添加到body中。 –

    +0

    @ Col.Shrapnel不正確 - 他的代碼將一個空字符串傳遞給正文,將整個消息傳遞給標題。 – DaveRandom

    +0

    @DaveRandom嗨Dave,非常感謝您的回答,不幸的是它不起作用,我確信這一切都需要在標題中傳遞,我之前使用過相同的代碼來發送電子郵件附件,唯一的區別是在我的另一個腳本中,這些文件實際上存在於服務器上,就像這裏沒有創建任何文件,信息只是從變量添加到頭部,我認爲這是問題所在。然而,我嘗試了你的代碼,它基本上寫出了標題作爲電子郵件內容,並凍結了我的瀏覽器好1-2分鐘哈哈:D – RobFos