Part 9 使用AJAX方法將色彩名稱傳到後端並寫入資料庫
本文改寫自舊文章:建立一個專業級線上行事曆 – Part 9 將資料從前端寫入後端資料庫 – 加上PHP與MySQL
在一個網頁應用式中,有些資料必須儲存起來,以便在不同的狀況時,回復先前的資料。目前我們的月曆應用程式,已經可以透過色彩選擇對話方塊來設定整個應用程式的色彩,只是這個應用程式尚完成網頁重新載入後回復色彩資料。
基本上,HTTP可以讓二個網頁(同一個網頁也可以傳給自己資料)傳遞資料有二種方法:GET和POST,GET就像下面的URL,可以看到資料是一組”key=value”方式送到另一個網頁,若是有二組資料,資料間則是用”&”進行串接。 http://www.example.com/action.php?name=john&age=24,這個大家在學習PHP時,可以透過$_GET關聯陣列$_GET['name'], $_GET['age']取得name與age這二個key的值:jhon與24。(大家若忘了,把PHP這個部份拿出來複習一下。)
要完成色彩在網頁重新載入後回復之前選擇的色彩,作法(邏輯)是:
Part I 更新色彩名稱在後端資料庫 (update)
- 使用GET或POS方法將色彩名稱傳至後端程式,可能的程式語言是:
- PHP,伺服器平台是Linux,使用Apache網頁伺服器加PHP引擎模組,在我提供學生的虛擬主機帳號,即是這樣的環境。如果沒有虛擬主機帳號,想要練習程式或是在使用Windows作業系統當成伺服器,可以安裝XAMPP或WAMP懶人包,一鍵完成需要的網頁應用程式環境 (localhost)。
- C#,是微軟所提供的.Net環境使用的程式語言,其運行環境是微軟Windows的網頁伺服器,.Net是目前網頁應用程式開發的另一個重要平台。
- Node.js,近年來使用JavaScript提供後端執行環境,其特點是程式語言使用JavaScript,其繼承JavaScript的優異特性,逐漸有不少的開發者使用。
- 後端程式取得色彩名稱
- 後端程式將色彩名稱透過SQL更新至資料庫(MySQL、SQL Server等其他資料庫管理系統DBMS)
Part II 從資料庫讀取色彩名稱到前端 (Read)
- 使用PHP程式撰寫函式查詢資料庫表格裏的資料
- 在前端嵌入該函式的呼叫,並將回傳值以echo的方式將色彩名稱嵌入前端網頁程式碼中。
- 將色彩名稱指定給目前色彩變數
- 網頁如果要內嵌PHP程式碼的話,網頁檔案的副檔名必須是php、php3...,後端網頁伺服器才會將這個檔案先丟給PHP引擎處理,否則的話,只會當成一般html網頁,PHP程式不會被執行。
- 我們要建立一個資料庫與資料表格,並且在該資料表格建立一筆色彩資料,以便之後我們用來將變更的色彩資料儲存(更新)起來。
- 我們這邊使用底下的資源來實現:
- 網頁伺服器,Apache web server + PHP module
- 資料庫管理系統,MySQL
實作步驟一:資料儲存
使用phpMyAdmin來建立一個資料庫及資料庫的使用者(給予全部的權限),並在這個資料庫上建立一個表格(有虛擬主機帳號的同學請至虛擬主機後台)。- 資料庫名稱:as you wish
- 資料庫使用者:as you wish
- 資料表格名稱:theme
實作步驟二:資料傳送AJAX函式與前端JavaScript程式
要從前端送或收資料,我們必須透過XMLHttpRequest 這個物件,此物件有一個很炫的名字叫ajax,第1個a點出這個物件最具代表性的特色:Asynchronous/非同步,非同步的意思是:前後端在交換資料時不需要彼此互相”等待”,一方需要資料時,告訴另一方,然後,轉頭做自己的事,另一方資料送到時,會被通知資料到了…。 這個月曆程式的資料更新邏輯,在個別資料(色彩與記事資料)變動時,資料由前端透過XMLHttpRequest送到後端,由後端的php程式處理。 新增js/ajax.js,這支程式是前端與後端的資料橋樑: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; }註:模版字符串(template literals,backtick 反引號,跟單引號不同)可以讓我們將變成或敘述插入在字串中。上面式子的等效傳統寫法 str += '=' + object[key] + '&'; 我們在前端JavaScript程式中呼叫ajax(object)這個方法,我們將更新資料需求包裝在object物件裏,objectToString這個方法會將object這個物件的key與value值一個一個抓出來,組成key1=value1&key2&vaule2&...字串,再把這個字串送到後端處理。
實作步驟三:PHP程式碼
<?php $connection = mysqli_connect("localhost", "user", "password", "databaseName"); //連線資料庫 if(!$connection){ //如果連線失敗 die("There was an error connecting to the database."); //網頁宣告到此die,並在網頁輸出… } function db_updateTheme($newTheme){ global $connection; $query = "UPDATE theme SET cur_theme = '$newTheme' WHERE id = 1"; //更新theme資料表格中,id欄位值為1的資料列中的cur_theme欄位值為$newTheme $result = mysqli_query($connection, $query); //送出SQL查詢 if(!$result){ //查詢失敗的話… die("Query failed: " . mysqli_error($connection)); } } if(isset($_POST['color'])){ //透過關聯陣列$_POST['color']取得傳送過來的color資料 db_updateTheme($_POST['color']); //呼叫db_updateTheme方法 } ?>ajax方法裏 request.open(“POST”, “index.php”); 這個敘述係利用POST方法來叫用index.php(接收資料的PHP碼所在的檔案),因此,在index.php裏加上取得資料的PHP程式碼,當透過ajax方法使用POST方法傳送color資料時,呼叫db_updateTheme方法更新theme表格中的color欄位 (id固定為1,因為整個月曆應用程式只有一筆色彩資料。) 此段程式流程:
- mysqli_connect方法連接資料庫,四個參數:localhost、使用者名稱(授權的資料庫使用者)、密碼、資料庫名稱
- if(!$connection),如果連結資料庫失敗(帳密錯誤、網路斷線…),使用die函式結束。
- if(isset($_POST[‘color’])),判斷是否透過http的POST方法傳進來color資料,是的話呼叫db_updateTheme($_POST[‘color’]);
- db_updateTheme函式將色彩代碼資料更新至資料表格theme中(指定id值為1的資料列),若執行sql查詢失敗的話,則使用die結束。
<script src="js/updateData.js"></script> <script src="js/changeTheme.js"></script> <script src="js/ajax.js"></script> <script language="JavaScript"> (略) ajax({color: 'pink'}); </script>更新網頁,然後檢視資料庫是否資料成功變更(cur_theme==>'pink')。
實作步驟四:選取色彩後。將色彩名稱更新到資料表
測試成功後,請把 ajax({color: 'pink'}); 這行程式拿掉,然後在changeTheme.js中的changeColor加上:function changeColor(){ //將currentColor.name更新到資料庫 ajax({color:currentColor.name}); (以上略)此時,測試選取色彩,然後觀察資料是否變更。
實作步驟五:撰寫PHP函式讀取cur_theme欄位資料並回傳
當資料已經能夠寫入資料表後,我們就要在網頁載入時讀取資料表中的色彩名稱。在index.php加入一段php碼:function setTheme(){ global $connection; $query = "SELECT * FROM theme"; $result = mysqli_query($connection, $query); if(!$result){ die("Something went wrong...`"); } while($row = mysqli_fetch_assoc($result)){ return $row['cur_theme']; } }這個函式會執行SQL敘述,查詢theme表格中資料列,由於資料表只有一列,所以while迴圈只會執行一次,透過return的方式回傳cur_theme欄位所記錄的色彩名稱。
實作步驟六:網頁載入讀取資料表裏的色彩名稱
<script> currentColor.name = <?php echo( json_encode( setTheme() )); ?> ; //json_encode將回傳的資料包裝成JSON編碼字串,然後指定給currentColor.name var today = new Date(); var thisMonth = today.getMonth(); console.log(thisMonth); var thisYear = today.getFullYear(); console.log(thisYear); updateDate(); fillInMonth(); </script>程式碼一開始就透過呼叫setTheme函式取得儲存在資料庫上的色彩名稱,這個函式是用PHP寫的,然後在JavaScript中用嵌入一段PHP碼來呼叫,透過echo印出色彩名稱字串,透過指定方式把色彩名稱指定給currentColor.name,之後在fillInMonth裏就會呼叫changeColor函式把預設的藍色畫面換成儲存在資料庫裏的cur_theme色彩名稱。 範例打包檔