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自身的

<?php  foreach($data as $k=>$v):  ?>
<?php endforeach; ?>
<?php  if():  ?>
<?php   endif; ?>

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • 转载自cr180大神DiscuzX2.5完整目录结构【source程序文件库】 /source/admincp后台...
    cndaqiang阅读 832评论 1 2
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,019评论 4 62
  • 朋友的作用是什么呢?这是我常常在想的问题。 我的朋友基本上可以分为两种。一种是积极进取,在我遇到困难后直指我的痛点...
    希希13阅读 1,578评论 0 1
  • 一只聪明的猫要帮助它穷困潦倒的主人翻身,于是它向主人要了一双靴子和一个布袋,穿过荆棘到森林里打猎。它把每次获得的猎...
    开心果嘛嘛阅读 1,487评论 1 0
  • 文/桃小夭 1 小时候下雨,以为全世界都在撑伞。并不知道大多数地方依然艳阳高照。 以为冬天,到处都是白雪皑皑,原来...
    桃小夭3199阅读 592评论 0 3