小猫咪 小猫畅谈 2021-11-23 18

最近在测试 Ajax 时需要用到后端 PHP, 因此花了点时间複习之前的笔记, 整理资料库存取时在下面这本书的第 25 章看到使用 PDO (PHP Data Object) 操作 MySQL 资料库的介绍, 我觉得比传统方式简单好用 :

# 彻底研究 jQuery Mobile + PHP 手机程式及网站开发 (上奇, 张亚飞)

我用 phpinfo() 函数查询所租的英国 Hostinger 主机发现也有支援 PDO (MySQL 与 SQlite), 所以就顺便做一下测试与整理 :


使用 PDO 存取资料库的程序如下 :


1. 建立资料库连线 :

使用 new PDO($dsn, $username, $password) 建立一个 PDO 资料库连线物件, 传入参数有三 :
$dsn (资料来源字串) :
包含 MySQL 资料库主机位址 (host), 通讯埠 (port), 以及资料库名称 (dbname). 例如 :
$dsn="mysql:host=mysql.hostinger.co.uk;port=3306;dbname=u137801000_test";  
$dsn="mysql:host=localhost;port=3306;dbname=test"; (使用本机伺服器)
$username (资料库使用者名称) :
即 MySQL 资料库使用者名称, 例如 :
$username="u137801000_test";
$username="root"; (使用本机伺服器)
$password (资料库使用者密码) :
即 MySQL 资料库使用者密码, 例如 :
$password="mysql";
例如我在 Hostinger 的主机用的是 :

//建立 PDO 连线物件
$dsn="mysql:host=mysql.hostinger.co.uk;port=3306;dbname=u137801000_test";
$username="u137801000_test";
$password="a123456";
$conn=new PDO($dsn, $username, $password);

在本机 XAMPP 用的是 :

//建立 PDO 连线物件
$dsn="mysql:host=localhost;port=3306;dbname=test";
$username="root";
$password="mysql";
$conn=new PDO($dsn, $username, $password);

因为呼叫 PDO() 发生错误时可能暴露资料库连线资讯形成资安漏洞, 例如若将上面的资料库名称改为不存在的 test1 就会出现如下例外 (exception) :

Fatal error: Uncaught PDOException: SQLSTATE[HY000] [1049] Unknown database 'test1' in D:\xampp\htdocs\php_pdo_test_1.php:7 Stack trace: #0 D:\xampp\htdocs\php_pdo_test_1.php(7): PDO->__construct('mysql:host=loca...', 'root', 'mysql') #1 {main} thrown in D:\xampp\htdocs\php_pdo_test_1.php on line 7

补强办法是将 PDO() 指令放在 try-catch 中, 当发生连线错误捕捉到 PDOException 例外事件时呼叫 die() 函数结束程序, 避免直接暴露资料库存取资讯 :

try {$conn=new PDO($dsn, $username, $password);}
catch (PDOException $e) {
  echo "资料库连线错误!";
  die();
  }


2. 设定资料库编码 :

若资料库内储存资料含有中文字元, 则需以下列指令设定资料库编码为 utf-8 :

$conn->exec("SET CHARACTER SET utf8");


3. 执行资料库操作 :

资料库主要有 CRUD (Create/Read/Update/Delete, 增删查改) 等操作, 常用的 SQL 指令如下表 :


资料库操作         SQL 指令范例
建立 (Create)         INSERT INTO users(name,age,gender) VALUES('Tom',25,'M')
读取 (Read)         SELECT * FROM users WHERE gender='F' AND age < 40 ORDER BY name DESC
更新 (Update)         UPDATE users SET age=23,gender='F' WHERE name='Amy'
删除 (Delete)         DELETE FROM users WHERE name = "Tom"


另外有时还会用到建立资料表之操作, 指令例如 :

$SQL="CREATE TABLE users(name varchar(50) NOT NULL, age int NOT NULL)"

更多 SQL 指令范例参考 :

# 最常用的 SQL 指令

呼叫 PDO 连线物件的 query() 方法并传入 SQL 字串即可执行 SQL 指令, 此方法会传回一个 PDOStatement 物件 (即受影响之资料集) :

$RS=$conn->query($SQL);

此资料集物件常用之方法有两个 :
rowCount() : 传回资料集的笔数 (SQL 指令操作影响之列数)
fetch() :  传回资料集中最上面的一笔资料并将指标往下移
例如 :

$row=$RS->fetch();   //传回资料集中最上面的一笔资料
if ($RS->rowCount() > 0) {echo "更新完成";}

fetch() 方法传回值为一个关联式阵列, 可用阵列之键 (即资料表之栏位名称) 来存取, 例如 :

echo $row["name"];


4. 关闭资料库连线 :

因连线物件会占用记忆体, 故执行完只要将 PDO 连线物件指定 NULL 值即可关闭连线.

$conn=NULL;


以下测试使用最近为网友解题于 Hostinger 上所建的一个测试资料表为例, 其 SQL 指令为 :

--
-- 资料表结构 `pid_valid_date`
--

CREATE TABLE `pid_valid_date` (
  `pid` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
  `valid_date` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
建好后输入如下测试资料,  SQL 指令为 :

--
-- 倾印资料表的资料 `pid_valid_date`
--

INSERT INTO `pid_valid_date` (`pid`, `valid_date`) VALUES
('A123456789', '2021-02-13'),
('Q123456789', '2025-11-21'),
('S123456789', '2023-05-29'),
('T123456789', '2020-12-31');

参考 :

# 用 PHP 与 jQuery Ajax 存取资料库 (习题)


测试 1 : 读取资料库中的资料表 (读取第一笔资料) [看原始码]

<?php
header('Content-Type: text/html;charset=UTF-8');
//建立 PDO 连线物件
$dsn="mysql:host=localhost;port=3306;dbname=test";
$username="root";
$password="mysql";
try {$conn=new PDO($dsn, $username, $password);}
catch (PDOException $e) {
  echo "资料库连线错误!";
  die();
  }
//设定资料编码
$conn->exec("SET CHARACTER SET utf8");
//读取资料表
$SQL="SELECT * FROM `pid_valid_date`";
$RS=$conn->query($SQL);
//读取第一列资料
$row=$RS->fetch();
//倾印阵列内容
var_dump($row);
if(!empty($row)) {
  $msg="pid=".$row["pid"]." valid_date=".$row["valid_date"]."<br>";
  }
echo $msg;
//关闭资料库连线
$conn=NULL;
?>
此例用 DPO 连线物件的 query() 方法从资料表 pid_valid_date 中撷取所有栏位资料后传回资料集 (PDOStatement 物件), 呼叫其 fetch() 方法传回资料集中的第一列资料 (关联式阵列), 以栏位名称即可取得每一栏之值, 原始的资料表传回结果如下 :

array(4) { ["pid"]=> string(10) "A123456789" [0]=> string(10) "A123456789" ["valid_date"]=> string(10) "2021-02-13" [1]=> string(10) "2021-02-13" } pid=A123456789 valid_date=2021-02-13

资料集 PDOStatement 物件的 fetch() 方法只传回资料集中的第一笔资料, 若要列出全部资料集需使用迴圈进行迭代, 例如 :



测试 2 : 读取资料库中的资料表 (列出全部资料) [看原始码]

<?php
header('Content-Type: text/html;charset=UTF-8');
//建立 PDO 连线物件
$dsn="mysql:host=localhost;port=3306;dbname=test";
$username="root";
$password="mysql";
try {$conn=new PDO($dsn, $username, $password);}
catch (PDOException $e) {
  echo "资料库连线错误!";
  die();
  }
//设定资料编码
$conn->exec("SET CHARACTER SET utf8");
//读取资料表
$SQL="SELECT * FROM `pid_valid_date`";
$RS=$conn->query($SQL);
//读取第一列资料
$row=$RS->fetch();
//迭代整个资料集
while(!empty($row)) {
  echo "pid=".$row["pid"]." valid_date=".$row["valid_date"]."<br>";
  $row=$RS->fetch();
  }
//关闭资料库连线
$conn=NULL;
?>
此例呼叫 fetch() 取得第一笔资料后用 while 迴圈检查资料是否为空, 否则就印出该笔资料并取出下一笔资料直到资料集结束, 结果如下 :

pid=A123456789 valid_date=2021-02-14
pid=Q123456789 valid_date=2025-11-21
pid=S123456789 valid_date=2023-05-29
pid=T123456789 valid_date=2020-12-31

下面是其它资料表操作例如新增, 更新, 删除等全部整合在一起的范例 :



测试 3 : 在资料表中新增一笔资料 [看原始码]

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
    <meta http-equiv="cache-control" content="no-cache">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <script src="http://code.jquery.com/jquery-3.5.1.min.js"></script>
  </head>
  <body>
    <label for="pid">身分证字号(10个字元)<label>
    <input type="text" id="pid" name="pid" placeholder="A123456789"><br>
    <label for="valid_date">有效期限<label>
    <input type="date" id="valid_date" name="valid_date" placeholder="2020-11-03"><br><br>
    <button id="create">新增</button>
    <button id="read">读取</button>
    <button id="update">修改</button>
    <button id="delete">删除</button>
    <button id="read_all">读取全部</button>
    <div id="display"></div>
    <script>
      $(document).ready(function(){
        $('#create').on('click', function() {
          var pid=$("#pid").val();
          var valid_date=$("#valid_date").val();
          if(pid.length!=10){alert("身分证字号为10个字元");return;}
          if(valid_date.length==0){alert("请选择日期");return;}
          $.post({
            url: "http://tony1966.xyz/test/phptest/php_pdo_test_3_create.php",
            dataType: "html",
            data: {pid: pid, valid_date: valid_date},
            success: function(res) {
              alert(res);
              }
            });
          });
        $('#read').on('click', function() {
          var pid=$("#pid").val();
          if(pid.length!=10){alert("身分证字号为10个字元");return;}
          $.post({
            url: "http://tony1966.xyz/test/phptest/php_pdo_test_3_read.php",
            dataType: "html",
            data: {pid: pid},
            success: function(res) {
              $("#valid_date").val(res);
              $("#display").html(res);
              }
            });
          });
        $("#update").on("click", function(e){
          var pid=$("#pid").val();
          var valid_date=$("#valid_date").val();
          if(pid.length!=10){alert("身分证字号为10个字元");return;}
          if(valid_date.length==0){alert("请选择日期");return;}
          $.post({
            url: "http://tony1966.xyz/test/phptest/php_pdo_test_3_update.php",
            dataType: "html",
            data: {pid: pid, valid_date: valid_date},
            success: function(res) {
              alert(res);
              }
            });
          });
        $("#delete").on("click", function(e){
          var pid=$("#pid").val();
          if(pid.length!=10){alert("身分证字号为10个字元");return;}
          $.post({
            url: "http://tony1966.xyz/test/phptest/php_pdo_test_3_delete.php",
            dataType: "html",
            data: {pid: pid},
            success: function(res) {
              alert(res);
              }
            });
          });
        $("#read_all").on("click", function(e){
          $.get({
            url: "http://tony1966.xyz/test/phptest/php_pdo_test_2.php",
            dataType: "html",
            success: function(res) {
              $("#display").html(res);
              }
            });
          });
        });
    </script>
  </body>
</html>

此例使用了 HTML5 的 input[type=date] 元件来输入与显示日期, 透过五个按钮来进行 CRUD 操作, 关于 date 元件参考 :

# HTML5 的日期输入功能教学

按 "读取全部" 钮会透过 Ajax 向上面范例的 php_pdo_test_2.php 提出请求, 传回资料表 pid_valid_date 中的所有资料, 显示于 id=display 的 div 元件中, 结果如下 :





按 "读取" 会先检查有无输入长度为 10 个字元的身分证字号, 通过后会透过 Ajax 向后端程式 php_pdo_test_3_read.php 提交参数 pid, 查询结果为有效日期栏位 valid_date, 除了设定输入栏位外也会显示在 id=display 的 div 元素中.  

#php_pdo_test_3_read.php
<?php
header('Content-Type: text/html;charset=UTF-8');
//建立 PDO 连线物件
$dsn="mysql:host=mysql.hostinger.co.uk;port=3306;dbname=u137801000_test";
$username="u137801000_test";
$password="a123456";
try {$conn=new PDO($dsn, $username, $password);}
catch (PDOException $e) {
  echo "资料库连线错误!";
  die();
  }
//设定资料编码
$conn->exec("SET CHARACTER SET utf8");
$pid=$_REQUEST["pid"];
//读取资料表
$SQL="SELECT * FROM `pid_valid_date` WHERE pid='".$pid."'";
$RS=$conn->query($SQL);
//读取第一列资料 (传回关联式阵列)
$row=$RS->fetch();
echo $row["valid_date"];
//关闭资料库连线
$conn=NULL;
?>
按 "更新" 按钮会检查输入身分证字号与有效日期这两个栏位是否有输入合规之字串, 然后向后端程式 php_pdo_test_3_update.php 提交参数 pid 与 valid_date, 传回的结果字串会用 alert() 显示 :

#php_pdo_test_3_update.php
<?php
header('Content-Type: text/html;charset=UTF-8');
//建立 PDO 连线物件
$dsn="mysql:host=mysql.hostinger.co.uk;port=3306;dbname=u137801000_test";
$username="u137801000_test";
$password="a123456";
try {$conn=new PDO($dsn, $username, $password);}
catch (PDOException $e) {
  echo "资料库连线错误!";
  die();
  }
//设定资料编码
$conn->exec("SET CHARACTER SET utf8");
$pid=$_REQUEST["pid"];
$valid_date=$_REQUEST["valid_date"];
//读取资料表
$SQL="UPDATE `pid_valid_date` SET valid_date='".$valid_date."' ".
     "WHERE pid='".$pid."'";
$RS=$conn->query($SQL);
if($RS->rowCount() > 0) {echo "更新纪录成功";}
else {echo "更新纪录失败";}
//关闭资料库连线
$conn=NULL;
?>
按 "删除" 按钮会检查输入身分证字号栏位是否有输入合规之字串, 然后向后端程式 php_pdo_test_3_delete.php 提交参数 pid, 传回的结果字串会用 alert() 显示 :

#php_pdo_test_3_delete.php
<?php
header('Content-Type: text/html;charset=UTF-8');
//建立 PDO 连线物件
$dsn="mysql:host=mysql.hostinger.co.uk;port=3306;dbname=u137801000_test";
$username="u137801000_test";
$password="a123456";
try {$conn=new PDO($dsn, $username, $password);}
catch (PDOException $e) {
  echo "资料库连线错误!";
  die();
  }
//设定资料编码
$conn->exec("SET CHARACTER SET utf8");
$pid=$_REQUEST["pid"];
$valid_date=$_REQUEST["valid_date"];
//读取资料表
$SQL="DELETE FROM `pid_valid_date` WHERE pid='".$pid."'";
$RS=$conn->query($SQL);
if($RS->rowCount() > 0) {echo "删除纪录成功";}
else {echo "删除纪录失败";}
//关闭资料库连线
$conn=NULL;
?>
按 "新增" 按钮会检查输入身分证字号与有效日期这两个栏位是否有输入合规之字串, 然后向后端程式 php_pdo_test_3_create.php 提交参数 pid 与 valid_date, 传回的结果字串会用 alert() 显示 :

#php_pdo_test_3_create.php
<?php
header('Content-Type: text/html;charset=UTF-8');
//建立 PDO 连线物件
$dsn="mysql:host=localhost;port=3306;dbname=test";
$username="root";
$password="mysql";
try {$conn=new PDO($dsn, $username, $password);}
catch (PDOException $e) {
  echo "资料库连线错误!";
  die();
  }
//设定资料编码
$conn->exec("SET CHARACTER SET utf8");
$pid=$_REQUEST["pid"];
$valid_date=$_REQUEST["valid_date"];
//读取资料表
$SQL="INSERT INTO `pid_valid_date`(pid, valid_date) VALUES('".
     $pid."','".$valid_date."')";
$RS=$conn->query($SQL);
if($RS->rowCount() > 0) {echo "新增纪录成功";}
else {echo "新增纪录失败";}
//关闭资料库连线
$conn=NULL;
?>
使用 PDO 物件存取 MySQL 资料库感觉比传统的函数式操作要简单.

商业许可: 仅限学习交流,不可商用 

最近在测试 Ajax 时需要用到后端 PHP, 因此花了点时间複习之前的笔记, 整理资料库存取时在下面这本书的第 25 章看到使用 PDO (PHP Data Object) 操作 MySQL 资料库的介绍, 我觉得比传统方式简单好用 :

# 彻底研究 jQuery Mobile + PHP 手机程式及网站开发 (上奇, 张亚飞)

我用 phpinfo() 函数查询所租的英国 Hostinger 主机发现也有支援 PDO (MySQL 与 SQlite), 所以就顺便做一下测试与整理 :


使用 PDO 存取资料库的程序如下 :


1. 建立资料库连线 :

使用 new PDO($dsn, $username, $password) 建立一个 PDO 资料库连线物件, 传入参数有三 :
$dsn (资料来源字串) :
包含 MySQL 资料库主机位址 (host), 通讯埠 (port), 以及资料库名称 (dbname). 例如 :
$dsn="mysql:host=mysql.hostinger.co.uk;port=3306;dbname=u137801000_test";  
$dsn="mysql:host=localhost;port=3306;dbname=test"; (使用本机伺服器)
$username (资料库使用者名称) :
即 MySQL 资料库使用者名称, 例如 :
$username="u137801000_test";
$username="root"; (使用本机伺服器)
$password (资料库使用者密码) :
即 MySQL 资料库使用者密码, 例如 :
$password="mysql";
例如我在 Hostinger 的主机用的是 :

//建立 PDO 连线物件
$dsn="mysql:host=mysql.hostinger.co.uk;port=3306;dbname=u137801000_test";
$username="u137801000_test";
$password="a123456";
$conn=new PDO($dsn, $username, $password);

在本机 XAMPP 用的是 :

//建立 PDO 连线物件
$dsn="mysql:host=localhost;port=3306;dbname=test";
$username="root";
$password="mysql";
$conn=new PDO($dsn, $username, $password);

因为呼叫 PDO() 发生错误时可能暴露资料库连线资讯形成资安漏洞, 例如若将上面的资料库名称改为不存在的 test1 就会出现如下例外 (exception) :

Fatal error: Uncaught PDOException: SQLSTATE[HY000] [1049] Unknown database 'test1' in D:\xampp\htdocs\php_pdo_test_1.php:7 Stack trace: #0 D:\xampp\htdocs\php_pdo_test_1.php(7): PDO->__construct('mysql:host=loca...', 'root', 'mysql') #1 {main} thrown in D:\xampp\htdocs\php_pdo_test_1.php on line 7

补强办法是将 PDO() 指令放在 try-catch 中, 当发生连线错误捕捉到 PDOException 例外事件时呼叫 die() 函数结束程序, 避免直接暴露资料库存取资讯 :

try {$conn=new PDO($dsn, $username, $password);}
catch (PDOException $e) {
  echo "资料库连线错误!";
  die();
  }


2. 设定资料库编码 :

若资料库内储存资料含有中文字元, 则需以下列指令设定资料库编码为 utf-8 :

$conn->exec("SET CHARACTER SET utf8");


3. 执行资料库操作 :

资料库主要有 CRUD (Create/Read/Update/Delete, 增删查改) 等操作, 常用的 SQL 指令如下表 :


资料库操作         SQL 指令范例
建立 (Create)         INSERT INTO users(name,age,gender) VALUES('Tom',25,'M')
读取 (Read)         SELECT * FROM users WHERE gender='F' AND age < 40 ORDER BY name DESC
更新 (Update)         UPDATE users SET age=23,gender='F' WHERE name='Amy'
删除 (Delete)         DELETE FROM users WHERE name = "Tom"


另外有时还会用到建立资料表之操作, 指令例如 :

$SQL="CREATE TABLE users(name varchar(50) NOT NULL, age int NOT NULL)"

更多 SQL 指令范例参考 :

# 最常用的 SQL 指令

呼叫 PDO 连线物件的 query() 方法并传入 SQL 字串即可执行 SQL 指令, 此方法会传回一个 PDOStatement 物件 (即受影响之资料集) :

$RS=$conn->query($SQL);

此资料集物件常用之方法有两个 :
rowCount() : 传回资料集的笔数 (SQL 指令操作影响之列数)
fetch() :  传回资料集中最上面的一笔资料并将指标往下移
例如 :

$row=$RS->fetch();   //传回资料集中最上面的一笔资料
if ($RS->rowCount() > 0) {echo "更新完成";}

fetch() 方法传回值为一个关联式阵列, 可用阵列之键 (即资料表之栏位名称) 来存取, 例如 :

echo $row["name"];


4. 关闭资料库连线 :

因连线物件会占用记忆体, 故执行完只要将 PDO 连线物件指定 NULL 值即可关闭连线.

$conn=NULL;


以下测试使用最近为网友解题于 Hostinger 上所建的一个测试资料表为例, 其 SQL 指令为 :

--
-- 资料表结构 `pid_valid_date`
--

CREATE TABLE `pid_valid_date` (
  `pid` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
  `valid_date` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
建好后输入如下测试资料,  SQL 指令为 :

--
-- 倾印资料表的资料 `pid_valid_date`
--

INSERT INTO `pid_valid_date` (`pid`, `valid_date`) VALUES
('A123456789', '2021-02-13'),
('Q123456789', '2025-11-21'),
('S123456789', '2023-05-29'),
('T123456789', '2020-12-31');

参考 :

# 用 PHP 与 jQuery Ajax 存取资料库 (习题)


测试 1 : 读取资料库中的资料表 (读取第一笔资料) [看原始码]

<?php
header('Content-Type: text/html;charset=UTF-8');
//建立 PDO 连线物件
$dsn="mysql:host=localhost;port=3306;dbname=test";
$username="root";
$password="mysql";
try {$conn=new PDO($dsn, $username, $password);}
catch (PDOException $e) {
  echo "资料库连线错误!";
  die();
  }
//设定资料编码
$conn->exec("SET CHARACTER SET utf8");
//读取资料表
$SQL="SELECT * FROM `pid_valid_date`";
$RS=$conn->query($SQL);
//读取第一列资料
$row=$RS->fetch();
//倾印阵列内容
var_dump($row);
if(!empty($row)) {
  $msg="pid=".$row["pid"]." valid_date=".$row["valid_date"]."<br>";
  }
echo $msg;
//关闭资料库连线
$conn=NULL;
?>
此例用 DPO 连线物件的 query() 方法从资料表 pid_valid_date 中撷取所有栏位资料后传回资料集 (PDOStatement 物件), 呼叫其 fetch() 方法传回资料集中的第一列资料 (关联式阵列), 以栏位名称即可取得每一栏之值, 原始的资料表传回结果如下 :

array(4) { ["pid"]=> string(10) "A123456789" [0]=> string(10) "A123456789" ["valid_date"]=> string(10) "2021-02-13" [1]=> string(10) "2021-02-13" } pid=A123456789 valid_date=2021-02-13

资料集 PDOStatement 物件的 fetch() 方法只传回资料集中的第一笔资料, 若要列出全部资料集需使用迴圈进行迭代, 例如 :



测试 2 : 读取资料库中的资料表 (列出全部资料) [看原始码]

<?php
header('Content-Type: text/html;charset=UTF-8');
//建立 PDO 连线物件
$dsn="mysql:host=localhost;port=3306;dbname=test";
$username="root";
$password="mysql";
try {$conn=new PDO($dsn, $username, $password);}
catch (PDOException $e) {
  echo "资料库连线错误!";
  die();
  }
//设定资料编码
$conn->exec("SET CHARACTER SET utf8");
//读取资料表
$SQL="SELECT * FROM `pid_valid_date`";
$RS=$conn->query($SQL);
//读取第一列资料
$row=$RS->fetch();
//迭代整个资料集
while(!empty($row)) {
  echo "pid=".$row["pid"]." valid_date=".$row["valid_date"]."<br>";
  $row=$RS->fetch();
  }
//关闭资料库连线
$conn=NULL;
?>
此例呼叫 fetch() 取得第一笔资料后用 while 迴圈检查资料是否为空, 否则就印出该笔资料并取出下一笔资料直到资料集结束, 结果如下 :

pid=A123456789 valid_date=2021-02-14
pid=Q123456789 valid_date=2025-11-21
pid=S123456789 valid_date=2023-05-29
pid=T123456789 valid_date=2020-12-31

下面是其它资料表操作例如新增, 更新, 删除等全部整合在一起的范例 :



测试 3 : 在资料表中新增一笔资料 [看原始码]

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
    <meta http-equiv="cache-control" content="no-cache">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <script src="http://code.jquery.com/jquery-3.5.1.min.js"></script>
  </head>
  <body>
    <label for="pid">身分证字号(10个字元)<label>
    <input type="text" id="pid" name="pid" placeholder="A123456789"><br>
    <label for="valid_date">有效期限<label>
    <input type="date" id="valid_date" name="valid_date" placeholder="2020-11-03"><br><br>
    <button id="create">新增</button>
    <button id="read">读取</button>
    <button id="update">修改</button>
    <button id="delete">删除</button>
    <button id="read_all">读取全部</button>
    <div id="display"></div>
    <script>
      $(document).ready(function(){
        $('#create').on('click', function() {
          var pid=$("#pid").val();
          var valid_date=$("#valid_date").val();
          if(pid.length!=10){alert("身分证字号为10个字元");return;}
          if(valid_date.length==0){alert("请选择日期");return;}
          $.post({
            url: "http://tony1966.xyz/test/phptest/php_pdo_test_3_create.php",
            dataType: "html",
            data: {pid: pid, valid_date: valid_date},
            success: function(res) {
              alert(res);
              }
            });
          });
        $('#read').on('click', function() {
          var pid=$("#pid").val();
          if(pid.length!=10){alert("身分证字号为10个字元");return;}
          $.post({
            url: "http://tony1966.xyz/test/phptest/php_pdo_test_3_read.php",
            dataType: "html",
            data: {pid: pid},
            success: function(res) {
              $("#valid_date").val(res);
              $("#display").html(res);
              }
            });
          });
        $("#update").on("click", function(e){
          var pid=$("#pid").val();
          var valid_date=$("#valid_date").val();
          if(pid.length!=10){alert("身分证字号为10个字元");return;}
          if(valid_date.length==0){alert("请选择日期");return;}
          $.post({
            url: "http://tony1966.xyz/test/phptest/php_pdo_test_3_update.php",
            dataType: "html",
            data: {pid: pid, valid_date: valid_date},
            success: function(res) {
              alert(res);
              }
            });
          });
        $("#delete").on("click", function(e){
          var pid=$("#pid").val();
          if(pid.length!=10){alert("身分证字号为10个字元");return;}
          $.post({
            url: "http://tony1966.xyz/test/phptest/php_pdo_test_3_delete.php",
            dataType: "html",
            data: {pid: pid},
            success: function(res) {
              alert(res);
              }
            });
          });
        $("#read_all").on("click", function(e){
          $.get({
            url: "http://tony1966.xyz/test/phptest/php_pdo_test_2.php",
            dataType: "html",
            success: function(res) {
              $("#display").html(res);
              }
            });
          });
        });
    </script>
  </body>
</html>

此例使用了 HTML5 的 input[type=date] 元件来输入与显示日期, 透过五个按钮来进行 CRUD 操作, 关于 date 元件参考 :

# HTML5 的日期输入功能教学

按 "读取全部" 钮会透过 Ajax 向上面范例的 php_pdo_test_2.php 提出请求, 传回资料表 pid_valid_date 中的所有资料, 显示于 id=display 的 div 元件中, 结果如下 :





按 "读取" 会先检查有无输入长度为 10 个字元的身分证字号, 通过后会透过 Ajax 向后端程式 php_pdo_test_3_read.php 提交参数 pid, 查询结果为有效日期栏位 valid_date, 除了设定输入栏位外也会显示在 id=display 的 div 元素中.  

#php_pdo_test_3_read.php
<?php
header('Content-Type: text/html;charset=UTF-8');
//建立 PDO 连线物件
$dsn="mysql:host=mysql.hostinger.co.uk;port=3306;dbname=u137801000_test";
$username="u137801000_test";
$password="a123456";
try {$conn=new PDO($dsn, $username, $password);}
catch (PDOException $e) {
  echo "资料库连线错误!";
  die();
  }
//设定资料编码
$conn->exec("SET CHARACTER SET utf8");
$pid=$_REQUEST["pid"];
//读取资料表
$SQL="SELECT * FROM `pid_valid_date` WHERE pid='".$pid."'";
$RS=$conn->query($SQL);
//读取第一列资料 (传回关联式阵列)
$row=$RS->fetch();
echo $row["valid_date"];
//关闭资料库连线
$conn=NULL;
?>
按 "更新" 按钮会检查输入身分证字号与有效日期这两个栏位是否有输入合规之字串, 然后向后端程式 php_pdo_test_3_update.php 提交参数 pid 与 valid_date, 传回的结果字串会用 alert() 显示 :

#php_pdo_test_3_update.php
<?php
header('Content-Type: text/html;charset=UTF-8');
//建立 PDO 连线物件
$dsn="mysql:host=mysql.hostinger.co.uk;port=3306;dbname=u137801000_test";
$username="u137801000_test";
$password="a123456";
try {$conn=new PDO($dsn, $username, $password);}
catch (PDOException $e) {
  echo "资料库连线错误!";
  die();
  }
//设定资料编码
$conn->exec("SET CHARACTER SET utf8");
$pid=$_REQUEST["pid"];
$valid_date=$_REQUEST["valid_date"];
//读取资料表
$SQL="UPDATE `pid_valid_date` SET valid_date='".$valid_date."' ".
     "WHERE pid='".$pid."'";
$RS=$conn->query($SQL);
if($RS->rowCount() > 0) {echo "更新纪录成功";}
else {echo "更新纪录失败";}
//关闭资料库连线
$conn=NULL;
?>
按 "删除" 按钮会检查输入身分证字号栏位是否有输入合规之字串, 然后向后端程式 php_pdo_test_3_delete.php 提交参数 pid, 传回的结果字串会用 alert() 显示 :

#php_pdo_test_3_delete.php
<?php
header('Content-Type: text/html;charset=UTF-8');
//建立 PDO 连线物件
$dsn="mysql:host=mysql.hostinger.co.uk;port=3306;dbname=u137801000_test";
$username="u137801000_test";
$password="a123456";
try {$conn=new PDO($dsn, $username, $password);}
catch (PDOException $e) {
  echo "资料库连线错误!";
  die();
  }
//设定资料编码
$conn->exec("SET CHARACTER SET utf8");
$pid=$_REQUEST["pid"];
$valid_date=$_REQUEST["valid_date"];
//读取资料表
$SQL="DELETE FROM `pid_valid_date` WHERE pid='".$pid."'";
$RS=$conn->query($SQL);
if($RS->rowCount() > 0) {echo "删除纪录成功";}
else {echo "删除纪录失败";}
//关闭资料库连线
$conn=NULL;
?>
按 "新增" 按钮会检查输入身分证字号与有效日期这两个栏位是否有输入合规之字串, 然后向后端程式 php_pdo_test_3_create.php 提交参数 pid 与 valid_date, 传回的结果字串会用 alert() 显示 :

#php_pdo_test_3_create.php
<?php
header('Content-Type: text/html;charset=UTF-8');
//建立 PDO 连线物件
$dsn="mysql:host=localhost;port=3306;dbname=test";
$username="root";
$password="mysql";
try {$conn=new PDO($dsn, $username, $password);}
catch (PDOException $e) {
  echo "资料库连线错误!";
  die();
  }
//设定资料编码
$conn->exec("SET CHARACTER SET utf8");
$pid=$_REQUEST["pid"];
$valid_date=$_REQUEST["valid_date"];
//读取资料表
$SQL="INSERT INTO `pid_valid_date`(pid, valid_date) VALUES('".
     $pid."','".$valid_date."')";
$RS=$conn->query($SQL);
if($RS->rowCount() > 0) {echo "新增纪录成功";}
else {echo "新增纪录失败";}
//关闭资料库连线
$conn=NULL;
?>
使用 PDO 物件存取 MySQL 资料库感觉比传统的函数式操作要简单.

客服QQ:116622333

Copyright © 2018 Sucaimao.com 主题样式归智速电子商务所有 违者必追究法律责任