8.4. 使用 PHP 操作 MySQL

未匹配的标注

持之以恒,方得始终!

PHP 也是先连接 mysql,然后发送命令。也就是每次都要占用一次连接数的。

写一个搜索图书表单 search.html

<html>
<head>
    <title>图书搜索</title>
</head>
<body>
   <form action="results.php" method="post">
        <select name="searchtype">
                <option value="author">author</option>
                <option value="title">title</option>
                <option value="isbn">isbn</option>
        </select>
        <br>
        <input type="text" name="searchterm", size="40">
        <br>
        <input type="submit" name="submit" value="search">
   </form>
</body>
</html>

处理脚本 results.php

<html>
    <head>
        <title>搜索结果</title>
    </head>
    <body>
        <h1>搜索结果:</h1>
        <?php
        $searchtype = $_POST['searchtype'];
        $searchterm = trim($_POST['searchterm']);
        if(!$searchtype || !$searchterm) {
            echo "没有输入参数";
            exit;
        }

        // 下面的函数已废弃了
        /* if (!get_magic_quotes_gpc()) {
            $searchtype = addslashes($searchtype);
            $searchterm = addslashes($searchterm);
        } */

        // 连接到mysql
        @ $db = new mysqli('localhost', 'jerry', 'jerry123', 'books');

        // 如果连接报错
        if (mysqli_connect_errno()) {
            echo "连接mysql失败";
            exit;
        }

        $query  = "select * from books where ".$searchtype." like '%".$searchterm."%'";

        // 执行查询
        $result = $db->query($query);

        // 获取结果的条数
        $num_results = $result->num_rows;

        echo "<p>总共查到了 $num_results 本图书</p>";

        for ($i=0; $i < $num_results; $i++) {
            $row  = $result->fetch_assoc();
            echo "<p>第 " . ($i+1) . " 本 " . 
            " 书名-" . htmlspecialchars(stripslashes($row['title'])) . 
            " 作者-" . stripslashes($row['author']) . 
            " isnb-" . stripslashes($row['isbn']) . 
            " 价格-" . stripslashes($row['price']) . "</p><br>";    
        }

        $result->free();
        $db->close();
        ?>
    </body>
</html>

检查并过滤外部数据

  1. 过滤左右两边的空白字符
    $searchterm = trim($_POST['searchterm']);
  2. 检查外部数据是否非空值
    if (!$searchtype || !$serachterm) {}
  3. 过滤外部数据
    addslashes()
    stripslashes()
    htmlspecialchars()

建立一个连接

PHP 提供了 mysqli 库,我们可以用它来连接 mysql。

@ $db = new mysqli('主机地址', '用户', '密码', '库');

检查连接是否成功

if (mysqli_connect_errno()) {}

注意,MySQL 对同时连接数据库的连接数量有限制,参数 max_connections 决定了同时连接的个数。
还比如 apache 的参数 MaxClients
超过了限制,会让服务拒绝新的连接请求,避免系统忙碌或瘫痪时,系统资源被请求和使用。

它们在配置文件中,my.conf, httpd.conf, 可以修改它们。

选择一个库

上面代码中,实例化 mysqli类 时,已经把库传给了它的构造方法。
我们还可以这样

$db->select_db(dbname);

执行查询

// 写好 sql
$sql = "select * from books where ".$searchtype." like '%".$searchterm."%'";

// 执行查询
$result = $db->query($sql); // 返回一个结果对象

从结果对象中取数据

我们可以用不同的方法,从结果对象中取出需要的数据。

$num = $result->num_rows; // 获取结果的条数

for ($i = 0; $i < $num; $i++) {
    $row = $result->fetch_assoc(); // 返回的是数组
    $row = $result->fetch_row();
    $row = $result->fetch_object(); // 返回对象
}

断开连接

$result->free(); // 释放结果集
$db->close(); // 关闭连接

当然了,脚本结束,也会自动处理的。

数据入库

图书信息录入表单

<form action="insert_book.php" method="post">
isbn : <input type="text" name="isbn"> <br>
author: <input type="text" name="author"> <br>
title : <input type="text" name="title"> <br>
price : <input type="text" name="price"> <br>
<input type="submit" value="submit"> 
</form>

处理脚本 insert_book.php

// 接收参数
$isbn   = $_POST['isbn'];
$author = $_POST['author'];
$title  = $_POST['title'];
$price  = $_POST['price'];

// 检查参数
if (!$isbn || !$author || !$title || !$price) {
    echo "参数错误";
    exit;
}

// 过滤参数
/* if (!get_magic_quotes_gpc()) {
    $isbn   = addslashes($isbn);
    $author = addslashes($author);
    $title  = addslashes($title);
    $price  = doubleval($price);
} */

// 连接mysql
@ $db = new mysqli('localhost', 'jerry', 'jerry123', 'books');

if (mysqli_connect_errno()) {
    echo "连接失败";
    exit;
}

// 执行添加
$sql    = "insert into books values ('$isbn', '$author', '$title', $price)"; // 里面的变量是可以解析的
$result = $db->query($sql);

if ($result) {
    echo $db->affected_rows . "本书添加成功";
} else {
    echo "sql执行失败";
}

$db->close();

注意:对于 select 的查询,我们用 obj->num_rows 获取结果行数,对于 insert, delete, update , 要用 obj->affected_rows

使用 prepare

mysqli库支持 prepare,可以避免 sql 注入攻击。
我们来修改一下 insert_book.php 脚本:

$isbn   = $_POST['isbn'];
$author = $_POST['author'];
$title  = $_POST['title'];
$price  = $_POST['price'];

if (!$isbn || !$author || !$title || !$price) {
    echo "参数错误";
    exit;
}

@ $db = new mysqli('localhost', 'jerry', 'jerry123', 'books');
if (mysqli_connect_errno()) {
    echo "连接失败";
    exit;
}

$sql  = "insert into books values(?, ?, ?, ?)";
$stmt = $db->prepare($sql);
$stmt->bind_param("sssd", $isbn, $author, $title, $price); // sssd 对应 4个?替换参数的数据类型, s字符串, d是double,i是int , b是blob
$stmt->execute();

echo $stmt->affected_rows . "book inserted into database";

$stmt->close();

循环插入

绑定结果

对于 select 的查询,可以使用 $stmt->bind_result(),将查的值绑定到变量上。

每次调用 $stmt->fetch(),结果集下一行的列值,就会被赋值给这些绑定的变量中,

比如,前面的图书搜索脚本中:

$stmt->bind_result($isbn, $author, $title, $price);

将查询的4个列值,绑定到这四个变量上。
在调用 $stmt->execute() 后,可在循环中调用 $stmt->fetch(),每当该语句被调用时,它将获得下一个结果行,并填充到4个绑定变量中。
当然了 bind_param 和 bind_result 是可以一起用的。

使用 pear MDB2

我们可以用更统一的方式,来连接到不同的数据库,如 mysql,Oracle,postgresql。

  1. 下载 download.pear.php.net/package/MDB2-...

  2. 解压,放入图书项目下,重命名目录名称为 MDB2
    使用 PHP 操作 MySQL

  3. 重写之前的搜索图书脚本

如有任何侵权行为,请通知我删除,谢谢大家!
个人邮箱:865460609@qq.com

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
Junwind
讨论数量: 0
发起讨论 只看当前版本


暂无话题~