前端JS使用AJAX將訂單資料送至伺服器後端PHP並用mail送出訂單
註:原本這裏的學習,我打算用WordPress的ajax來送資料到後端,還沒整個測試完,因此,底下使用之前在月曆裏用的ajax方法 (參考:Part 9 使用AJAX方法將色彩名稱傳到後端並寫入資料庫)。
第一步:將購物車的資料送到後端PHP
在hedaer.php中加入二個JavaScript函式(ajax與objectToString),整個購物車的送出按鈕的Java Script:<script> function ajax(object){ var request = new XMLHttpRequest(); request.open("POST", "index.php"); request.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); request.send( objectToString(object)); } function objectToString(object){ let str = ""; Object.keys(object).forEach(function(key){ str += key; str += `=${object[key]}&`; //``模板字符串 }); console.log(str); return str; } function submitOrder() { let currentUserName = "", userEMail=""; <?php global $current_user; wp_get_current_user(); if ( is_user_logged_in() ) { //如果WordPress使用者有登入的話 echo "currentUserName = ".'"'.$current_user->display_name.'";'."\r\n"; echo "userEMail = ".'"'.$current_user->user_email.'";'."\r\n"; } ?> let cartObject = shoppingCart.listCart(); //取得購物車項目物件 ajax( {order_data : JSON.stringify(cartObject)}); jQuery('#cart').modal('hide'); //關閉對話方塊 jQuery('.clear-cart').click(); //清空購物車 } </script>ajax函式是先將一個JSON物件(key:value)以objectToString函式轉換成key=value的字串形式,使用XMLHttpRequest類別送出資料到後端,至於後端送給誰,敘述 request.open("POST", "index.php");指定資料送給index.php(這個檔案是整個WordPress的首頁檔,包括header.php與footer.php),因此,我們把一些有的沒的都寫在header.php(這樣其實很不好…,只是為了簡單,我們先這樣做,以後再來改。) 我們在header.php的末端加入接收資料的處理程式(php):
<?php function processOrder(){ //我們為了觀察資料,我們將過程與資料寫在order_data.txt檔,這個檔案在主題根目錄上 $data = fopen( get_stylesheet_directory()."/order_data.txt", "w"); $order_data = stripslashes ($_POST['order_data'] ); fwrite($data, $order_data); fclose($data); } if (isset($_POST['order_data'])) processOrder(); ?>整個修改過的header.php (只列出從我們加上的script開始)
<script> function ajax(object){ var request = new XMLHttpRequest(); request.open("POST", "index.php"); request.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); request.send( objectToString(object)); } function objectToString(object){ let str = ""; Object.keys(object).forEach(function(key){ str += key; str += `=${object[key]}&`; //``模板字符串 }); console.log(str); return str; } function submitOrder() { let currentUserName = "", userEMail=""; <?php global $current_user; wp_get_current_user(); if ( is_user_logged_in() ) { //如果WordPress使用者有登入的話 echo "currentUserName = ".'"'.$current_user->display_name.'";'."\r\n"; echo "userEMail = ".'"'.$current_user->user_email.'";'."\r\n"; } ?> let cartObject = shoppingCart.listCart(); //取得購物車項目物件 ajax( {order_data : JSON.stringify(cartObject)}); jQuery('#cart').modal('hide'); //關閉對話方塊 jQuery('.clear-cart').click(); //清空購物車 } </script> <?php function processOrder(){ //我們為了觀察資料,我們將過程與資料寫在order_data.txt檔,這個檔案在主題根目錄上 $data = fopen( get_stylesheet_directory()."/order_data.txt", "w"); $order_data = stripslashes ($_POST['order_data'] ); fwrite($data, $order_data); fclose($data); } if (isset($_POST['order_data'])) processOrder(); ?>打開order_data.txt,內容:(例,不會跟我列出來的一模一樣)
[{"name":"黑糖珍珠奶茶","price":60,"count":3,"total":"180.00"},{"name":"仙草凍奶茶","price":65,"count":3,"total":"195.00"},{"name":"抹茶珍珠奶茶","price":70,"count":3,"total":"210.00"}]這是一個陣列的形式,裏面是三個JSON物件,每一個物件是訂單中的一個項目。接來下的工作,我們要用PHP把所有的訂單項目物件抓出來,並擷取出其中的欄位與資料。
第二步:後端PHP將收到的JSON物件陣列的訂單資料轉換成PHP的關聯陣列的陣列
修改processOrder.php<?php function processOrder(){ //我們為了觀察資料,我們將過程與資料寫在order_data.txt檔,這個檔案在主題根目錄上 $data = fopen( get_stylesheet_directory()."/order_data.txt", "w"); //開啟檔案,以寫入的方式 $order_data = stripslashes($_POST['order_data'] ); //從前端取得資料,並消去字串中的\符號 fwrite($data, "原始的資料:".$order_data.PHP_EOL); //寫入資料到檔案中… $cart = json_decode($order_data, true); //將前端傳來的JSON物件陣列轉換成PHP的陣列形式… $i = 1; foreach ($cart as $item) { fwrite($data, "第".$i."筆 ".$item["name"]." ".$item["price"]." ".$item["count"]." ".$item["total"].PHP_EOL); $i++; } fclose($data); //關閉檔案 } if (isset($_POST['order_data'])) processOrder(); ?>打開order_data.txt,內容:(例,不會跟我列出來的一模一樣)
原始的資料:[{"name":"黑糖珍珠奶茶","price":60,"count":3,"total":"180.00"},{"name":"仙草凍奶茶","price":65,"count":3,"total":"195.00"},{"name":"抹茶珍珠奶茶","price":70,"count":3,"total":"210.00"}] 第1筆 黑糖珍珠奶茶 60 3 180.00 第2筆 仙草凍奶茶 65 3 195.00 第3筆 抹茶珍珠奶茶 70 3 210.00後端PHP能夠收到前端JS送來的資料後,並且能夠轉換JSON物件成PHP能夠處理的資料後,後端PHP就能夠將資料進行下一步的處理:
- 使用檔案函式,將資料寫在後端的磁碟空間上。(像上面的order_data.txt)
- 使用PHP的郵件函式將資料透過郵件伺服器送出。
- 使用PHP的MySQL函式或Wordpress $wpdb物件,將資料寫入MySQL資料庫。
注意:在寫PHP時,若出錯,不知道問題在那,我們必須打wp-config.php,找到底下這個設定:
define( 'WP_DEBUG', false );將上面的false改成true,當PHP碼出錯時,瀏覽器會印出錯誤訊息,透過這些訊息,我們才能夠快速地找出錯誤在那。
第三步:PHP將訂單利用mail送至訂單收件者
<?php function processOrder(){ global $current_user; wp_get_current_user(); //我們為了觀察資料,我們將過程與資料寫在order_data.txt檔,這個檔案在主題根目錄上 $data = fopen( get_stylesheet_directory()."/order_data.txt", "w"); $order_data = stripslashes ($_POST['order_data'] ); fwrite($data, $order_data.PHP_EOL); $order_data_php = json_decode( $order_data, true ); $i = 1; $orderAmount = 0; $orderBody = '<table id="customers" style="width:600px;">'.PHP_EOL; $orderBody .= '<tr><td colspan="5"><h2 style="text-align:center;">新訂單明細</h2></td></tr>'.PHP_EOL; $orderBody .= '<tr><th>No.</th><th style="text-align:left;">商品名稱</th>'. '<th style="text-align:right;">單價</th>'. '<th style="text-align:right;">數量</th>'. '<th style="text-align:right;">小計(元)</th></tr>'.PHP_EOL; foreach ($order_data_php as $item) { $orderBody .= '<tr>'.PHP_EOL; $orderBody .= '<td style="text-align:center;">'.$i.'</td>'.PHP_EOL; $orderBody .= '<td style="text-align:ledt;">'.$item["name"].'</td>'.PHP_EOL; $orderBody .= '<td style="text-align:right;">'.$item["price"].'</td>'.PHP_EOL; $orderBody .= '<td style="text-align:right;">'.$item["count"].'</td>'.PHP_EOL; $orderBody .= '<td style="text-align:right;">'.$item["total"].'</td>'.PHP_EOL; $orderBody .= '</tr>'.PHP_EOL; $orderAmount += $item["total"]; $i++; } $orderBody .= '<tr><td colspan="4" style="text-align:right;">本次訂單總金額</td><td style="text-align:right;">'.$orderAmount.'</td></tr>'.PHP_EOL; $orderBody .= '<tr><td colspan="4" style="text-align:right;">訂購者</td><td style="text-align:right;">'.$current_user->display_name.'</td></tr>'.PHP_EOL; $orderBody .= '</table>'.PHP_EOL; //將資料寫入order_data.txt,方便觀察 fwrite($data, $orderBody); //以mail傳送訂單至訂單收件者 $to ='fgchen@gmail.com'; //收件者,這個郵箱務必改成你自己的郵箱 $subject = '新訂單'; //信件標題 //內文是HTML的郵件,必須要設置Content-type $headers = 'MIME-Version: 1.0' .PHP_EOL; $headers .= 'Content-type: text/html; charset=UTF-8'.PHP_EOL; $headers .= 'From: Order man<u1085100@u1085100.stu.fgchen.com>'.PHP_EOL; // 特別注意:寄送郵件時,收件者的郵件主機若有強制DKIM或SPF機制(DMARC政策), // 像是gmail,會檢查傳送郵件主機的域名跟你的發郵件時的收件者(From:)裏的主機名稱進行比對。 // 因此,在我們的主機上(虛擬主機),一定要用給你的虛擬主機域名xxxx.stu.fgchen.com,若不一樣, // gmail會拒絕接收郵件(DMARC政策,防詐騙機制)。舉例來說,你把From…改成: // $headers .= 'From: Name<Name@yahoo.com.tw>'.'\r\n'; // Gmail檢查yahoo.com.tw跟你發送主機的域名不一樣時,Gmail就會拒收你的信!!! if( mail($to, $subject, $orderBody, $headers) ) //發送郵件 fwrite($data, "信件發送成功"); //寄信成功就會顯示的提示訊息 else fwrite($data, "信件發送失敗"); //寄信失敗顯示的錯誤訊息 fclose($data); } if (isset($_POST['order_data'])) processOrder(); ?>這邊,$orderBody是我們訂單內容,我們用HTML的table來進行內容的格式輸出,因為,在gmail中,是用Web的形式,我們用HTML來格式我們的輸出。我們從order_data.txt取出$orderBody,內容是:
<table id="customers" style="width:600px;"> <tr><td colspan="5"><h2 style="text-align:center;">新訂單明細</h2></td></tr> <tr><th>No.</th><th style="text-align:left;">商品名稱</th><th style="text-align:right;">單價</th><th style="text-align:right;">數量</th><th style="text-align:right;">小計(元)</th></tr> <tr> <td style="text-align:center;">1</td> <td style="text-align:ledt;">黑糖珍珠奶茶</td> <td style="text-align:right;">60</td> <td style="text-align:right;">1</td> <td style="text-align:right;">60.00</td> </tr> <tr> <td style="text-align:center;">2</td> <td style="text-align:ledt;">仙草凍奶茶</td> <td style="text-align:right;">65</td> <td style="text-align:right;">1</td> <td style="text-align:right;">65.00</td> </tr> <tr> <td style="text-align:center;">3</td> <td style="text-align:ledt;">黑白珍珠奶茶</td> <td style="text-align:right;">70</td> <td style="text-align:right;">1</td> <td style="text-align:right;">70.00</td> </tr> <tr><td colspan="4" style="text-align:right;">本次訂單總金額</td><td style="text-align:right;">195</td></tr> <tr><td colspan="4" style="text-align:right;">訂購者</td><td style="text-align:right;">WDA1100</td></tr> </table>從前端送出訂單,我們到郵箱找我們的郵件: 程式都大同小異,JavaScript與PHP字串操作很像,只是JavaScript字串串接是用"+",PHP則是用".",程式背後的邏輯都一樣,程式語言都類似, 都是"英文"語系,網頁/網站程式設計很複雜,多看多寫多想,多看同學同好討論。 全端網頁程式設計,前端是HTML+JavaScript,後端是PHP,PHP的工作是處理後端Server能夠提供的服務:檔案、郵件、資料庫,想像JS是一個人,PHP也是一個人,一個負責前線,一個負責後勤,前端是客服,後端是行政支援,前端負責收集客戶資料、意見等,後端負責把資料記錄起來(或使用郵件系統將資料寄出),後端負責大數據分析,將結果資料交給前端進行視覺化的呈現…。