Web开发 | ThinkPHP 3.2.3 - 04.ThinkPHP与数据库2

本文详细介绍了ThinkPHP 3.2.3中的数据库操作,包括聚合函数、添加数据记录(数组方式和AR方法)、收集表单数据、数据修改、删除数据及原生SQL执行。讲解了having()、where()方法的区别,以及count(), sum(), avg(), max(), min()等聚合函数的使用。同时,展示了如何通过create()方法实现表单数据收集,以及save()方法的注意事项。此外,还涉及到了商品信息的修改和表单验证的实现。" 126713150,8753399,C#泛型AVLTree实现及完整源码解析,"['C#开发', '数据结构与算法', '哈希算法']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.聚合函数及having使用细节

$info = $goods -> where() -> field(字段) -> select();

select()方法

  1、返回一个二维数组信息
  2、返回全部数据表信息
  3、给该方法传递参数
    1) select(20) 查询主键值等于30的记录信息
    2) select(“20,21,22,23”); 查询主键值等于20,21,22,23的记录信息
  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    public function showlist(){
        $goods = D("Goods");
        //查询主键值等于30的记录信息
        //$info = $goods -> select(30);
        //查询主键值等于20,21,22,23的记录信息
        $info = $goods -> select("20,21,22,23");
        //把数据assign到模板
        $this -> assign('info',$info);
        $this->display();
    }

  4、find()如果我们查询的结果只有一个信息,使用select()会返回一个二维数组,为了使用方便我们可以返回一个一维数组,这时候可使用find()方法
  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    public function showlist(){
        $goods = D("Goods");
        $info = $goods -> find(30); //返回一维数组结果
        show_bug($info);
        $this->display();
    }

  5、having()方法设置查询条件,where()方法设置查询条件

having()和where()区别

  1)、使用有先后顺序
  2)、where price>100 having price>100
  3)、where设置条件,字段必须是数据表中存在的字段
  4)、having设置条件,字段必须是selec语句查询出来的字段

        //两者都能使用的情况
        select goods_price,goods_number from sw_goods where goods_price>100   //正确
        select goods_price,goods_number from sw_goods having goods_price>100   //正确

        //只可以使用where,不可以使用having
        select goods_name,goods_number from sw_goods where goods_price>100   //正确
        select goods_name,goods_number from sw_goods having goods_price>100   //错误

        //只可以使用having,不可以使用where
        //查询每种goods_category_id商品的价格平均值,获得平均价格大于1000的种类信息
        select goods_category_id,avg(goods_price) as ag from sw_goods where ag>1000 group by goods_category_id   //错误
        select goods_category_id,avg(goods_price) as ag from sw_goods group by goods_category_id having ag>1000   //正确

  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    public function showlist(){
        $goods = D("Goods");
        $info = $goods -> having('goods_price > 1000') -> select();
        //把数据assign到模板
        $this -> assign('info',$info);
        $this->display();
    }

  6、相关聚合函数 count() sum() avg() max() min()
    以上聚合函数是最后被调用的方法,可以结合具体条件方法使用
  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    public function showlist(){
        $goods = D("Goods");
        //查询记录总条数
        echo $goods -> count();
        echo "<br/>";
        //获得价格最高的商品信息
        echo $goods -> max('goods_price');
        echo "<br/>";
        //获得价格大于1000的商品总数
        echo $goods -> where('goods_price > 1000') -> count();
        echo "<br/>";

        //此时limit()不起效果
        //运行时默认为limit(1)
        echo $goods -> limit(5) -> where('goods_price > 1000') -> count();

        //把数据assign到模板
        $this -> assign('info',$info);
        $this->display();
    }

2.添加数据记录add

两种方式实现数据添加
两种方式都返回被添加的新记录的主键id值

数组方式实现数据添加

  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    //添加商品
    public function add(){
        //利用数组方式实现数据添加
        $goods = D("Goods");
        $ar = array(
                'goods_name' => '红米Pro',
                'goods_price' => 1000,
                'goods_number' => 53,
            );
        //goods_name、goods_price、goods_number是数据表中字段名称
        $rst = $goods -> add($ar);
        show_bug($rst);
        if ($rst > 0) {
            echo "success";
        }else{
            echo "failure";
        }

        $this->display();
    }
AR方法实现数据添加

TP框架中的AR是假的,但是可以实现

  1、ActiveRecord 活跃记录
  2、AR规定了程序与数据库之间的关系
    1)、一个数据表对应一个类Model
    2)、一条数据记录对应类的一个对象
    3)、每个字段对应该对象的具体属性

  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    //添加商品
    public function add(){

        //利用AR方式实现数据添加
        $goods = D("Goods");
        $goods -> goods_name = '红米';
        $goods -> goods_price = 1200;
        $goods -> goods_number = 53;

        $rst = $goods -> add($ar);
        show_bug($rst);
        if ($rst > 0) {
            echo "success";
        }else{
            echo "failure";
        }

        $this->display();
    }

3.收集表单数据并实现收集添加

制作一个表单

  shop/Admin/View/Goods/add.html
程序代码如下:

        /* 常量__SELF__对应的路径为:ThinkPHP/shop/index.php/Admin/Goods/add */
        <form action="{$smarty.const.__SELF__}" method="post" enctype="multipart/form-data">
            <table border="1" width="100%" class="table_a">
                <tr>
                    <td>商品名称</td>
                    <td><input type="text" name="goods_name" /></td>
                </tr>
                <tr>
                    <td>商品价格</td>
                    <td><input type="text" name="goods_price" /></td>
                </tr>
                <tr>
                    <td>商品数量</td>
                    <td><input type="text" name="goods_number" /></td>
                </tr>
                <tr>
                    <td>商品重量</td>
                    <td><input type="text" name="goods_weight" /></td>
                </tr>
                <tr>
                    <td>商品详细描述</td>
                    <td>
                        <textarea name="goods_introduce"></textarea>
                    </td>
                </tr>

                <tr>
                    <td colspan="2" align="center">
                        <input type="submit" value="添加">
                    </td>
                </tr>  
            </table>
            </form>
通过$_POST收集信息

  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    public function add(){
        //两个逻辑:1、展现表单;2、接受表单数据
        //echo __SELF__;
        //该常量对应的路径为:ThinkPHP/shop/index.php/Admin/Goods/add
        if (!empty($_POST)) {
            //输出_POST信息
            print_r($_POST);
        } else {
            $this->display();
        }   
    }

  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    public function add(){
        //两个逻辑:1、展现表单;2、接受表单数据
        $goods = D("Goods");
        if (!empty($_POST)) {
            $ar = $_POST;
            $z = $goods -> add($ar);
            if ($z) {
                echo "success";
            } else {
                echo "failure";
            }
        } else {
            $this->display();
        }   
    }

当表单数据信息存在的字段与数据表字段不同时候,需要使用AR方式进行添加

  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    public function add(){
        //两个逻辑:1、展现表单;2、接受表单数据
        $goods = D("Goods");
        if (!empty($_POST)) {
            $goods -> goods_name = $_POST['goods_name'];
            $goods -> goods_price = $_POST['goods_price'];
            $goods -> goods_number = $_POST['goods_number'];
            $goods -> goods_weight = $_POST['goods_weight'];
            $goods -> goods_introduce = $_POST['goods_introduce'];
            $z = $goods -> add($ar);
            if ($z) {
                echo "success";
            } else {
                echo "failure";
            }
        } else {
            $this->display();
        }   
    }
通过create()方法实现数据收集

  使用AR方式时,当有相对多的字段进行添加,可以使用create()方法实现数据收集,并且对于非法的字段会自动进行过滤
  数据模型对象 -> create()

  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    public function add(){
        //两个逻辑:1、展现表单;2、接受表单数据
        $goods = D("Goods");
        if (!empty($_POST)) {
            $goods -> create();
            $z = $goods -> add($ar);
            if ($z) {
                echo "success";
            } else {
                echo "failure";
            }           
        } else {
            $this->display();
        }   
    }

  ThinkPHP/Library/Think/Model.class.php
程序代码如下:

    /**
     * 创建数据对象 但不保存到数据库
     * @access public
     * @param mixed $data 创建数据
     * @param string $type 状态
     * @return mixed
     */
     public function create($data='',$type='') {
        // 如果没有传值默认取POST数据
        if(empty($data)) {
        // 收集post表单数据并传递给$data
            $data   =   I('post.');
        ...
        // 验证完成生成数据对象
        if($this->autoCheckFields) { // 开启字段检测 则过滤非法字段数据
            $fields =   $this->getDbFields();
            foreach ($data as $key=>$val){
                if(!in_array($key,$fields)) {
                // 提交的表单数据如果与数据表中字段不匹配将进行过滤
                    unset($data[$key]);
                }elseif(MAGIC_QUOTES_GPC && is_string($val)){
                    $data[$key] =   stripslashes($val);
                }
            }
        }
        ...
        // 返回创建的数据以供其他调用
        return $data;
     }

4.实现数据修改save

注意:
  1、明确告诉系统哪条数据被更新
  2、设置where进行数据更新

save()方法返回值:
  0:执行没有问题,执行前后数据没有变化
  自然数:受影响的记录条数
  false:执行失败

如下情况在TP框架中不可被执行

程序代码如下:

//数组形式
$goods = D("Goods");
$ar = arrat('goods_name'=>'联想手机';'goods_price'=>1200);
$goods -> save($ar);
//AR形式
$goods = D("Goods");
$goods -> goods_name = 联想手机;
$goods -> goods_price =>1200;
$goods -> save();

  上述程序将会修改全部数据,SQL语句从技术上可行,但从业务上不可行(事故),以上情况在TP框架中不可被执行。

  需要做出如下修改
程序代码如下:

//数组形式
//情况1
$goods = D("Goods");
$ar = arrat('goods_id'=>12;'goods_name'=>'联想手机';'goods_price'=>1200);
$goods -> save($ar);
//情况1
$goods = D("Goods");
$ar = arrat('goods_name'=>'联想手机';'goods_price'=>1200);
$goods -> where('goods_price > 1000') -> save($ar);


//AR形式
//情况1
$goods = D("Goods");
$goods -> goods_id = 12;
$goods -> goods_name = 联想手机;
$goods -> goods_price =>1200;
$goods -> save();
//情况2
$goods = D("Goods");
$goods -> goods_name = 联想手机;
$goods -> goods_price =>1200;
$goods -> where('goods_price > 1000') -> save();

5.删除数据及原生SQL语句执行

删除数据

返回受影响的记录条数

$goods = D("Goods");
//以下三种方式都可以删除数据
$goods -> delete(63);  //删除主键值等于30的记录信息
$goods -> delete('10,20,30');  //删除主键值等于10,20,30的三条记录
$goods -> where('goods_id > 50 ') -> delete();  //删除goods_id大于50的全部记录
执行原生SQL语句

  1、查询语句query() 返回一个二维数组信息
  2、添加、修改、删除、execute() 返回受影响的记录条数
程序代码如下:

$goods = D("Goods");
$sql = "select * from sw_goods";
$goods -> query($sql);

$sql = "select goods_category_id from sw_goods group by goods_category_id having avg(goods_price)>1000";
$rst = $goods -> query($sql);

$sql = "update sw_goods set goods_name='红米' where goods_id=100";
$goods -> execute($sql);

6.后台商品修改实现

  通过路由给一个操作方法传递参数
    http://网址/index.php/模块/控制器/方法upd/变量名1/值/变量名2/值/变量名3/值
  以上路由是通过get形式给指定的操作传递了三个参数信息

单参数$_GET接收

  原则上参数信息接收的时候通过$_GET接收即可
  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    //修改商品
    public function upd(){
        echo $_GET['goods_id'];
        $this->display();
    }

访问http://localhost/ThinkPHP/shop/index.php/Admin/Goods/upd/goods_id/2

多参数$_GET接收

  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    //修改商品
    public function upd(){
        echo $_GET['goods_id'];
        echo $_GET['name'];
        $this->display();
    }

访问http://localhost/ThinkPHP/shop/index.php/Admin/Goods/upd/goods_id/2/name/tom

  但是以上参数信息接收太直接,不安全,需要按照框架规则使用如下方式接收get参数信息

使用操作方法接收参数

  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    public function upd($name,$goods_id){
        echo $goods_id;
        echo $name;
        $this->display();
    }

访问http://localhost/ThinkPHP/shop/index.php/Admin/Goods/upd/goods_id/2/name/tom

  以上参数表述,如果在请求的时候没有按照规则传递参数,那么当前方法禁止访问,除非参数已经设置了默认值。

  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    public function upd($name=tom,$goods_id){
        echo $goods_id;
        echo $name;
        $this->display();
    }

  访问http://localhost/ThinkPHP/shop/index.php/Admin/Goods/upd/goods_id/2

修改商品信息步骤

1、在“修改”按钮处把修改商品id信息通过get形式传递给upd操作
  shop/Admin/View/Goods/showlist.html
程序代码如下:

<a href="{$smarty.const.__CONTROLLER__}/upd/goods_id/{$v.goods_id}">修改</a>

2、在upd方法中制作形式参数$good_id,接受浏览器传递的get变量goods_id
  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    //修改商品
    public function upd($goods_id){
            $this->display();
    }

3、表单添加隐藏域或在方法内设置where语句,确保SQL语句在TP框架能执行
4、在upd操作方法内部有两个逻辑:展现表单、收集表单。

表单添加隐藏域

  shop/Admin/View/Goods/upd.html
程序代码如下:

           <form action="" method="post" enctype="multipart/form-data">
            {*隐藏域传递被修改的商品id信息*}
            <input type="hidden" name="goods_id" value="{$info.goods_id}" />
            <table border="1" width="100%" class="table_a">
                <tr>
                    <td>商品名称</td>
                    <td><input type="text" name="goods_name" value="{$info.goods_name}" /></td>
                </tr>
               ...
                <tr>
                    <td>商品详细描述</td>
                    <td>
                        <textarea name="f_goods_introduce">{$info.goods_introduce}</textarea>
                    </td>
                </tr>

                <tr>
                    <td colspan="2" align="center">
                        <input type="submit" value="修改">
                    </td>
                </tr>  
            </table>
            </form>

  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    public function upd($goods_id){

        $goods = D("Goods");
        //两个逻辑:1、展示表单;2、收集表单
        if (!empty($_POST)) {
            //print_r($_POST);
            $goods -> create();
            $rst = $goods -> save();
            if ($rst) {
                echo "success";
            } else {
                echo "failure";
            }       
        } else {
            $info = $goods -> find($goods_id);  //一维数组
            $this -> assign('info',$info);
            $this->display();
        }       
    }

方法内设置where语句

  shop/Admin/View/Goods/upd.html
程序代码如下:

            <form action="{$smarty.const.__SELF__}" method="post" enctype="multipart/form-data">
            <table border="1" width="100%" class="table_a">
                <tr>
                    <td>商品名称</td>
                    <td><input type="text" name="goods_name" value="{$info.goods_name}" /></td>
                </tr>
                </tr>
                ...
                <tr>
                    <td colspan="2" align="center">
                        <input type="submit" value="修改">
                    </td>
                </tr>  
            </table>
            </form>

  shop/Admin/Controller/GoodsController.class.php
程序代码如下:

    public function upd($goods_id){
        $goods = D("Goods");
        //两个逻辑:1、展示表单;2、收集表单
        if (!empty($_POST)) {
            //print_r($_POST);
            $goods -> create();
            $rst = $goods -> where("goods_id = $goods_id" )-> save();
            if ($rst) {
                echo "success";
            } else {
                echo "failure";
            }       
        } else {
            $info = $goods -> find($goods_id);  //一维数组
            $this -> assign('info',$info);
            $this->display();
        }       
    }

7.注册表单验证

**在服务器端通过TP框架实现表单验证** 具体步骤:
制作表单
表单form数据通过create()方法收集

验证功能要求我们必须通过create()方法收集数据

  shop/Home/View/User/register.html
程序代码如下:

<form id="yw0" action="{$smarty.const.__SELF__}" method="post">                
    <table cellpadding="5" cellspacing="3" style="text-align:left; width:100%; border:0;">
        <tbody>
            <tr>
                <td style="width:13%; text-align: right;">
                    <label for="User_username" class="">用户名 
                        <span class="">*</span>
                    </label>
                </td>
                <td style="width:87%;">
                    <input class="" size="25" name="username" id="User_username" type="text" value="" />                  
                    <span style="color:red;">用户名已经存在</span>
                </td>
            </tr>
            <tr>
                <td align="right">
                    <label for="User_password" class="">密码 
                        <span class="">*</span>
                    </label>
                </td>
                <td>
                    <input class="" size="25" name="password" id="User_password" type="password" value="" />         
                </td>
            </tr>
            <tr>
                <td align="right">
                    <label for="User_password2">密码确认</label>
                </td>
                <td>
                    <input class="" size="25" name="password2" id="User_password2" type="password" />
                </td>
            </tr>       
            <tr>
                <td align="right">
                    <label for="User_user_email">邮箱</label>
                </td>
                <td>
                    <input class="" size="25" name="user_email" id="User_user_email" type="text" value="" />    
                </td>
            </tr>
            <tr>
                <td align="right">
                    <label for="User_user_qq">qq号码</label>
                </td>
                <td>
                    <input class="" size="25" name="user_qq" id="User_user_qq" type="text" value="" />
                </td>
            </tr>
            <tr>
                <td align="right">
                    <label for="User_user_tel">手机</label>
                </td>
                <td>
                    <input class="" size="25" name="user_tel" id="User_user_tel" type="text" value="" />
                </td>
            </tr>
            <tr>
                <td align="right">
                    <label for="User_user_sex">性别</label>
                </td>
                <td>
                    <input id="ytUser_user_sex" type="hidden" value="" name="user_sex" />
                    <span id="User_user_sex">
                    <input id="User_user_sex_0" value="1" checked="checked" type="radio" name="user_sex" /> 
                    <label for="User_user_sex_0">男</label>&nbsp;
                    <input id="User_user_sex_1" value="2" type="radio" name="user_sex" / 
                    <label for="User_user_sex_1">女</label>&nbsp;
                    <input id="User_user_sex_2" value="3" type="radio" name="user_sex" />
                    <label for="User_user_sex_2">保密</label></span>
                </td>
            </tr>
            <tr>
                <td align="right"><label for="User_user_xueli">学历</label></td>
                <td>
                    <select name="user_xueli" id="User_user_xueli">
                        <option value="1" selected="selected">-请选择-</option>
                        <option value="2">小学</option>
                        <option value="3">初中</option>
                        <option value="4">高中</option>
                        <option value="5">大学</option>
                    </select>                                
                        <div class="" id="User_user_xueli_em_" style="display:none"></div>                            
                </td>
            </tr>
            <tr>
                    <td align="right"><label for="User_user_hobby">爱好</label></td>
                    <td>
                        <input id="ytUser_user_hobby" type="hidden" value="" name="user_hobby" />
                        <span id="User_user_hobby">
                            <input id="User_user_hobby_0" value="1" type="checkbox" name="user_hobby[]" /> 
                            <label for="User_user_hobby_0">篮球</label>&nbsp;
                            <input id="User_user_hobby_1" value="2" type="checkbox" name="user_hobby[]" /> 
                            <label for="User_user_hobby_1">足球</label>&nbsp;
                            <input id="User_user_hobby_2" value="3" type="checkbox" name="user_hobby[]" /> 
                            <label for="User_user_hobby_2">排球</label>&nbsp;
                            <input id="User_user_hobby_3" value="4" type="checkbox" name="user_hobby[]" /> 
                            <label for="User_user_hobby_3">棒球</label>
                        </span>                                
                    </td>
                </tr>
                <tr>
                    <td align="right"><label for="User_user_introduce">简介</label></td>
                    <td>
                        <textarea cols="50" rows="5" name="user_introduce" id="User_user_introduce"></textarea>                      
                    </td>
                </tr>
                <tr>
                    <td>&nbsp;</td>
                    <td align="left">
                        <input name="Submit" value="用户注册" class="" type="submit" />
                    </td>
                </tr>
                <tr>
                    <td colspan="2">&nbsp;</td>
                </tr>
            </tbody>
        </table>
    </form>
自定义数据Model模型类实现具体验证规则

  shop/Home/Controller/UserController.class.php
程序代码如下:

    function register(){
        $user = new \Model\UserModel();

        //判断表单是否提交
        if (!empty($_POST)) {
            //print_r($_POST);
            $z = $user -> create();  //集成表单验证
            //只有全部验证通过$z才会为真
            if (!$z) {
                //验证失败,输出错误信息
                //getError()方法返回验证失败的信息
                show_bug($user->getError());
            } else {
                $rst = $user -> add();
                if ($rst) {
                    echo "success";
                } else {
                    echo "error";
                }
            }       

        } else {
            //$this -> display();
        }
        //为了开发方便,将$this -> display()放到这里
        $this -> display();
    }

  shop/Model/UserModel.class.php
程序代码如下:

<?php
namespace Model;
use Think\Model;

class UserModel extends Model{
    //一次性获得全部验证错误
    //是否批处理验证
    protected $patchValidate=true;

    //实现表单项目验证
    //通过重写父类属性_validate实现表单验证
    protected $_validate=array(
            //用户名验证
            array('username','require','用户名必须填写'),
            array('username','','用户名已存在',0,'unique'),
            //密码验证
            array('password','require','密码必须填写'),
            array('password','5,10','密码位数必须5-10之间',0,'length'),
            //确认密码验证
            array('password2','require','确认密码必须填写'),
            //与密码的值必须一致
            array('password2','password','两次密码必须一致',0,'confirm'),
            //邮箱验证
            array('user_email','email','邮箱格式不正确'),
            //qq验证
        //  array('user_qq','number','qq号码必须是数字'),
        //  array('user_qq','5,12','qq号码位数5到12之间',0,'length'),
            array('user_qq',"/^[1-9]\d{4,11}$/",'qq格式不正确'),
            //手机号码验证
            array('user_tel','/^1\d{10}$/','手机号码格式不正确'),
            //验证学历
        //  array('user_xueli','1','学历必须选择一个',0,'notin'),
            array('user_xueli',"2,3,4,5",'学历必须选择一个',0,'in'),
            //验证爱好
            //爱好项目至少选择两项以上
            //爱好的值是一个数组,判断其元素个数即可知道结果
            //callback利用当前Model中的一个指定方法进行验证
            array('user_hobby',"check_hobby",'爱好必须选择两项以上',0,'callback'),
    );

    //自定义方法验证爱好信息
    //$name参数是当前被验证项目的信息
    //$name = $_POST['user_hobby']
    function check_hobby($name){
        if (count($name)<2) {
            return false;
        } else {
            return true;
        }   
    }
}

验证规则的第4个参数说明(0,1,2)
验证条件
验证条件

注意:
  1、通过new进行模型实例化
  2、调用create()方法才可以触发TP自动验证

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值