創作內容

59 GP

[達人專欄] 論壇是怎麼架設的?自己動手做做看!(三)

作者:解凍豬腳│2019-08-04 19:43:06│巴幣:1,152│人氣:6109

  前篇:論壇是怎麼架設的?自己動手做做看!(二)

  來講資料庫吧。

  我們通常在 localhost/phpmyadmin(若設在 port 8080 請自己加上去)就可以進入資料庫的管理頁面(請注意,資料庫管理頁面本身是設在網頁的 port 上面,而不是上面講的 3306,資料庫的 port 3306 是讀取的時候才用到的):



  我們可以在左邊看到 information_schema、mysql、performance_schema、phpmyadmin 等等預設的資料庫,而為了保險起見,通常也不會有人去碰它們。點選左邊的「新增」,我們可以自己新增一個給自己網站用的資料庫,你可以取個好記的名字:



  通常為了可以存放多國語言,大部分的網站都會選擇使用 UTF-8 的編碼。點選建立,我們就會新增好一個剛才被我取名為「mywebsite」的資料庫:



  不過,光有資料庫是沒有用的,這就好像我們有了一個房間,卻沒有櫃子可以放紙張一樣,我們在「mywebsite」的資料庫中建立一個叫做「articles」的資料表(自由取名):



  接著我們按照需要的規格來設計資料表吧!如果想要讓文章可以儲存作者的名字、文章的內容,那我們就可以依照需要來設定資料的最大長度,例如我們可以設一個 author 欄位,讓它只能存放 255 個字元,而 content 可以存放 65535 個字。至於上面的 id,則是為了事後可以用來瀏覽文章或方便整理而另外設的主要編號,這個在 SQL 資料庫中,我們通常稱它是「primary key」,有點像是班級裡面的座號一樣,是獨一無二的。

  因為我們要讓編號自動往上遞增,所以我們勾選上面的 A_I(auto increment),通常系統會問你是否要順便把它設為 primary key,選擇「執行」:



  於是我們得到了一個可以用來儲存文章內容的資料表:



  直接用上面的「新增」功能來測試看看吧,id 不需要填,系統會自己幫你編號:


  


  都新增好以後大概就是這樣:



  設好資料庫以後,我們就可以把 index.php 裡面的內容改掉了:

<?php
    $sv_name = 'localhost';
    $username = 'root';
    $password = '';
    $db_name = 'mywebsite';
    $conn = mysqli_connect($sv_name, $username, $password, $db_name);
    mysqli_query($conn, "SET NAMES 'utf8'");
    if(!$conn){
        die('Connection failed.');
    }
?>

<?php
    if(isset($_GET['article']) && is_numeric($_GET['article'])){
        $articleNumber = $_GET['article'];
        $stmt = mysqli_prepare($conn, "SELECT author, content FROM articles WHERE id = ?");
        $stmt->bind_param('i', $_GET['article']);
        mysqli_stmt_execute($stmt);
        mysqli_stmt_bind_result($stmt, $r0, $r1);
        mysqli_stmt_fetch($stmt);
        echo "作者:".$r0;
        echo "<br/>--<br/>";
        echo $r1;
        echo "<br/>";
        if($articleNumber > 1){
?>
            <a href="./index.php?article=<?php echo($articleNumber-1) ?>">上一篇</a><br/>
<?php
        }
        if($articleNumber < 3){
?>
            <a href="./index.php?article=<?php echo($articleNumber+1) ?>">下一篇</a>
<?php
        }
    }
?>

  前面那段就是伺服器名稱、資料庫使用者名稱、資料庫使用者密碼、資料庫名稱等設定,設定好以後連到資料庫,而下半段 prepare ~ fetch 一段才是從資料庫讀資料,通常連線的那段只需要在 PHP 檔案開頭執行一次就可以了。

  因為安裝的時候通常都是以 root 作為使用者名稱(預設沒有密碼),所以密碼欄位留空就行。

  這時候我們可以看到它成功從資料庫讀出文章內容:



  因為本系列談的是概念,所以我不會把 SQL 的「新增、修改、刪除、查詢」四大功能的細節全都講完,只會提供簡單的範例,剩下的細節就只能請各位自己找找囉~網路上有很多種用 PHP 來連接 SQL 資料庫的方法和教學,也各有優缺點,多看不同人的範例也是好事。

  不過!這裡有一點需要注意,將來當你使用 SQL 資料庫,執行語法的時候,請務必使用 prepare/bind 的方式,用含有 "?" 的查詢字串來間接填入參數(如上範例),千萬不可以用下面這種直接串語法的形式:

    $query = "SELECT author, content FROM articles WHERE id = ".$_GET['article'];

  這種方式一般來說會讓駭客有機會利用 SQL injection 的手法,試圖把你資料庫裡其他的東西偷取出來,嚴重者甚至會取得管理員的權限,所以保持良好的習慣、瞭解常見的攻擊手法對於一個工程師來說是很重要的事情。

  當然,這個世界上也不是只有 SQL 資料庫系統,例如 Google 提供的 Firebase 服務就使用了 NoSQL 格式的資料庫,兩者的存取的方式和結構就截然不同了,值得大家去研究一下。

  瞭解了讀取文章以後,我們更可以再另外新增一個 newarticle.php 來設定發文介面:

<form method="POST" action="./newarticle2.php">
    作者:<input name="author111"/><br/>
    文章內容:<br/>
    <textarea name="content111"></textarea>
    <input type="submit" value="送出"/>
</form>

  然後再設一個 newarticle2.php 來處理資料:

<?php
    $sv_name = 'localhost';
    $username = 'root';
    $password = '';
    $db_name = 'mywebsite';
    $conn = mysqli_connect($sv_name, $username, $password, $db_name);
    mysqli_query($conn, "SET NAMES 'utf8'");
    if(!$conn){
        die('Connection failed.');
    }
?>

<?php
    echo $_POST['author111']."<br/>";
    echo $_POST['content111']."<br/>";
    $stmt = mysqli_prepare($conn, "INSERT INTO articles (author, content) VALUES (?, ?)");
    $stmt->bind_param('ss', $_POST['author111'], $_POST['content111']);
    mysqli_stmt_execute($stmt);
    header('Location: ./index.php?article=1');
?>

  這裡特別把名字改成 author111、content111 只是為了要讓初學的你知道誰是誰,把後面加上的 111 全都去掉的話當然也可以。總之,form 裡面的所有 input 都是用來決定之後要向「./newarticle2.php」送出哪些資料,這些 input 標籤的 name 欄位,到了 newarticle2 裡面就要用 $_POST[name] 來取得。

  不過,因為當初文章篇數是寫死的,所以在你成功發表文章以後,還是要去 index.php 上面修改一下 if($articleNumber < 3) 的條件(使用 SELECT max(id) FROM articles 語句可以直接得到最後一篇文章的 id);另外也要把顯示文章的 echo $r1; 處改成 echo nl2br($r1);,因為用網頁送出的文章並不是使用 <br/> 標籤來換行的,這要使用 nl2br() 函式來轉換),畢竟前面的資料只是示範用。

  只要這麼簡單的一些步驟,最基本的發文的功能就做好了,剩下的就是介面的問題而已(雖然說「而已」,但也不是什麼小工程)。其實一個功能齊全的論壇,當然還會有更多的細節,例如標題、刪除文章、插入圖片、要顯示哪個簽名檔等等,甚至是更進階的功能,這些都可以發揮你的想像力,只是當初設定的資料表就要另外再自行設計了。

  沒有錯,我們也可以用 POST 方法,如法炮製出會員的註冊頁面,並且在安全考量下,利用 hash 算法,在把密碼存進去資料庫之前,將密碼轉換成 hash 值(詳見此篇),而登入頁面也是這樣。

  只要懂得操作資料庫,我們就能夠在登入的處理頁面中,用 $_POST 取得使用者傳來的帳號密碼,去比對資料庫是否有同筆資料,有的話就令 $_SESSION['uid'] 為該帳號的 primary key,從此之後只要用 $_SESSION['uid'] 就可以知道連線過來的使用者的登入狀態(即權限),也就等於完成了登入的功能(注意:若需使用 session 功能,必須在每個 PHP 檔案裡的開頭用 PHP 語法執行 session_start();)。

  稍微對 index.php 做一點小優化:

<?php
    $sv_name = 'localhost';
    $username = 'root';
    $password = '';
    $db_name = 'mywebsite';
    $conn = mysqli_connect($sv_name, $username, $password, $db_name);
    mysqli_query($conn, "SET NAMES 'utf8'");
    if(!$conn){
        die('Connection failed.');
    }
?>

<?php
    if(isset($_GET['article']) && is_numeric($_GET['article'])){
        $articleNumber = $_GET['article'];
        $stmt = mysqli_prepare($conn, "SELECT author, content FROM articles WHERE id = ?");
        $stmt->bind_param('i', $_GET['article']); // 因為是整數所以用 i(字串用 s)
        mysqli_stmt_execute($stmt);
        mysqli_stmt_bind_result($stmt, $author, $content);
        mysqli_stmt_fetch($stmt);

        // 把抓到的文章和作者資訊印出來
        echo "作者:".$author;
        echo "<br/>--<br/>";
        echo nl2br($content);
        echo "<br/>";
        $stmt->close();

        // 這裡從資料庫抓編號最大的文章
        $stmt = mysqli_prepare($conn, "SELECT MAX(id) FROM articles");
        mysqli_stmt_execute($stmt);
        mysqli_stmt_bind_result($stmt, $max);
        mysqli_stmt_fetch($stmt);

        // 顯示上一篇或下一篇的連結
        if($articleNumber > 1){
?>
            <a href="./index.php?article=<?php echo($articleNumber-1); ?>">上一篇</a><br/>
<?php
        }
        if($articleNumber < $max){
?>
            <a href="./index.php?article=<?php echo($articleNumber+1); ?>">下一篇</a><br/>
<?php
        }
?>
        <a href="./newarticle.php">發表文章</a>
<?php
    }
?>

  這樣就算是完成基本的「閱讀」跟「發文」功能了。



  前後端的銜接大概就是這樣。只要知道 GET、POST 的傳值方法,懂得使用 SQL 資料庫的 SELECT、INSERT INTO、UPDATE、DELETE 四種基本的操作,然後會運用 SESSION 來紀錄登入狀態,你已經具有完成論壇後端的能力了,因為舉凡發文、回文、註冊、登入、修改個人資料、會員自刪文章……這些功能全都像 newarticle.php 和 newarticle2.php 一樣,一個作為介面、一個作為執行實際操作,然後再讓使用者跳轉到你的目標頁面。

  有了這些說明,想學 PHP 的各位也可以去 Google 上面多查本篇文章裡一些看不懂的關鍵字,有發現不同的 SQL 資料庫存取方式也可以自己試試看,我當初就是這樣修練過來的

  礙於篇幅大小,這系列的介紹就先到這裡,感謝各位的耐心觀看。等我哪天心血來潮(大誤)的時候會再稍微優化一下 code 整個丟上來當範例。看下來發現這篇教學好像有點混亂,如果有看沒有懂的話,請你再把這文章多看幾次,我相信該講的觀念我都有講了,剩下的細節就交給 Google 大神來幫你吧!希望對想學 PHP 的各位有幫助。

  (我現在終於可以理解當初教我們 PHP 的教授是什麼樣的心情

引用網址:https://home.gamer.com.tw/TrackBack.php?sn=4483719
All rights reserved. 版權所有,保留一切權利

相關創作

同標籤作品搜尋:網頁|網站|網頁設計|PHP|HTML|電腦|連線|網路|資料庫|XAMPP

留言共 14 篇留言

乃乃

08-04 19:44

保全之智乃(小熊模式)
上什麼課會教呀

08-04 20:04

解凍豬腳
網頁程式設計08-04 20:06
我喜歡吃飯
雖然看不懂 但是感覺好厲害ㄛ!差點就愛上豬腳了

08-04 20:35

苂釠法師
雖然看不懂,但感覺好猛ㄛ!貧僧差點就要跟豬腳ii了

08-04 20:46

宇宙吃貨胖宅貓
好猛喵

08-04 20:53

young
U質文 先推 要升大一資工菜ㄐ先卡ㄍ

08-04 21:27

MR-acetyl
豬腳你知道為啥巴哈伺服器有時會上不去嗎?跟cloudfare有沒有關係啊 https://truth.bahamut.com.tw/s01/201904/9c6144b981df9245916076dbf9c1324a.JPG?w=300

08-04 22:00

解凍豬腳
這我也不曉得,恐怕只有巴哈那邊才知道了08-05 00:36
cablec
眼花了@@。。。

08-04 22:37

Hans(憨死)
路過
好奇論壇是要講phpBB3的架設嗎?
還是WordPress/Drupal/XOOPS/Joomla!擇一 ?

08-04 23:08

解凍豬腳
我標題下得不好,這系列比較著重原理層面
你講的這些其實都是現成的套件
個人認為這畢竟動動手指按兩下就能建立好
好像也沒有特別拿出來講的必要08-04 23:11
玥晴 Luna (#ΦωΦ#)

08-04 23:13

Raven
補充下,現在沒有人用php從頭刻到尾(學校除外,去年看到新竹某名校的網頁是學生用php刻出來的,然後叫我接手補完......??????),詳細請查laravel,用過你就會覺得前端後端全擠在一起是很智障的一件事

08-05 01:04

解凍豬腳
感謝補充,本系列主要是想講基本的原理,套 MVC 架構這種事情屬於細部的優化,所以就沒有多談了08-05 01:08
雪之王女‧F‧巧可奈
豬腳不當程式設計師太可惜了

08-05 08:51

チョコラネコ
看到上面有人提到後端框架laravel

其實套不套框架,是看需求
有框架通常是為了往團隊協作好維護的方向走
的確laravel摸熟後,後面維護真的很方便,不會有功能和畫面混在一起的狀況

但最近和朋友在搞的小專案,考慮功能和架構後
反而是前端套框架(vue cli,用過vue以後就不會想用jquery了,大推)
後端是用純php寫api,用來處理前端的POST/GET與資料庫的增刪修查

總之用甚麼工具,都是看專案(或是客戶)的需求
不一定聽別人說用某某框架,每個專案都用那框架下去做

話說資料庫存取,可以考慮用看看PDO,對各大DB支援度滿高的
而且有問題找到的資源也比較豐富
(之前有看過文章問mysqli,結果下面最佳回覆說「遇到這問題,我一律推薦改用PDO」,笑死)

然後網頁的坑其實很大很深,學不完
最好的方式就是像這樣,給自己挖一個坑(做個小專案)
過程中,坑就越挖越多了,也能學得更多

(一位下個月要轉職成為後端工程師的菜雞路過

10-24 18:42

解凍豬腳
感謝分享,祝你轉職順利呀~~ [e35]10-24 18:48
傑森五德
笑死 這系列很明顯就是想說明原理
怎麼看下來一堆人在那邊 套件套件 真的快笑死
套件不是小學生點來點去就有的嗎

這文章核心精神才是學習的明燈 就是搞懂原理

02-06 10:18

我要留言提醒:您尚未登入,請先登入再留言

59喜歡★johnny860726 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:一張價值 20 萬的紙... 後一篇:七夕和らい一起逛夜市,遇...

追蹤私訊切換新版閱覽

作品資料夾

------------------ (0)

豬腳生活 (1)
日常雜談、巴哈大小事 (193)
煞氣a國中生 (7)
高中生活日誌 (55)
大學生活日誌 (34)
冬令營回憶錄 (19)
也許藏有一些小祕密吧? (3)
各式各樣的開箱文 (11)
貓科動物時間 (15)

------------------ (0)

繪圖創作 (1)
電繪插圖、草稿 (199)
短篇漫畫、單幅標語 (61)
上課太無聊的手繪塗鴉 (8)
不知道該怎麼分類的綜合作品 (18)

文字創作 (1)
草莓兵的國軍紀實 (14)
我與らい的點點滴滴 (12)
那些榮耀的時刻與心跳加速的瞬間 (60)
有感而發的隨筆之作、無法分類的短文 (17)

------------------ (0)

語言學習 (1)
日語:天気がいいから (5)
粵語:唔好再淨係識講粗口喇 (6)
英語:Hey, you! (1)

程式設計及電腦網路 (1)
系列文:跟著豬腳 C 起來 (10)
系列文:論壇網站運作原理 (3)
Go(Golang) (11)
Ruby / RGSS (7)
Visual Basic (13)
JavaScript (1)
各種原理 (17)

思想:多思考一下,世界會更不一樣 (1)
網路經驗、社會觀察 (23)
檸檬庫 (21)

數學:我來拯救你的期中考了 (1)
各類基礎觀念 (5)
國中生也能懂的微積分 (9)
微分方程 (0)

小說:用筆鋒劃出新世界的入口 (1)

繪圖:我也想畫出私巴拉西的美圖 (10)

------------------ (0)

施工中 (22)

不堪回首的痕跡、雜物堆放 (31)

------------------ (0)

未分類 (1)

Lobster0627全體巴友
大家可以多多來我的YT頻道看看哦(*´∀`)~♥https://www.youtube.com/@lobstersandwich看更多我要大聲說4小時前


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】