網路程式設計

資料庫存取#1

Practice #3

  • 加入新增一筆資料的功能

 

20 minutes to go

資料庫

資料庫連線

中文issue

新增 INSERT INTO

查詢 SELECT...FROM

修改 UPDATE

刪除 DELETE

查詢

SELECT "欄位名" FROM "表格名";
  • 基本查詢

欄位名

表格名

查詢

SELECT * FROM survey;
SELECT name, mail FROM survey;
  • SQL語法 
$sql = "SELECT * FROM survey";    // SQL字串
$result = mysql_query($sql);      // 查詢
  • 轉換成php
  • 查詢結果 $result 如何處理?
// 在while迴圈搭配使用
mysql_fetch_array($result, MYSQL_BOTH); // MYSQL_BOTH指可用0,1,2...或欄位名稱id, name, mail兩種方式
// 或者使用
mysql_fetch_assoc($result);    // 只能用欄位名稱

查詢範例

<?php
    include_once('db.php');             // 資料庫連線

    $agestr = array(0 => "沒有選", 1 => "19歲以下", 2 => "20~29歲", 3 => "30~39歲", 4 => "40歲以上");
    $brand = array(1 => 'Apple', 2 => '三星', 3 => 'hTC', 4 => 'Sony');

    mysql_query("SET NAMES 'utf8'");    // 處理中文
    $sql = "SELECT * FROM survey";      // SQL查詢指令
    $result = mysql_query($sql);        // 執行SQL,回傳查詢結果
    
    while ($row = mysql_fetch_array($result, MYSQL_BOTH)) {
        echo $row['id'] . ' ';      // 印出id欄位值
        echo $row['name'] . ' ';    // 印出姓名欄位值 
        echo $row['mail'] . ' ';    // 印出電子郵件欄位值
        echo $agestr[$row['age']] . ' ';      // 印出年齡欄位轉換後字串
            
        $phone = explode('|', $row['brand']);   // 將字串轉成陣列,如 1|3|4 轉成陣列
        foreach ($phone as $value) {
            echo $brand[$value] . ' ';
        }
        echo '<BR>';
    }
?>

Practice #4

  • 在新增一筆資料之後加入查詢功能
    • 查詢全部內容
    • 排序方式:最新加入在最前面

20 minutes to go

# 排序語法 ORDER BY
# ASC 由小到大
# DESC 由大到小
SELECT "欄位名" 
FROM "表格名" 
[WHERE "條件"]
ORDER BY "欄位名" [ASC, DESC];

#以id欄位由大到小排列
SELECT * FROM survey ORDER BY id DESC;

查詢範例-字串常數

<?php
# 定義常數, 將陣列序列化 (php 5.5版以下)
define ("FRUITS", serialize (array ("apple", "cherry", "banana")));

# 使用,反序列化
$my_fruits = unserialize (FRUITS);
  • $agestr, $brand為常數,應只定義一次
<?php
# 定義常數, 將陣列序列化
define('AGESTR', serialize(array(0 => "沒有選", 1 => "19歲以下", 2 => "20~29歲", 3 => "30~39歲", 4 => "40歲以上")));
define('BRAND', serialize(array(1 => 'Apple', 2 => '三星', 3 => 'hTC', 4 => 'Sony')));
  • 在另一個檔案定義$agestr, $brand
  • 其他檔案使用時,include_once,反序列化
<?php
    include_once 'constant.php';
    $agestr = unserialize(AGESTR);  // 使用前,反序列化
    $brand = unserialize(BRAND);    // 使用前,反序列化

constant.php

實際使用

index.php

查詢範例-修改後

<?php
    include_once('db.php');             // 資料庫連線
    include_once('constant.php');
    $agestr = unserialize(AGESTR);
    $brand = unserialize(BRAND);

    mysql_query("SET NAMES 'utf8'");    // 處理中文
    $sql = "SELECT * FROM survey";      // 查詢
    $result = mysql_query($sql);
    
    while ($row = mysql_fetch_array($result, MYSQL_BOTH)) {
        echo $row['id'] . ' ';
        echo $row['name'] . ' ';
        echo $row['mail'] . ' ';
        echo $agestr[$row['age']] . ' ';
            
        $phone = explode('|', $row['brand']);   // 將字串轉成陣列,如 1|3|4 轉成陣列
        foreach ($phone as $value) {
            echo $brand[$value] . ' ';
        }
        echo '<BR>';
    }
?>

Practice #5

  • 建立constant.php,將陣列常數搬移至此檔
  • 其他檔案使用時,建立變數使用之

 

10 minutes to go

<?php
# php 5.6以上版本可用 const直接定義,不需序列化
const DEFAULT_ROLES = array('guy', 'development team');

資料庫

資料庫連線

中文issue

新增 INSERT INTO

查詢 SELECT...FROM

修改 UPDATE

刪除 DELETE

修改

UPDATE "表格名"
SET "欄位1" = [新值]
WHERE "條件";
  • SQL語法 
$id = $_POST['id'];
$mail = $_POST['mail'];
// ...
$sql = "UPDATE survey SET mail='$mail' WHERE id='$id'";    // SQL字串
$result = mysql_query($sql);      // 修改
  • 轉換成php
UPDATE Store_Information
SET Sales = 500
WHERE Store_Name = 'Los Angeles' 
AND Txn_Date = 'Jan-08-1999';
  • 範例

500

修改表單

UPDATE "表格名"
SET "欄位1" = [新值]
WHERE "條件";
  • SQL語法 
$id = $_POST['id'];
$mail = $_POST['mail'];
// ...
$sql = "UPDATE survey SET mail='$mail' WHERE id='$id'";    // SQL字串
$result = mysql_query($sql);      // 修改
  • 轉換成php
UPDATE Store_Information
SET Sales = 500
WHERE Store_Name = 'Los Angeles' 
AND Txn_Date = 'Jan-08-1999';
  • 範例

500

Practice #6

  • 利用新增表單,建立修改表單

20 minutes to go

資料庫

資料庫連線

中文issue

新增 INSERT INTO

查詢 SELECT...FROM

修改 UPDATE

刪除 DELETE

刪除

DELETE FROM "表格名"
WHERE "條件";
  • SQL語法 
$id = $_POST['id'];
// ...
$sql = "DELETE FROM survey WHERE id='$id'";    // SQL字串
$result = mysql_query($sql);      // 刪除
  • 轉換成php
DELETE FROM Store_Information
WHERE Store_Name = 'Los Angeles';
  • 範例

Practice #7

  • 需求:將資料列表後,勾選某一項目即可進行刪除

10 minutes to go

開始寫程式之前...

規劃期 製作前期 製作期 上架期
規格書 Wireframe 後端 測試
UI flow 前端 上架
Mockup 設計 維運
Prototype

系統開發流程

 

 

 

 

 

 

程式開發

 

 

 

 

 

 

系統分析

 

 

 

 

 

 

測試維運

製作前期:Wireframe

製作前期:UI flow

製作前期:UI-Flow

搭配系統草圖(wireframe)

查詢Select 

新增Insert into

刪除Delete

修改Update

製作前期:Mockup

製作前期:Prototype

Practice #8

  • 練習製作ui-flow(搭配草圖wireframe)
  • 需求:手機使用意見調查
  1. 記錄基本資料:姓名、email、年齡
  2. 調查資料:手機使用廠牌
  3. 要能分頁列出所有調查資料
  4. 要能新增調查資料、一次一筆
  5. 要能修改調查資料
  6. 要能刪除調查資料

Hands-on

動手做吧

http://pmtips.net/wp-content/uploads/2012/06/hands-on-PM.jpg

Practice #9

 

  • 設計首頁:index.php
    • 三個按鈕:新增、修改、刪除
  • 設計新增、修改表單(共用)
  • 設計確認刪除
  • 新增、修改、刪除:回到首頁

如何讓HTML Form處理multiple actions

Multiple actions

<form action="dispatch.php" method="post">
    <input type="submit" value="刪除" name="delete">
    <input type="submit" value="修改" name="update">
</form>
  • 表單部分:指定submit按鈕的name
  • 用$_POST判斷
header("Location: http://example.com/myOtherPage.php");
// 或是
$action = 'delete.php';
header("Location: " . $action);
  • 用header()轉址(必須HTML輸出之前)
<?php
if ($_POST['delete']) {
    header('Location: ' . 'delete.php');
    die();
}
if ($_POST['update']) {
    header('Location: ' . 'update.php');
    die();
}

Multiple actions

<form action="dispatch.php" method="post">
    <input type="submit" value="刪除" name="delete">
    <input type="submit" value="修改" name="update">
</form>
  • 表單部分
  • Action部分
<?php
if ($_POST['delete']) {
    header('Location: ' . 'delete.php');
    die();
}
if ($_POST['update']) {
    header('Location: ' . 'update.php');
    die();
}
?>
<!DOCTYPE html>
...

Before we go...

  • XAMPP資料庫密碼設定好了嗎?

。root帳號:超級管理員

    需要密碼保護
    僅用於後台管理

 

。務必建立其他帳號(非超級管理員)

XAMPProot密碼保護

  • 在xampp/phpmyadmin找到config.inc.php
  • 修改config.inc.php「唯讀」權限改為「讀寫」
  • 修改config.inc.php內容
$cfg['Servers'][$i]['auth_type'] = 'http';  /* 將config改成http */
$cfg['Servers'][$i]['AllowNoPassword'] = true;  /*要改成true,因為MySQL root預設為空白 */
  • config.inc.php權限改回「唯讀」
  • 瀏覽器執行localhost/phpmyadmin
  • 從phpmyadmin內修改root帳號密碼。

建立新資料庫

  • 建立使用者帳號時同步建立資料庫

建立新資料庫新增使用者(1/4)

建立新資料庫新增使用者(2/4)

資料庫與帳號名稱相同

資料庫主機位置

本機

建立新資料庫避免中文存入變亂碼(3/4)

務必改為 utf8_general_ci

確認資料庫名稱

建立新資料庫建立資料表(4/4)

完成

建立資料表

資料庫基本認識

資料庫連線

中文儲存與顯示問題

資料庫連線

database.php

page1.php

page2.php

重複使用

資料庫連線

<?php
    include_once 'database.php';

    $link = mysql_connect($server, $username, $password);    // 連接伺服器
    if( !$link) {
        die('無法連接資料庫');
    }
    $db = mysql_selectdb($dbname, $link) ;        // 開啟資料庫
    if (!$db) {
        die('無法開啟資料庫');
    }
    mysql_close($link);    // 關閉資料庫連線
?>
  • 連接伺服器、開啟資料庫
<?php
    $server = 'localhost';    // 伺服器
    $username = 'first_db';   // 帳號
    $password = 'xxxxxx';     // 密碼
    $dbname = 'first_db';     // 資料庫名稱:當初建立時與帳號相同
?>
  • 基本資料(例:database.php)

Practice #1

  • 練習將「處理表單」的程式加入下列程式碼:
    • 連接伺服器
    • 開啟資料庫
    • 關閉資料庫

 

10 minutes to go

資料庫連線

<?php
    include_once 'database.php'

    $link = mysql_connect($server, $username, $password);    // 連接伺服器
    if( !$link) {
        die('無法連接資料庫');
    }
    $db = mysql_select_db($dbname, $link) ;        // 開啟資料庫
    if (!$db) {
        die('無法開啟資料庫');
    }
    /*
        資料庫存取:新增 修改 查詢 刪除
    */

    mysql_close($link);    // 關閉資料庫連線
?>
  • include_once():解決重複程式碼

每個頁面重複

database.php

資料庫連線

<?php
    include_once 'database.php' 
    /*
        資料庫存取:新增 修改 查詢 刪除
    */
    mysql_close($link);    // 關閉資料庫連線
?>
  • include_once():解決重複程式碼

每個頁面重複

<?php
    $server = 'localhost';    // 伺服器
    $username = 'first_db';   // 帳號
    $password = 'xxxxxx';     // 密碼
    $dbname = 'first_db';     // 資料庫名稱:當初建立時與帳號相同

    $link = mysql_connect($server, $username, $password);    // 連接伺服器
    if( !$link) {
        die('無法連接資料庫');
    }
    $db = mysql_select_db($dbname, $link) ;        // 開啟資料庫
    if (!$db) {
        die('無法開啟資料庫');
    }
?>

資料庫基本認識

資料庫連線

中文儲存與顯示問題

中文儲存與顯示問題

<?php
    include_once('db.php');    // 引入db.php

    mysql_query("SET NAMES 'utf8'");    //處理寫入資料庫時的編碼問題

    /*
        資料庫存取:新增 修改 查詢 刪除
    */

    mysql_close($link);    // 關閉資料庫連線
?>
  • 加入SET NAMES 'utf8'
  • 也可放在database.php檔內
<?php
    // ....[略]....
    $db = mysql_select_db($dbname, $link) ;        // 開啟資料庫
    if (!$db) {
        die('無法開啟資料庫');
    }
    mysql_query("SET NAMES 'utf8'");    //處理寫入資料庫時的編碼問題

database.php

What's going next?

資料庫存取-CRUD

Create Read Update Delete

新增 查詢 修改 刪除

資料庫存取-CRUD

Create Read Update Delete

新增

新增範例原始版

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <form name="form1" method="post" action="confirm.php">
          <p>
            <label for="name"></label>
          姓名:  <input type="text" name="name" id="name">
          <br>
          電子郵件:
          <label for="mail"></label>
          <input type="text" name="mail" id="mail">
          </p>
          <p>
            <label>請勾選年紀:<br>
              <input type="radio" name="age" value="0" id="age_0">
              19歲以下</label>
            <br>
            <label>
              <input type="radio" name="age" value="1" id="age_1">
              20~29歲</label>
            <br>
            <label>
              <input type="radio" name="age" value="2" id="age_2">
              30~39歲</label>
            <br>
            <label>
              <input type="radio" name="age" value="3" id="age_3">
              40歲以上</label>
            <br>
          </p>
          
          <p>
            <input type="submit" name="button" id="button" value="送出">
            <input type="reset" name="button2" id="button2" value="重設">
          </p>
        </form>
    </body>
</html>
  • 新增表單index.html

新增範例原始版

<?php
    include_once('database.php');    // 引入db.php

    $name = $_POST['name'];
    $mail = $_POST['mail'];
    if (isset($_POST['age'])) {
        $age = $_POST['age'];
    } else {
        $age = 0;
    }
   
    $sql = "INSERT INTO `first_db`.`survey` "
            . "(`id`, `name`, `mail`, `age`)"
            . " VALUES (NULL, '$name',"
            . " '$mail', "
            . "'$age');";

    mysql_query($sql);    // 新增資料
    mysql_close($link);    // 關閉資料庫連線
?>
  • INSERT INTO

What's wrong with SQL string?

SQL字串除錯不易

<?php
    $sql = "INSERT INTO `first_db`.`survey` "
            . "(`id`, `name`, `mail`, `age`, `brand`)"
            . " VALUES (NULL, '$name',"
            . " '$mail', "
            . "'$age',"
            . " '$phonestr');";

?>

發生執行錯誤時,通常無明顯錯誤訊息!

解決方案:使用他人提供的函式庫

Medoo函式庫

Medoo安裝待確認事項

  • 下載medoo解壓縮
  • 加入lib/medoo.php
  • 確認php.ini已開啟pdo模組

解壓縮後,複製檔案至lib下

  • 重新撰寫database.php
  • 參考線上說明,進行資料庫CRUD操作
;extension=php_pdo_mssql.dll
extension=php_pdo_mysql.dll
;extension=php_pdo_oci.dll

Medoo安裝 php.ini設定

;extension=php_pdo_mssql.dll
extension=php_pdo_mysql.dll
;extension=php_pdo_oci.dll
  • 開啟php.ini,搜尋pdo
  • 確認php_pdo_mysql.dll該行前無分號
  • 若有分號,刪除分號後存檔,重啟apache

Medoo安裝 重新撰寫database.php

<?php

include_once 'lib/medoo.php';

$options = array(
    'database_type' => 'mysql',       // 預設
    'database_name' => '你的資料庫名稱',// 資料庫名稱
    'server' => 'localhost',          // 伺服器:本機
    'username' => '你的帳號名稱',       // 帳號
    'password' => '你的密碼',          // 密碼
    'charset' => 'utf8');

$database = new medoo($options);
$database->query("SET NAMES 'utf8'");

?>

資料庫存取-CRUD

Create Read Update Delete

新增

 

Medoo版

新增資料

        <?php
        include_once 'database.php';

        $name = $_POST['name'];
        $mail = $_POST['mail'];
        if (isset($_POST['age'])) {
            $age = $_POST['age'];
        } 
        // 新增資料
        $last_user_id = $database->insert("survey", array(
            "name" => $name,
            "mail" => $mail,
            "age" => $age
        ));
        ?>

survey資料表

資料庫存取-CRUD

Create Read Update Delete

查詢

 

Medoo版

查詢資料

<?php
        include_once 'database.php';

        // 兩個參數,第一個為資料表名稱,第二個為選取的欄位
        // * 代表全選
        $result = $database->select("survey", "*");

        // 顯示查詢結果
        foreach ($result as $row) {
            echo $row['id'] . ' ';
            echo $row['name'] . ' ';
            echo $row['mail'] . ' ';
            echo $row['age'] . ' ';
            echo '<BR>';
        }
?>

工具函式:讀取資料庫內設定的選項項目

  • 表單選項:定義於資料庫內
  • 使用enum型態或set型態

工具函式ENUM設定

  • 表單value值:從1開始設定
  • 寫入1, 2, 3...值
  • 實際存入enum值,而非1,2,3...
if (isset($_POST['age'])) {
    $age = $_POST['age'];
} else {
    $age = 1;
}
// 新增資料
$last_user_id = $database->insert("survey", [
    "name" => $name,
    "mail" => $mail,
    "age" => $age
    ]);
?>

工具程式讀取ENUM欄位值

<?php
include_once 'lib/medoo.php';

$options = array(
    'database_type' => 'mysql',       // 預設
    'database_name' => '你的資料庫名稱',// 資料庫名稱
    'server' => 'localhost',          // 伺服器:本機
    'username' => '你的帳號名稱',       // 帳號
    'password' => '你的密碼',          // 密碼
    'charset' => 'utf8');

$database = new medoo($options);
$database->query("SET NAMES 'utf8'");

/*回傳陣列:回傳mysql資料庫裡的enum設定值,並將其轉為陣列*/
function enum_list($table, $field) {
    global $database;
    $type = $database->query("SHOW COLUMNS FROM $table WHERE Field = '$field'")
            ->fetchAll();
    preg_match("/^enum\(\'(.*)\'\)$/", $type[0]['Type'], $matches);
    $enum = explode("','", $matches[1]);
    return $enum;
}

修改database.php,加入enum_list

資料庫存取-CRUD

Create Read Update Delete

新增+查詢

 

Medoo版

範例新增+查詢-表單部分

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <?php
        include_once 'database.php';
        ?>
        <form name="form1" method="post" action="confirm.php">
            <p>
                <label for="name"></label>
                姓名:
                <input type="text" name="name" id="name">
                <br>
                電子郵件:
                <label for="mail"></label>
                <input type="text" name="mail" id="mail">
            </p>
            <p>
                <label>請勾選年紀:<br>
                    <?php
                    $age_options = enum_list('survey', 'age');
                    foreach ($age_options as $key => $value) {
                        ?>
                        <input type="radio" name="age" value="<?= $key + 1 ?>" id="age_0">
                        <?= $value ?></label>
                    <br>
                    <?php
                }
                ?>
            </p>
            <p>
                <input type="submit" name="button" id="button" value="送出">
                <input type="reset" name="button2" id="button2" value="重設">
            </p>
        </form>
    </body>
</html>

表單: survey.php

<label>請勾選年紀:<br>
    <?php
    $age_options = enum_list('survey', 'age');
    foreach ($age_options as $key => $value) {
    ?>
        <input type="radio" name="age" value="<?= $key + 1 ?>">
          <?= $value ?></label>
        <br>
    <?php
    }
    ?>

範例新增+查詢-處理程式

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <?php
        include_once 'database.php';
        if (empty($_POST['name']) || empty($_POST['mail']) || !isset($_POST['age'])) {
            echo '資料未填寫完成' . '<br>';
        } else {
            $name = $_POST['name'];
            $mail = $_POST['mail'];
            $age = $_POST['age'];
            // 新增資料
            $last_user_id = $database->insert("survey", [
                "name" => $name,
                "mail" => $mail,
                "age" => $age
            ]);
        }
        ?>
        <?php
        // 查詢資料
        $result = $database->select("survey", "*");

        foreach ($result as $row) {
            echo $row['id'] . ' ';
            echo $row['name'] . ' ';
            echo $row['mail'] . ' ';
            echo $row['age'] . ' ';
            echo '<BR>';
        }
        ?>
        <a href="survey.php">返回前頁</a>
    </body>
</html>

處理程式: confirm.php

資料庫存取-CRUD

Create Read Update Delete

更多查詢

 

Medoo版

Medoo查詢基本語法查詢方式(1/4)

<?php
include_once 'lib/medoo.php';
$options = array(
    'database_type' => 'mysql',       // 預設
    'database_name' => '你的資料庫名稱',// 資料庫名稱
    'server' => 'localhost',          // 伺服器:本機
    'username' => '你的帳號名稱',       // 帳號
    'password' => '你的密碼',          // 密碼
    'charset' => 'utf8');

$db = new medoo($options);
$db->query("SET NAMES 'utf8'");
?>

以database.inc.php為例:

資料庫變數為$db

Medoo查詢基本語法查詢方式(2/4)

$db->select($table, $columns, $where)

查詢方式

$table: 表格名稱(字串)

$columns: 讀取之欄位名稱(字串/陣列)

$where(選填): 過濾條件(陣列)

查詢結果:陣列

$columns = array('name','mail', 'age');
$where = array('age' => '19歲以上' )
$result = $db->select('survey', $columns, $where)

foreach($result as $row) {
    echo "姓名:". $row['name'] . ' 信箱:' . $row['mail] . '<br>';
}

Medoo查詢基本語法更多範例(3/4)

$result= $db->select(
    "survey",    // 表格名
    "name",      // 只讀取一欄
    array("mail" => "foo@bar.com") // mail值 等於 foo@bar.com
);
$result= $db->select(
    "student",    // 表格名
    array("sid","name","score"),  // 讀取三欄
    array("score" => 100)         // score 等於 100
);
$result= $db->select(
    "student",    // 表格名
    array("sid","name","score"),  // 讀取三欄
    array("score[>=]" => 60)      // score 大於等於 60
);

更多範例:http://medoo.in/api/where

Medoo查詢基本語法更多範例(4/4)

$result= $db->select(
    "survey",    // 表格名
    "name",      // 只讀取一欄
    array("salary[<>]" => [200, 500]) // salary介於200~500
);
$result= $db->select(
    "student",    // 表格名
    array("sid","name","mail"),  // 讀取三欄
    array("OR" => array(         // 兩個條件 or組合
	        "sid" => array(2, 123, 234, 54),
		"mail" => array("foo@bar.com", "cat@dog.com")
	)
    )
);

更多範例:http://medoo.in/api/where

Practice #2

  • 建立commerce資料庫
  • 建立產品資料表product
  • 新增產品
  • 查詢價格大於某個數值的所有產品

網路程式設計

By Leuo-Hong Wang

網路程式設計

#2 資料庫存取-1

  • 1,195