thinkphp3.2开发笔记

需求

  1. 商品表的管理:CRUD、搜索、排序、翻页
  2. 考虑SQL注入
  3. 使用js插件:时间插件,在线编辑器
  4. 图片生成缩略图,节省带宽,加载快

创建一个控制器完成商品表的操作

namespace Admin\Controller;
use Think\Controller;
class GoodsController extends Controller 
{
    public function add()
    {
        // 2.处理表单
        if(IS_POST)
        {
            //3. 先生成模型
            // D和M的区别:D生成我们自己创建的模型对象,M生成TP自带的模型对象
            // 这里我们要生成我们自己创建的模型,因为这里要使用我们自己创建的模型中的验证规则来验证表单
            // 这里用M可以添加成功但是验证表单的功能会失败,因为验证规则是在我们自己定义的模型中的,而M生成的是TP自带的模型里没有验证规则
            $model = D('Goods');
            // 4. a.接收表单中所有的数据并存到模型中 b.使用I函数过滤数据 c.根据模型中定义的规则验证表单
                    //5.在create方法时传入第二个参数标记是什么类型的表单,其中1:添加,2:修改
            if($model->create(I('post.'), 1))
            {
                // 5. 插入数据库
                if($model->add())
                {
                    // 6. 提示信息
                    $this->success('操作成功!', U('lst'));
                    // 7.停止执行后面的代码
                    exit;
                }
            }
            // 8. 如果上面失败,获取失败的原因
            $error = $model->getError();
            // 9. 显示错误信息,并跳回到上一个页面
            $this->error($error);
        }
        // 1.显示表单
        $this->display();
    }

public function edit()
    {
        // 处理表单
        if(IS_POST)
        {
            $model = D('Goods');
            if($model->create(I('post.'), 2))
            {
                // save方法的返回值是影响的记录数(mysql_affected_rows),如果修改时没有修改任何值会返回0.如果失败返回FALSE
                if(FALSE !== $model->save())
                {
                    $this->success('操作成功!', U('lst?p='.I('get.p')));
                    exit;
                }
            }
            // 如果失败显示错误信息
            $this->error($model->getError());
        }
        // 接收商品的ID
        $id = I('get.id');
        // 先从数据库中取出要修改的记录的信息
        $model = M('Goods');
        $info = $model->find($id);
        $this->assign('info', $info);
        // 显示修改的表单
        $this->display();
    }
    public function delete()
    {
        $model = D('Goods');
        $model->delete(I('get.id'));
        $this->success('操作成功!', U('lst?p='.I('get.p')));
    }
    // 列表
    public function lst()
    {
        $model = D('Goods');
        // 获取带翻页的数据
        $data = $model->search();
        $this->assign(array(
            'data' => $data['data'],
            'page' => $data['page'],
        ));
        $this->display();
    }
}






创建模型

class GoodsModel extends Model 
{
    // 在添加时调用create方法时允许接收的字段
    protected $insertFields = array('goods_name','price','goods_desc','is_on_sale');
    // 在修改时表单中可以有哪些字段
    protected $updateFields = array('id', 'goods_name','price','goods_desc','is_on_sale');
    // 定义表单验证的规则,控制器中的create方法时用
    protected $_validate = array(
        array('goods_name', 'require', '商品名称不能为空!', 1),
        array('goods_name', '1,45', '商品名称必须是1-45个字符', 1, 'length'),
        array('price', 'currency', '价格必须是货币格式', 1),
        array('is_on_sale', '0,1', '是否上架只能是0,1两个值', 1, 'in'),
    );
    // TP在调用add方法之前会自动调用这个方法,我们可以把在插入数据库之前要执行的代码写到这里
    // 第一个参数:就是表单中的数据(要插入到数据库中的数据)是一个一维数组
    // 第二个参数:额外信息,:当前模型对应的实际的表名是什么
    // 说明:在这个函数中要改变这个函数外部的$data,需要按钮引用传递,否则修改也无效
    // 说明:如果return false是指控制器中的add方法返回了false
    protected function _before_insert(&$data, $option)
    {
        // 获取当前时间
        $data['addtime'] = time();
        // 上传LOGO
        if(isset($_FILES['logo']) && $_FILES['logo']['error'] == 0)
        {
            $rootPath = C('IMG_rootPath');
            $upload = new \Think\Upload(array(
                'rootPath' => $rootPath,
            ));// 实例化上传类
            $upload->maxSize = (int)C('IMG_maxSize') * 1024 * 1024;// 设置附件上传大小
            $upload->exts = C('IMG_exts');// 设置附件上传类型
           /// $upload->rootPath = $rootPath; // 设置附件上传根目录
            $upload->savePath = 'Goods/'; // 图片二级目录的名称
            // 上传文件 
            $info   =   $upload->upload();
            if(!$info)
            {
                // 先把上传失败的错误信息存到模型中,由控制器最终再获取这个错误信息并显示
                $this->error = $upload->getError();
                return FALSE; // 返回控制器
            }
            else
            {
                $logoName = $info['logo']['savepath'] . $info['logo']['savename'];
                // 拼出缩略图的文件名
                $smLogoName = $info['logo']['savepath'] . 'thumb_' .$info['logo']['savename'];
                // 生成缩略图
                $image = new \Think\Image();
                // 打开要处理的图片
                $image->open($rootPath.$logoName);
                $image->thumb(150, 150)->save($rootPath.$smLogoName);
                // 把图片的表单放到表单中
                $data['logo'] = $logoName;
                $data['sm_logo'] = $smLogoName;
            }
        }
    }
    protected function _before_update(&$data, $option)
    {
        // 上传LOGO
        if(isset($_FILES['logo']) && $_FILES['logo']['error'] == 0)
        {
            $rootPath = C('IMG_rootPath');
            $upload = new \Think\Upload(array(
                'rootPath' => $rootPath,
            ));// 实例化上传类
            $upload->maxSize = (int)C('IMG_maxSize') * 1024 * 1024;// 设置附件上传大小
            $upload->exts = C('IMG_exts');// 设置附件上传类型
           /// $upload->rootPath = $rootPath; // 设置附件上传根目录
            $upload->savePath = 'Goods/'; // 图片二级目录的名称
            // 上传文件 
            $info   =   $upload->upload();
            if(!$info)
            {
                // 先把上传失败的错误信息存到模型中,由控制器最终再获取这个错误信息并显示
                $this->error = $upload->getError();
                return FALSE; // 返回控制器
            }
            else
            {
                $logoName = $info['logo']['savepath'] . $info['logo']['savename'];
                // 拼出缩略图的文件名
                $smLogoName = $info['logo']['savepath'] . 'thumb_' .$info['logo']['savename'];
                // 生成缩略图
                $image = new \Think\Image();
                // 打开要处理的图片
                $image->open($rootPath.$logoName);
                $image->thumb(150, 150)->save($rootPath.$smLogoName);
                // 把图片的表单放到表单中
                $data['logo'] = $logoName;
                $data['sm_logo'] = $smLogoName;
                // 删除商品的原图片
                // 先根据商品的ID取出这件商品的图片的路径
                $logo = $this->field('logo,sm_logo')->find($option['where']['id']);
                // 从配置文件取出图片所在目录
                $rp = C('IMG_rootPath');
                // 删除图片
                unlink($rp . $logo['logo']);
                unlink($rp . $logo['sm_logo']);
            }
        }
    }
    public function search()
    {
        /************ 搜索 ****************/
        $where = array();  // 默认情况下的搜索条件为空
        // 商品名称的搜索
        $goodsName = I('get.goods_name');
        if($goodsName)
            $where['goods_name'] = array('like', "%$goodsName%");
        // 价格的搜索
        $startPrice = I('get.start_price');
        $endPrice = I('get.end_price');
        if($startPrice && $endPrice)
            $where['price'] = array('between', array($startPrice, $endPrice));
        elseif ($startPrice)
            $where['price'] = array('egt', $startPrice);
        elseif ($endPrice)
            $where['price'] = array('elt', $endPrice);
        // 上架的搜索
        $isOnSale = I('get.is_on_sale', -1);
        if($isOnSale != -1)
            $where['is_on_sale'] = array('eq', $isOnSale); 
        // 是否删除的搜索
        $isDelete = I('get.is_delete', -1);
        if($isDelete != -1)
            $where['is_delete'] = array('eq', $isDelete); 
        // 时间的搜索
        $startAddtime = I('get.start_addtime');
        $endAddtime = I('get.end_addtime');
        if($startAddtime && $endAddtime)
            $where['addtime'] = array('between', array(strtotime("$startAddtime 00:00:00"), strtotime("$endAddtime 23:59:59")));
        elseif ($startAddtime)
            $where['addtime'] = array('egt', strtotime("$startAddtime 00:00:00"));
        elseif ($endAddtime)
            $where['addtime'] = array('elt', strtotime("$endAddtime 23:59:59"));
        /***************** 排序 ******************/
        $orderby = 'id';  // 默认排序字段
        $orderway = 'desc'; // 默认排序方式
        $odby = I('get.odby');
        if($odby && in_array($odby, array('id_asc','id_desc','price_asc','price_desc')))
        {
            if($odby == 'id_asc')
                $orderway = 'asc';
            elseif ($odby == 'price_asc')
            {
                $orderby = 'price';
                $orderway = 'asc';
            }
            elseif ($odby == 'price_desc')
                $orderby = 'price';
        }
        /************ 翻页 *************/
        // 总的记录数
        $count = $this->where($where)->count();
        // 生成翻页对象
        $page = new \Think\Page($count, 10);
        $page->setConfig('next', '下一页');
        $page->setConfig('prev', '上一页');
        // 获取翻页字符串
        $pageString = $page->show();
        // 取出当前页的数据
        $data = $this->where($where)->limit($page->firstRow.','.$page->listRows)->order("$orderby $orderway")->select();
        
        //echo $this->getLastSql();
        
        return array(
            'page' => $pageString,
            'data' => $data,
        );
    }
    // 在控制器中调用delete方法之前会自动调用
    protected function _before_delete($option)
    {
        // 先根据商品的ID取出这件商品的图片的路径
        $logo = $this->field('logo,sm_logo')->find($option['where']['id']);
        // 从配置文件取出图片所在目录
        $rp = C('IMG_rootPath');
        // 删除图片
        unlink($rp . $logo['logo']);
        unlink($rp . $logo['sm_logo']);
    }
}


在师徒模板中,可以不需要使用tp标签输出变量,循环,判断,直接用php自身的

$v):  ?>



注意
我们在写其他控制器的CRUD时,都可以按照这种方式来做,提醒一下,向上传文件显示图片的代码,我们可以封装到Common/Common/function.php,然后可以直接调用使用

你可能感兴趣的:(thinkphp3.2开发笔记)