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
並新增一筆資料:(id永遠是1,cur_theme則是我們的色彩名稱,初始值為black)
名稱只是參考,可以自己命名,但是記得程式裏的相關名稱要一致!
實作步驟二:資料傳送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結束。
我們先在前端JavaScript段先用一行程式碼來測試是不是能夠用程式碼方式將一個特定色彩名稱傳到後端,並將資料庫裏的theme資料表裏的資料列id為1的cur_theme變更掉。
<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色彩名稱。