ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

借书网站小项目

2020-03-08 10:00:13  阅读:290  来源: 互联网

标签:function 项目 网站 db smarty pdo sql var 借书


在这里插入图片描述
网站的内容是在当当网上下载的图片作为页面的填充。
源代码获取:https://github.com/akh5/PHP/tree/master/library1.1

功能及实现代码

简介

    PHP实现的简单借书网站,能够进行用户的注册,登陆。可以根据图书类别,进行索引,可以根据书名进行查找,用户可以进行借书,还书,已经查看当前已借书籍


所用技术及运行环境

前端: HTML,CSS,JS
PHP: 设计模式->MVC,外部引擎->smarty
数据库: MySQL
集成环境: Wampserver


代码体量一览

在这里插入图片描述


功能介绍

轮播图模块

在这里插入图片描述
通过JS实现

var imgs = document.getElementsByClassName("images");
var left = document.getElementsByClassName("left")[0];
var right = document.getElementsByClassName("right")[0];
var len = imgs.length;
var current = 0;

function flip() {
    left.onclick = function () {
        current--;
        for(var i=0;i<imgs.length;i++){
            imgs[i].className='images';
        }
        if(current<0){
            current=imgs.length-1;
        }
        imgs[current].className='images active';
    }
    right.onclick = function () {
        current++;
        for(var i=0;i<imgs.length;i++){
            imgs[i].className='images';
        }
        if(current>imgs.length-1){
            current=0;
        }
        imgs[current].className='images active';
    }
}
flip();
setInterval(function () {
    current++;
    for(var i=0;i<imgs.length;i++){
        imgs[i].className='images';
    }
    if(current>imgs.length-1){
        current=0;
    }
    imgs[current].className='images active';
},3500)

通过修改选择器的方法显示,只有active的选择器可以显示图片,而向左向右的滚动,也就是将数组下标加一或减一,然后将当前的选择器加上active后代。而自动滚动,就是将向右的功能设定3.5秒的循环。

登陆注册模块

在这里插入图片描述
注册和登录窗口都是在一个页面内完成的,通设置display属性唤醒其中一个窗口并隐藏另一个窗口,通过表单传值进行数据库操作

var start = document.getElementsByClassName('icon')[0];
var shadow = document.getElementsByClassName('shadow')[0];
var regin = document.getElementsByClassName('regin')[0];
var sign = document.getElementsByClassName('sign')[0];
var close = document.getElementsByClassName('close');
var rsi = document.getElementById('rsi');

start.onclick=function () {
    shadow.style.display='block';
    regin.style.display='block';
}

rsi.onclick = function () {
    regin.style.display='none';
    sign.style.display='block';
}

close[0].onclick = function () {
    shadow.style.display='none';
    regin.style.display='none';
}
close[1].onclick = function () {
    shadow.style.display='none';
    sign.style.display='none';
}

查看账户模块

在这里插入图片描述

借书模块

在这里插入图片描述
在这里插入图片描述


代码介绍

Frame

Libs

在Libs文件夹中存放操作相同,且重复使用多次的代码,用抽象类对其进行封装,分为BaseController,和BaseModel的抽象类,以后所有的控制器,和模型类都要继承这两个抽象类

BaseController主要封装了smarty对象,并设定其左右界限符

<?php
namespace Frame\Libs;

abstract class BaseController
{

    protected $smarty = null;

    public function __construct()
    {
        //创建smarty对象
        $smarty = new \Frame\Vendors\Smarty();
        $smarty->left_delimiter = "<{";
        $smarty->right_delimiter = "}>";
        $smarty->setCompileDir(sys_get_temp_dir().DS."blog_t".DS);
        $smarty->setTemplateDir(VIEW_PATH);
        $this->smarty = $smarty;
        
    }
}

BaseMooule主要封装了pdo对象,方便以后所有的数据库操作

<?php
namespace Frame\Libs;

abstract class BaseModel
{
    protected $pdo = null;
    public function __construct()
    {
        $this->pdo = new \Frame\Vendors\PDOWrapper();
        
    }

    public static function getInstance()
    {
        $modelClassName = get_called_class();
        return new $modelClassName();
    } 
}

Vendor

Vendor文件夹中,除了放置smarty外,主要还封装了我们自己定义的PDO类,通过找到当前的数据库config,提前实例化pdo类

<?php
namespace Frame\Vendors;
use \PDO;
use \Exception;
use \PDOException;

final class PDOWrapper
{
    private $db_type;
    private $db_host;
    private $db_port;
    private $db_user;
    private $db_pass;
    private $db_name;
    private $charset;
    private $pdo = null;

    public function __construct()
    {
        $this->db_type = $GLOBALS['config']['db_type'];
        $this->db_host = $GLOBALS['config']['db_host'];
        $this->db_port = $GLOBALS['config']['db_port'];
        $this->db_user = $GLOBALS['config']['db_user'];
        $this->db_pass = $GLOBALS['config']['db_pass'];
        $this->db_name = $GLOBALS['config']['db_name'];
        $this->charset = $GLOBALS['config']['charset'];
        $this->createPDO(); //创建PDO对象
        $this->setErrMode();//设定报错模式
    }

    private function createPDO()
    {
        try{
            $dsn = "{$this->db_type}:host={$this->db_host};port={$this->db_port};dbname={$this->db_name};charset={$this->charset}";
            $this->pdo = new \PDO($dsn,$this->db_user,$this->db_pass);
        }catch(PDOException $e)
        {
            echo "<h2>创建pdo失败</h2><br>";
            echo "错误行号".$e->getLine()."<br>";
            echo "错误文件".$e->getFile()."<br>";
            echo "错误信息".$e->getMessage()."<br>";
            die();
        }
    }
    private function setErrMode()
    {
        $this->pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    }

    public function exec($sql)
    {
        try{
            return $this->pdo->exec($sql);
        }catch(PDOException $e)
        {
            $this->showErr($e);
        }
    }
    public function fetchOne($sql)
    {
        try{
            $PDOStatement = $this->pdo->query($sql);
            return $PDOStatement->fetch(PDO::FETCH_ASSOC);
        }catch(PDOException $e)
        {
            $this->showErr($e);
        }
    }
    public function fetchAll($sql)
    {
        try{
            $PDOStatement = $this->pdo->query($sql);
            return $PDOStatement->fetchAll(PDO::FETCH_ASSOC);
        }catch(PDOException $e)
        {
            $this->showErr($e);
        }
    }
    public function rowCount($sql)
    {
        try{
            $PDOStatement = $this->pdo->query($sql);
            return $PDOStatement->rowCount();
        }catch(PDOException $e)
        {
            $this->showErr($e);
        }
    }
    private function showErr($e)
    {
        echo "<h2>执行sql语句失败</h2>";
        echo "错误行号".$e->getLine();
        echo "错误文件".$e->getFile();
        echo "错误信息".$e->getMessage();
        die();
    }
}

Frame.class.php

最重要的是Frame类,是当前网站所有功能运行的基础,类中封装了类的自动加载器,并初始化config文件,通过地址传值的方式,自动调用相应的控制器,及其控制器中的方法
我们通过地址中传入的?c=控制器前缀&a=控制器方法然后取到控制器前缀并拼接上Controller字符串就能在控制器作用域中找到相应的控制器类

<?php
namespace Frame;
final class Frame
{
    public static function run()
    {
        self::initConfig();
        self::initRoute();
        self::initConst();
        self::initAutoLoad();
        self::initDispath();
    }
    private static function initConfig()
    {
        $GLOBALS['config'] = require_once(APP_PATH."Conf".DS."Config.php");
    }
    private static function initRoute()
    {
        $p = $GLOBALS['config']['default_platform'];
        $c = isset($_GET['c']) ? $_GET['c']:$GLOBALS['config']['default_controller'];
        $a = isset($_GET['a']) ? $_GET['a']:$GLOBALS['config']['default_action'];
        define('PLAT',$p);
        define('CONTROLLER',$c);
        define('ACTION',$a);    
    }
    private static function initConst()
    {
        define('VIEW_PATH',APP_PATH.'View'.DS.CONTROLLER.DS);
        
    }
    private static function initAutoLoad()
    {
        spl_autoload_register(function($className)
        {
           $filename =  ROOT_PATH.str_replace('\\',DS,$className).".class.php";
           if(file_exists($filename))
           require_once($filename);
        });
    }
    private static function initDispath()
    {
        $controllerClassName = PLAT.'\\'.'Controller'.'\\'.CONTROLLER."Controller";
        $controllerObj = new $controllerClassName;

        $action_name = ACTION;
        $controllerObj->$action_name();
   	}
}

Home

Home中存放控制器(Controller),模型(Model),视图(View)文件,控制器中主要是与视图结合,用户操作的界面,模型类中主要是数据库操作

Controller

Index是默认入口,也是页面打开最先展示的

<?php
namespace HOME\Controller;

use Frame\Libs\BaseController;
use Home\Model\IndexModel;
use Home\Model\SignModel;

final class IndexController extends BaseController
{
    public function index()
    {
        $modelObj = IndexModel::getInstance();
        //$this->smarty->assign("arrs",$arrs);
        $modelObj->regin();
        $this->smarty->display(APP_PATH.DS."View".DS."Library.html");
    }
    public function sign()
    {
        $modelObj = SignModel::getInstance();
        $modelObj->sign();
    }
}

index()方法中用smarty加载视图文件,而登陆时账号的验证方法,在方法中通过其对应的Model对象完成,而sign()方法,只有当地址传值?a=sign时调用,对应的就是注册的数据库方法


user控制器中,是当登陆验证成功后的可交互页面,通过session显示当前用户,搜索和类别操作,通过地址传递?b=类别 ?bn=书名传递相应的查找条件

<?php
 namespace HOME\Controller;

 use \Frame\Libs\BaseController;
 
 final class userController extends BaseController
 {
     public function index()
     {
        //  $modelObj = IndexModel::getInstance();
        $this->smarty->assign('username',$_SESSION['username']);
        $this->smarty->display(APP_PATH.DS."View".DS."user.html");
        if(isset($_POST['b']))
        {
            $bookcate = $_POST['b'];
            header("Location:?c=lend&b={$bookcate}");
        } if(isset($_POST['sear']))
        {
            $bookname = $_POST['sear'];
            header("Location:?c=lend&bn={$bookname}");
        } 
     }
 }

lend控制器主要作用就是显示查找到的书籍

<?php
namespace HOME\Controller;

use \Frame\Libs\BaseController;
use \Home\Model\lendModel;
 
 final class lendController extends BaseController
 {
     public function index()
     {
        $modelObj = lendModel::getInstance();
        if(isset($_GET['b']))
        {
            $arr = $modelObj->lend();
        }
        if(isset($_GET['bn']))
        {
            $arr = $modelObj->lendByname();
        }
        $this->smarty->assign('arrs',$arr);
        $this->smarty->display(APP_PATH.DS."View".DS."lend.html");   
     }
 }

borrow控制器中有借书和还书的相应方法通过地址传递?a=borrow,或?a=back来判断是借书还是还书操作

<?php
namespace HOME\Controller;
use \Frame\Libs\BaseController;
use \Home\Model\borrowModel;

final class borrowController extends BaseController
{
    public function index()
    {
       $modelObj = borrowModel::getInstance();
       $arr = $modelObj->show();
    //    var_dump($arr);
       $this->smarty->assign('username',$_SESSION['username']);
       $this->smarty->assign('arrs',$arr);
       $this->smarty->display(APP_PATH.DS."View".DS."borrow.html");
    }
    public function borrow()
    {
       $modelObj = borrowModel::getInstance();
       $modelObj->borrow();
       $arr = $modelObj->show();
    //    var_dump($arr);
       $this->smarty->assign('username',$_SESSION['username']);
       $this->smarty->assign('arrs',$arr);
       $this->smarty->display(APP_PATH.DS."View".DS."borrow.html");
    }
    public function back()
    {
       $modelObj = borrowModel::getInstance();
       $modelObj->back();
       $arr = $modelObj->show();
    //    var_dump($arr);
       $this->smarty->assign('username',$_SESSION['username']);
       $this->smarty->assign('arrs',$arr);
       $this->smarty->display(APP_PATH.DS."View".DS."borrow.html");
    }
}

Model

Model中是具体的pdo操作数据库方法
IndexModel验证当前是否登陆,已经检查登陆是否正确的操作

<?php
namespace Home\Model;
use \Frame\Libs\BaseModel;

class IndexModel extends BaseModel
{
    public function regin()
    {
        if(isset($_POST['submit'])){
            $name=$_POST['racc'];//post获取表单里的name
            $password=$_POST['rpass'];//post获取表单里的password
            $sql = "select password from user where account='$name'";
            $pass=$this->pdo->fetchOne($sql);
            if($password!=$pass['password'])
            {
             echo "<script>alert('用户名或密码错误')</script>";

            }else{
                $_SESSION['username'] = $name;
                $_SESSION['password'] = $password; 
                
                header("Location:?c=user");
            }   
        }
    }
}

登陆成功后,会将用户名和密码存入session当中,以便之后操作


signModel中通过插入语句进行注册操作

namespace Home\Model;
use \Frame\Libs\BaseModel;

class SignModel extends BaseModel
{
    public function sign()
    {
        if(!isset($_POST['submit'])){
           exit("错误执行");
        }//判断是否有submit操作
            
        $name=$_POST['sacc'];//post获取表单里的name
        $password=$_POST['spass'];//post获取表单里的password

        $sql = "INSERT INTO user(account,password) VALUES('{$name}','{$password}')";
        $res = $this->pdo->exec($sql);
        if($res){
            echo "<script>alert('注册成功')</script>";
            
            header("Location:index.php");
            }else{
                echo $name;
                echo $password;
                var_dump($res);
                echo mysqli_errno($res);
            }    
    }
}

lendModel查找相应书籍,相对简单通过fetchall方法

<?php
namespace Home\Model;
use \Frame\Libs\BaseModel;

class lendModel extends BaseModel
{
    public function lend()
    {
        
       $bookcate = $_GET['b'] ;
       $sql = "SELECT * FROM books WHERE Category='$bookcate' AND SurplusQuantity>0";
       return $this->pdo->fetchAll($sql);
    }
    public function lendByname()
    {
       $bookname = $_GET['bn'] ;
       $sql = "SELECT * FROM books WHERE BookName='$bookname' AND SurplusQuantity>0";
       return $this->pdo->fetchAll($sql);
    }
}

borrowModel,借书与还书,都是通过书名查找,并通过+1或-1操作对其修改,并将用户名和书名同时插入到另一个表当中。
<?php
namespace Home\Model;
use \Frame\Libs\BaseModel;

class borrowModel extends BaseModel
{
    public function borrow()
    {
		$name = $_SESSION['username'];
		$bookname = $_GET['bn'];
		$sql1 = "SELECT * FROM books WHERE BookName='$bookname'";
		$arr = $this->pdo->fetchOne($sql1);
		$newnumber = $arr['SurplusQuantity']-1;
		$sql2 = "UPDATE books SET SurplusQuantity = '$newnumber' WHERE BookName='$bookname'";
		$this->pdo->exec($sql2);
		$sql3 = "INSERT INTO userbook(user,BookName) VALUES('$name','$bookname') ";
		$this->pdo->exec($sql3);
	}
	public function show()
	{
		$name = $_SESSION['username'];
		$sql = "SELECT BookName FROM userbook WHERE user='$name'";
		return $this->pdo->fetchAll($sql);
	}
	public function back()
	{
		$name = $_SESSION['username'];
		$bookname = $_GET['bn'];
		$sql1 = "SELECT * FROM books WHERE BookName='$bookname'";
		$arr = $this->pdo->fetchOne($sql1);
		$newnumber = $arr['SurplusQuantity']+1;
		$sql2 = "UPDATE books SET SurplusQuantity = '$newnumber' WHERE BookName='$bookname'";
		$this->pdo->exec($sql2);
		$sql3 = "DELETE FROM userbook WHERE BookName='$bookname'AND user='$name' ";
		$this->pdo->exec($sql3);
	}
}

标签:function,项目,网站,db,smarty,pdo,sql,var,借书
来源: https://blog.csdn.net/MPF1230/article/details/104724548

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有