php+mysql 图书管理系统

1、实验目的

设计并实现一个精简的图书管理系统,要求具有图书入库、查询、借书、还书、借书证管理等功能。

2、实验平台

  • WAMP
  • win 10
  • mysqli

3、系统需求分析

基本数据对象

  • 书(书号、类别、书名、出版社、年份、作者、价格、总藏书量、库存)
  • 借书证(卡号、姓名、单位、类别(学生/教师))
  • 管理员(管理员ID,密码,姓名,联系方式)
  • 结束记录(书号、借书证号、借期、还期、经手(管理员id))

基本功能模块

管理员登录

输入管理员ID, 密码; 登入系统 或 返回ID/密码 错误.

图书入库

  1. 单本入库
  2. 批量入库 (方便最后测试)
    图书信息存放在文件中, 每条图书信息为一行. 一行中的内容如下
    ( 书号, 类别, 书名, 出版社, 年份, 作者, 价格, 数量 )
    Note: 其中 年份、数量是整数类型; 价格是两位小数类型; 其余为字符串类型
    Sample:
    ( book_no_1, Computer Science, Computer Architecture, xxx, 2004, xxx, 90.00, 2 )

图书查询

要求可以对书的 类别, 书名, 出版社, 年份(年份区间), 作者, 价格(区间) 进行查询. 每条图书信息包括以下内容:
( 书号, 类别, 书名, 出版社, 年份, 作者, 价格, 总藏书量, 库存 )

可选要求: 可以按用户指定属性对图书信息进行排序. (默认是书名)

借书

  1. 输入借书证卡号
    显示该借书证所有已借书籍 (返回, 格式同查询模块)
  2. 输入书号
    如果该书还有库存,则借书成功,同时库存数减一。
    否则输出该书无库存,且输出最近归还的时间。

还书

1.输入借书证卡号
显示该借书证所有已借书籍 (返回, 格式同查询模块)
2.输入书号
如果该书在已借书籍列表内, 则还书成功, 同时库存加一.
否则输出出错信息.

借书证管理

增加或删除一个借书证.

4、系统设计

4.1 总体设计

采用简单粗暴的MV(视图-模型)这一系统模型,在视图端(浏览器)发送请求,服务器处理这一请求并返回数据,视图接受数据并显示到视图中。
php+mysql 图书管理系统_第1张图片

4.2 数据库表结构设计

表定义

create table book
(
	bno char(8),
    category char(10),
    title varchar(40),
    press varchar(30),
    year int,
    author varchar(20),
    price decimal(7,2),
    total int,
    stock int,
    primary key(bno)
);

create table card
(
	cno char(7),
    name varchar(10),
    department varchar(40),
    type char(1),
    primary key(cno),
    check (type in ('T','S'))
);

create table admin
(
	admin_id char(20),
	password char(20),
	name char(20),
	email char(30),
	primary key(admin_id)
);

create table borrow
(
	cno char(7),
    bno char(8),
    borrow_date date,
    return_date date,
    done_by char(20),
    foreign key (bno) references book(bno) on delete cascade,
    foreign key (cno) references card(cno) on update cascade
);

但是,mysql的check是无用的,使用触发器来实现check功能:

DELIMITER $$
create trigger type_check_triger before insert on card
for each row
begin
	if(new.type not in ('T','S'))
	then 
		signal sqlstate '04922'
		set message_text = "ERROR: card type not in ('T','S')";
	end if;
end $$
DELIMITER ;

4.3 管理员登录模块

首先进入主页,选择(管理员/查询)这两个功能之一。由于普通用户只能进行查询功能,就不需要它们登录了。

这里使用的是html的radio表单:

ADMIN USER

php脚本根据表单提交选择用户查询界面或者登录界面:

 
	$choseerror="";
	$chose="";
	if($_SERVER["REQUEST_METHOD"] == "POST"){
		if(empty($_POST['q'])){
			$choseerror = "必须选择访问身份";
		} else {
			$chose=$_POST['q'];
			if($chose=="admin"){
				header("location:login.php");
			}else{
				header("location:query.php");
			}
		}
	}
?>

登录界面如下图:

选择admin身份,进入登录界面,输入账号和密码:

这个初始的账号是我在创建数据库的时候创建的:
php+mysql 图书管理系统_第2张图片
在登录界面的login.php中,首先和数据库建立连接,这里我使用了mysqli这个mysql拓展来连接。在连接的过程中有一点要注意的是,由于wamp默认了mariadb,所以你在连接的时候要指定mysql服务器的端口号。我就是在连接时找不到我创建的book数据库,然后在这了卡了很久。


    $server_name="localhost";
    $username="root";
    $password="qazwsx";
    $dbname="book";
    $conn = new mysqli($server_name,$username,$password,$dbname,'3308');

    if ($conn->connect_error) {
        die("连接失败: " . $conn->connect_error);
    } 
?>

之后再从book数据库中,select看看是否有表单输入的账户id和pwd,按情况分别处理:

        include 'connect.php';
        $id=$_POST['account'];
        $pwd=$_POST['password'];
        $sql_query="select * from admin where admin_id='".$id."' and password = '".$pwd."'";
        $sql=$conn->query($sql_query);
        $info=mysqli_fetch_array($sql);
        if($info==false){
            $loginerror = "ID或PWD错误!";
        }else{
            $_SESSION['admin_id']=$id;
            $_SESSION['pwd']=$pwd;
            header("location:index.php");
        }

账号密码错误提示:ID或PWD错误

登录成功后跳转到index.php界面。

index界面选择所需要执行的功能。

4.4 图书入库模块

4.4.1单本入库

使用一个表单,submit后做出判断,如果是需要的格式就插入到数据库。
所谓对格式做出判断,一是要求非空,二是要求year,num是整形,price是两位小数:

//出版年份
        if (empty($_POST["year"]))
        {
            $yearErr = "必需";
            $tbool=false;
        }
        else    
        {
            $year = test_input($_POST["year"]);
            if (!preg_match("/^[0-9]*$/",$year))
            {
                $yearErr = "只允整数";
                $tbool=false; 
            }
        }

//价格
        if (empty($_POST["price"]))
        {
            $priceErr = "必需";
            $tbool=false;
        }
        else    
        {
            $price = test_input($_POST["price"]);
            if (!preg_match("/^([0-9]*)+(.[0-9]{1,2})?$/",$price))
            {
                $priceErr = "decimal(7.2)"; 
                $tbool=false;
            }
        }

另外要考虑到:如果管理员入库一本馆藏中有的书,那么就不是insert而需要update。于是先做出判断:

        $sql_query="select * from book where bno='".$bno."'";
        $sql=$conn->query($sql_query);
        $info=mysqli_fetch_array($sql);
        if($info==false){
            //并不存在这一本书
            ...
        }else{
            //这本书已经在馆藏中了
            ...
        }

单本插入(无该书馆藏):

插入结果,在命令行中查看:
php+mysql 图书管理系统_第3张图片
已经有馆藏了,继续插入:

命令行select显示新的4本也被入库:
php+mysql 图书管理系统_第4张图片

4.4.2 批量入库

图书信息存在一个文件种,提交文件名:

批量插入后表如下:
php+mysql 图书管理系统_第5张图片
同样,在有藏书的情况下再次入库:
php+mysql 图书管理系统_第6张图片
批量导入和单本导入的差别并不大,主要涉及到对文件及字符串的处理:


			...省略

            $filename=$_POST['filename'];
            $file=fopen($filename,"r") or exit("无法打开文件".$filename);
            while(!feof($file))
            {
                $line = fgets($file);
                $line = test_input($line);
                if($line=="") continue;
                $line = mb_substr($line,1,mb_strlen($line)-2);
                $array = explode(",",$line);
                $bno=$array[0];...省略其它赋值
                include 'connect.php';
                //首先看看是否已经存在了这一本书,如果存在,则update,否则就是insert
                $sql_query="select * from book where bno=".$bno."";
                $sql=$conn->query($sql_query);
                $info=mysqli_fetch_array($sql);
                if($info==false){
                //并不存在这一本书
                ...
                }else{
                //这本书已经在馆藏中了
                ...
                }
			...省略
?>

4.4 图书查询模块

设置一个表单、收集需要的复合查询项。在php中将表单post的值进行处理,此处以price为例。当左/右区间为空时、设置为默认[0,9999.99]。检测值是否符合正则表达式、组装sql语句:

        if (!empty($_POST["pricel"]))
        {
            $pricel = test_input($_POST["pricel"]);
            if (!preg_match("/^([0-9]*)+(.[0-9]{1,2})?$/",$pricel))
            {
                $queryErr = $queryErr."价格左区间应当是decimal(7.2)形式!"; 
                $tbool=false;
            }
        }
        if(!empty($_POST["pricer"]))
        {
            $pricer = test_input($_POST["pricer"]);
            if (!preg_match("/^([0-9]*)+(.[0-9]{1,2})?$/",$pricer))
            {
                $queryErr = $queryErr."价格右区间应当是decimal(7.2)形式!"; 
                $tbool=false;
            }
        }
        if($pricel > $pricer){
            $queryErr = $queryErr."价格左区间应当小于右区间!";
            $tbool=false;
        }else{
            $sql_query=$sql_query." and price between ".$pricel." and ".$pricer." ";
        }

查询输入出错:
应当左区间小于右区间且符合格式:
php+mysql 图书管理系统_第7张图片
复合查询:
类别为小说、出版年份大于2000,价格小于40,按照出版年份排序:

4.5 借书模块

对于借书,首先判断借书证号是否存在,不存在则输出错误信息:

//测试是否有该借书证
            $sql_query="select * from card where cno = '".$cno."'";
            //echo $sql_query;
            $sql=$conn->query($sql_query);
            $info=mysqli_fetch_array($sql);
            if($info==false){
                //并不存在这一借书证号
                $borrowErr.="借书证".$cno."不存在!";
            }else{
            ...
            }

php+mysql 图书管理系统_第8张图片
然后判断所借的书是否非空,非空则判断是否已经借了这本书,
若没有借这本书,是否还有库存,如果没有库存,最近一次归还日期(实验要求的,我也不知道这个有啥用)

                if(!empty($_POST["bno"])){
                    $bno=$_POST["bno"];
                    $sql_query="select * from borrow natural join book where cno = '".$cno."' and bno = '".$bno."' and return_date is null";
                    $sql=$conn->query($sql_query);
                    $info=mysqli_fetch_array($sql);
                    //echo $sql_query;
                    //print_r($info);
                    if($info==false){
                        //没有借这本书
                        $sql_query="select * from book where bno = '".$bno."'";
                        $sql=$conn->query($sql_query);
                        $info=mysqli_fetch_array($sql);
                        if($info==false){
                            $borrowErr.="该书不存在";
                        }else{
                            $tmpstock=$info[8];
                            if($tmpstock=="0"){
                                $sql_query="select return_date from borrow where bno = '".$bno."' order by return_date desc";
                                $sql=$conn->query($sql_query);
                                $info=mysqli_fetch_array($sql);
                                $last_re_date = $info[0];
                                $borrowErr.= "该书库存为0!最近一次归还日期为:
"
.$last_re_date; }else{ //从book的stock中减少一本 $sql_query="update book set stock = ".$tmpstock." -1 where bno = '".$bno."'"; //echo $sql_query; $sql=$conn->query($sql_query); //向borrow记录插入一本书 $sql_query="insert into borrow values('".$cno."','".$bno."','".date("Y-m-d")."',null,'".$id."')"; //echo $sql_query; $sql=$conn->query($sql_query); } } }else{ //echo "hello"; $borrowErr.="已经有一本了,给别人留点吧!"; } }

书不存在
php+mysql 图书管理系统_第9张图片
已经有了一本
php+mysql 图书管理系统_第10张图片
没库存了:
php+mysql 图书管理系统_第11张图片

4.6 还书模块

还书模块的要求与借书模块基本相近。
显示已经借的书籍:
php+mysql 图书管理系统_第12张图片
还书(bno=1)之后:
php+mysql 图书管理系统_第13张图片
还一本没有借的书:
php+mysql 图书管理系统_第14张图片

4.7 借书证管理

我们用一个表单来收集一个card tuple所需要的属性,一个单选radio来选择功能(添加/删除)。
对于插入,判断是否已经存在了一个相同的卡号,如果已存在,则输出错误信息。否则insert插入:

                if($fun=="add"){
                    if($info==false){
                        //插入
                        $sql_query="insert into card values('".$cno."','".$name."','".
                        $department."','".$type."')";
                        $conn->query($sql_query);
                    }else{
                        //已经存在卡号
                        $cardErr.="卡号已存在,无法添加!";
                    }
                }

账号已存在:
php+mysql 图书管理系统_第15张图片
插入成功:
php+mysql 图书管理系统_第16张图片
输入信息不足:
php+mysql 图书管理系统_第17张图片
对于删除,也是先查看卡号是否存在。如果存在且该卡号还有未归还的书籍,那么输出错误信息,否则删除。

                    if($info==false){
                        //不存在
                        $cardErr.="没有符合条件的卡号";
                    }else{
                        //已经存在卡号,是否有没有还的书
                        $sql_query="select * from borrow natural join book where cno = '".
                        $cno."' and return_date is null";
                        $sql=$conn->query($sql_query);
                        $info=mysqli_fetch_array($sql);
                        if($info==false){
                            //没有没还的书,可以删除
                            $sql_query="delete from card where cno = '".$cno."'";
                            $sql=$conn->query($sql_query);
                        }else{
                            //还不能删除
                            $cardErr.="还有未归还的书!";
                        }
                    }

查看卡号是否存在:
php+mysql 图书管理系统_第18张图片
删除成功:
php+mysql 图书管理系统_第19张图片
无法删除一个有借书信息的卡号:
php+mysql 图书管理系统_第20张图片

4.8 账户登出

清空session,跳转到首页。


	session_start();
	$_SESSION = array();
	if (isset($_COOKIE[session_name()])) {
		setcookie(session_name(),'',time()-42000,'');
	}
	session_destroy();
	header("location:home.php");
?>

5、总结

总共花了3天,摸索着学html、css、php,最后终于弄出来了这个数据库的期中实验项目,真的困难。
另外代码这个学期不会放出(毕竟要交作业,查重恐怖)

学期结束,代码:https://download.csdn.net/download/baidu_40614951/12549363

你可能感兴趣的:(数据库)