# 與資料庫的結合運用
在 PHP 中連結資料庫
all.php | <?php require '../header.php'; ?> |
| |
| <?php |
| $pdo=new PDO('mysql:host=localhost;dbname=shop;charset=utf8', |
| '帳號', '密碼'); |
| ?> |
| |
| <?php require '../footer.php'; ?> |
網頁沒有顯示錯誤訊息就表示連接成功。
# 利用 PDO 連接資料庫
在 PHP 中要連結資料庫,通常使用提供了 PHP 與資料庫間的連線機制的 PDO。
在 PHP 中,可以使用 類別 (Class) 來統整定義相關的變數與函式。
PDO 即是一種類別,裡面包含了操作資料庫時會使用到的變數與函式。
類別中的變數稱為 屬性 (property),類別內的函式稱為 方法 (Method)。
要使用類別之前,一定要產生 instance。
# 產生 PDO 的 instance
用 PHP 顯示 table 中資料
all2.php | <?php require '../header.php'; ?> |
| |
| <?php |
| $pdo=new PDO('mysql:host=localhost;dbname=shop;charset=utf8', |
| 'staff', 'password'); |
| foreach ($pdo->query('select * from product') as $row) { |
| echo '<p>'; |
| echo $row['id'], ':'; |
| echo $row['name'], ':'; |
| echo $row['price']; |
| echo '</p>'; |
| } |
| ?> |
| |
| <?php require '../footer.php'; ?> |
all3.php | <?php require '../header.php'; ?> |
| |
| <?php |
| $pdo=new PDO('mysql:host=localhost;dbname=shop;charset=utf8', |
| 'staff', 'password'); |
| foreach ($pdo->query('select * from product') as $row) { |
| echo "<p>$row[id]:$row[name]:$row[price]</p>"; |
| } |
| ?> |
| |
| <?php require '../footer.php'; ?> |
以雙引號框住的字串,具有可在字串之中插入變數值的功能。
# 執行 SQL 指令
變數 PDO 名字是 $pdo
呼叫方法的程式寫法為 (變數 -> 方法 )
# 取得資料欄內的資料
利用 foreach 迴圈,就可將資料逐筆處理。
用 PHP 顯示 Table 中資料
all4.php | <?php require '../header.php'; ?> |
| |
| <table> |
| <tr><th>商品編號</th><th>商品名稱</th><th>商品價格</th></tr> |
| |
| <?php |
| $pdo=new PDO('mysql:host=localhost;dbname=pratice;charset=utf8', |
| '帳號', '密碼'); |
| foreach ($pdo->query('select * from person') as $row) { |
| echo "<tr><td>$row[person_id]</td><td>$row[person_name]</td><td>$row[person_birth]</td></tr>"; |
| echo "\n"; |
| } |
| ?> |
| |
| </table> |
| |
| <?php require '../footer.php'; ?> |
以雙引號框住的字串,具有可在字串之中插入變數值的功能。
all5.php | <?php require '../header.php'; ?> |
| |
| <table> |
| <tr><th>商品編號</th><th>商品名稱</th><th>商品價格</th></tr> |
| |
| <?php |
| $pdo=new PDO('mysql:host=localhost;dbname=shop;charset=utf8', |
| 'staff', 'password'); |
| foreach ($pdo->query('select * from product') as $row) { |
| echo '<tr>'; |
| echo '<td>', htmlspecialchars($row['id']), '</td>'; |
| echo '<td>', htmlspecialchars($row['name']), '</td>'; |
| echo '<td>', htmlspecialchars($row['price']), '</td>'; |
| echo '</tr>'; |
| echo "\n"; |
| } |
| ?> |
| |
| </table> |
| |
| <?php require '../footer.php'; ?> |
資料中若有可能包含在 HTML 中有特殊意義的字,顯示前應先經 htmlspecialchars 函式處理。
# 函式的定義
PHP 不僅提供了許多現成的函式,程式設計師也可自行撰寫需要的函式。
| function 函式名稱(傳入參數, ...){ |
| 執行的處理; |
| ... |
| return 回傳值; |
| } |
# 資料的搜尋
用欄位中的名稱搜尋資料
search-input.php | <?php require '../header.php'; ?> |
| |
| 請輸入商品名稱: |
| <form action="search-output.php" method="post"> |
| <input type="text" name="keyword"> |
| <input type="submit" value="搜尋"> |
| </form> |
| |
| <?php require '../footer.php'; ?> |
search-output.php | <?php require '../header.php'; ?> |
| |
| <table> |
| <tr><th>商品編號</th><th>商品名稱</th><th>商品價格</th></tr> |
| |
| <?php |
| $pdo=new PDO('mysql:host=localhost;dbname=shop;charset=utf8', |
| 'staff', 'password'); |
| $sql=$pdo->prepare('select * from product where name=?'); |
| $sql->execute([$_REQUEST['keyword']]); |
| foreach ($sql->fetchAll() as $row) { |
| echo '<tr>'; |
| echo '<td>', $row['id'], '</td>'; |
| echo '<td>', $row['name'], '</td>'; |
| echo '<td>', $row['price'], '</td>'; |
| echo '</tr>'; |
| echo "\n"; |
| } |
| ?> |
| |
| </table> |
| |
| <?php require '../footer.php'; ?> |
# where
在 SQL 的 select 敘述中,用來指定搜尋條件,在他之後直接寫出條件式。
可以用?來代替之後才要代入的值。
| select * from product where 資料欄名稱 =? |
# prepare
是用來進行 SQL 指令執行前的準備。
prepare 方法在執行後,會回傳已設定好 SQL 指令的 PDOStatement 實例。
這個實例在之後執行 SQL 指令時還是會用到,因此要先將它指定給變數。
| $sql=$pdo->prepare('select * from product where name=?'); |
# execute
要執行以傳入參數傳入 prepare 方法的 SQL 指令,必須利用 PHP 內建的 PDOStatement 類別的 execute 方法。
若指令中有多個 (?) 時,可以用 ( , ) 分隔多值。
| [$_REQUEST['first_keyword'], $_REQUEST['second_keywork']] |
利用 prepare 方法預處理好 SQL 指令,要利用 execute 方法執行。
# fetchAll
利用 execute 方法執行 SQL 指令後,可再利用 PDOStatement 類別的 fetchAll 方法取的執行結果。
| foreach(PDO的變數->fetchAll() as 要將取的結果代入的變數) |
| foreach ($sql->fetchAll() as $row) { |
# like
搜尋部分符合的商品
| select * from product where name like ?; |
? => %word%
指就算 word 前後有其他字也符合條件
| $sql=$pdo->prepare('select * from product where name like ?'); |
| $sql->execute(['%'.$_REQUEST['keyword'].'%']); |
# not like
找出不含搜尋關鍵字的資訊
| select * from product where name not like ?; |
# like and not like
| select * from product where name like ? and name not like ?; |
# 在資料表內新增資料
insert-input.php | <?php require '../header.php'; ?> |
| |
| <p>資料新增:</p> |
| <form action="insert-output.php" method="post"> |
| 商品名稱<input type="text" name="name"> |
| 價格<input type="text" name="price"> |
| <input type="submit" value="確定新增"> |
| </form> |
| |
| <?php require '../footer.php'; ?> |
insert-output.php | <?php require '../header.php'; ?> |
| |
| <?php |
| $pdo=new PDO('mysql:host=localhost;dbname=shop;charset=utf8', |
| 'staff', 'password'); |
| $sql=$pdo->prepare('insert into product values(null, ?, ?)'); |
| if ($sql->execute([$_REQUEST['name'], $_REQUEST['price']])) { |
| echo '新增成功。'; |
| } else { |
| echo '新增失敗。'; |
| } |
| ?> |
| |
| <?php require '../footer.php'; ?> |
insert-output2.php | <?php require '../header.php'; ?> |
| |
| <?php |
| $pdo=new PDO('mysql:host=localhost;dbname=shop;charset=utf8', |
| 'staff', 'password'); |
| $sql=$pdo->prepare('insert into product values(null, ?, ?)'); |
| if (empty($_REQUEST['name'])) { |
| echo '請輸入商品名稱。'; |
| } else if (!preg_match('/[0-9]+/', $_REQUEST['price'])) { |
| echo '請以整數輸入商品價格。'; |
| } else |
| if ($sql->execute( |
| [htmlspecialchars($_REQUEST['name']), $_REQUEST['price']] |
| )) { |
| echo '新增成功。'; |
| } else { |
| echo '新增失敗。'; |
| } |
| ?> |
| |
| <?php require '../footer.php'; ?> |
# empty
在值為空時,回傳 TRUE。
# 資料隱碼攻擊 (SQL injection)
說到要預防資料庫存入有問題的資料,就必須提到 資料隱碼攻擊 (SQL injection)。
資料隱碼攻擊 是指系統執行了非開發者撰寫的 SQL 指令,導致資料庫被非法存取的問題。
# 修改資料庫資料
update-input.php | <?php require '../header.php'; ?> |
| |
| <table> |
| <tr><th>商品編號</th><th>商品名稱</th><th>商品價格</th></tr> |
| |
| <?php |
| $pdo=new PDO( |
| 'mysql:host=localhost;dbname=shop;charset=utf8', 'staff', 'password' |
| ); |
| foreach ($pdo->query('select * from product') as $row) { |
| echo '<tr><form action="update-output.php" method="post">'; |
| echo '<input type="hidden" name="id" value="', $row['id'], '">'; |
| echo '<td>', $row['id'], '</td>'; |
| echo '<td>'; |
| echo '<input type="text" name="name" value="', $row['name'], '">'; |
| echo '</td>'; |
| echo '<td>'; |
| echo '<input type="text" name="price" value="', $row['price'], '">'; |
| echo '</td>'; |
| echo '<td><input type="submit" value="確定修改"></td>'; |
| echo '</form></tr>'; |
| echo "\n"; |
| } |
| ?> |
| |
| </table> |
| |
| <?php require '../footer.php'; ?> |
update-output.php | <?php require '../header.php'; ?> |
| |
| <?php |
| $pdo=new PDO('mysql:host=localhost;dbname=shop;charset=utf8', |
| 'staff', 'password'); |
| $sql=$pdo->prepare('update product set name=?, price=? where id=?'); |
| if (empty($_REQUEST['name'])) { |
| echo '請輸入商品名稱。'; |
| } else |
| if (!preg_match('/[0-9]+/', $_REQUEST['price'])) { |
| echo '請以整數輸入商品價格。'; |
| } else |
| if ($sql->execute( |
| [htmlspecialchars($_REQUEST['name']), |
| $_REQUEST['price'], $_REQUEST['id']] |
| )) { |
| echo '修改成功。'; |
| } else { |
| echo '修改失敗。'; |
| } |
| ?> |
| |
| <?php require '../footer.php'; ?> |
# 刪除資料庫資料
delete-input.php | <?php require '../header.php'; ?> |
| |
| <table> |
| <tr><th>商品編號</th><th>商品名稱</th><th>商品價格</th></tr> |
| |
| <?php |
| $pdo=new PDO('mysql:host=localhost;dbname=shop;charset=utf8', |
| 'staff', 'password'); |
| foreach ($pdo->query('select * from product') as $row) { |
| echo '<tr>'; |
| echo '<td>', $row['id'], '</td>'; |
| echo '<td>', $row['name'], '</td>'; |
| echo '<td>', $row['price'], '</td>'; |
| echo '<td>'; |
| echo '<a href="delete-output.php?id=', $row['id'], '">確定刪除</a>'; |
| echo '</td>'; |
| echo '</tr>'; |
| echo "\n"; |
| } |
| ?> |
| |
| </table> |
| |
| <?php require '../footer.php'; ?> |
delete-output.php | <?php require '../header.php'; ?> |
| |
| <?php |
| $pdo=new PDO('mysql:host=localhost;dbname=shop;charset=utf8', |
| 'staff', 'password'); |
| $sql=$pdo->prepare('delete from product where id=?'); |
| if ($sql->execute([$_REQUEST['id']])) { |
| echo '刪除成功。'; |
| } else { |
| echo '刪除失敗。'; |
| } |
| ?> |
| |
| <?php require '../footer.php'; ?> |
# 含有 REQUEST 參數的連結
| 要開啟的檔案名稱?REQUEST參數名=值 & REQUEST參數名=值 &... |
| echo '<a href="delete-output.php?id=', $row['id'], '">確定刪除</a>'; |
# 整合新增、修改、刪除
edit3.php | <?php require '../header.php'; ?> |
| |
| <table> |
| <tr><th>商品編號</th><th>商品名稱</th><th>價格</th></tr> |
| |
| <?php |
| $pdo=new PDO('mysql:host=localhost;dbname=shop;charset=utf8', |
| 'staff', 'password'); |
| if (isset($_REQUEST['command'])) { |
| switch ($_REQUEST['command']) { |
| case 'insert': |
| if (empty($_REQUEST['name']) || |
| !preg_match('/[0-9]+/', $_REQUEST['price'])) break; |
| $sql=$pdo->prepare('insert into product values(null,?,?)'); |
| $sql->execute( |
| [htmlspecialchars($_REQUEST['name']), $_REQUEST['price']]); |
| break; |
| case 'update': |
| if (empty($_REQUEST['name']) || |
| !preg_match('/[0-9]+/', $_REQUEST['price'])) break; |
| $sql=$pdo->prepare( |
| 'update product set name=?, price=? where id=?'); |
| $sql->execute( |
| [htmlspecialchars($_REQUEST['name']), $_REQUEST['price'], |
| $_REQUEST['id']]); |
| break; |
| case 'delete': |
| $sql=$pdo->prepare('delete from product where id=?'); |
| $sql->execute([$_REQUEST['id']]); |
| break; |
| } |
| } |
| foreach ($pdo->query('select * from product') as $row) { |
| echo '<tr>'; |
| echo '<form action="edit3.php" method="post">'; |
| echo '<input type="hidden" name="command" value="update">'; |
| echo '<input type="hidden" name="id" value="', $row['id'], '">'; |
| echo '<td>', $row['id'], '</td>'; |
| echo '<td>'; |
| echo '<input type="text" name="name" value="', $row['name'], '">'; |
| echo '</td>'; |
| echo '<td>'; |
| echo '<input type="text" name="price" value="', $row['price'], '">'; |
| echo '</td>'; |
| echo '<td><input type="submit" value="確定修改"></td>'; |
| echo '</form>'; |
| echo '<form action="edit3.php" method="post">'; |
| echo '<input type="hidden" name="command" value="delete">'; |
| echo '<input type="hidden" name="id" value="', $row['id'], '">'; |
| echo '<td><input type="submit" value="確定刪除"></td>'; |
| echo '</form>'; |
| echo '</tr>'; |
| echo "\n"; |
| } |
| ?> |
| |
| <tr> |
| <form action="edit3.php" method="post"> |
| <input type="hidden" name="command" value="insert"> |
| <td></td> |
| <td><input type="text" name="name"></td> |
| <td><input type="text" name="price"></td> |
| <td><input type="submit" value="確定新增"></td> |
| </form> |
| </tr> |
| </table> |
| |
| <?php require '../footer.php'; ?> |
# 實用的 PHP 程式 - 以購物網站為例
# Session
是在網頁應用程式中用來放置各使用者資料的機制。
利用 Session 機制,就能管理每個使用者的個別資料。
在 PHP 中,可透過 $_SESSION 陣列存取 Session 資料。
# 網站上線的實務知識
# 限制錯誤訊息的顯示
級別
常數 | 意義 |
---|
0 | 隱藏所有錯誤訊息 |
E_ERROR | 出現重大的執行錯誤時,中斷程式的執行 |
E_WARNING | 執行時出現的警告不會中斷程式的執行 |
E_PARSE | 解釋程式時出現錯誤。會在語法錯誤時發生 |
E_NOTICE | 執行時出現注意。會在懷疑程式可能有誤發生時 |
E_ALL | 顯示所有錯誤訊息 |
# 利用框架 (Framework)
框架 (Framework) 與函式庫一樣,都是用來支援應用程式開發的軟體。
但是框架提供的不是好用的函式與類別,而且用來規範應用程式的技術方式。
框架並不是用來提供應用程式會用到的部分功能,而是用來提供建構應用程式的整體框架。
因此和函式庫一樣,若能善用框架,就能在短時間開發出功能更好的應用程式。
此外,在多人同時開發應用程式時,利用框架就能統一應用程式的技術方式。
可以讓開發團隊更容易共享資訊,提高開發效率。
Laravel
https://laravel.com/