Web开发 | ThinkPHP 3.2.3 - 06.验证码、分页、缓存、图片附件上传及缩略图

本文详细介绍了在ThinkPHP 3.2.3中如何实现验证码生成、验证,登录功能中的用户密码判断,分页效果的实现,以及缓存(包括文件、内存和数据库)的应用。同时讲解了图片附件的上传和缩略图的生成,最后探讨了面向切面编程Behavior的概念。

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

1.验证码生成使用verify

$verify = new 命名空间Verify();
$verify -> entry();
简单生成验证码

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

    //制作专门方法实现验证码生成
    function verifyImg(){
        //以下类Verify在之前并没有include引入,而是使用自动加载
        //ThinkPHP/Library/Think/Think.class.php中的autoload()方法      
        $verify = new \Think\Verify();
        //ThinkPHP/Library/Think/Verify.class.php命名空间为Think
        //完全限定名称实例化
        //实例化,走的是Verify里的构造方法__construct()
        //show_bug($verify);
        $verify -> entry();
    }

  运行http://localhost/ThinkPHP/shop/index.php/Admin/Manager/verifyImg

运行效果运行效果

验证码相关类解析

  ThinkPHP/Library/Think/Think.class.php中的autoload()方法
程序代码如下:

    /**
     * 类库自动加载
     * @param string $class 对象类名
     * @return void
     */
    public static function autoload($class) {

        //1、show_bug($class);
        //将输出以下信息:
        //string(13) "Think\Storage"
        //string(25) "Think\Storage\Driver\File"
        //string(9) "Think\Log"
        //string(30) "Behavior\ReadHtmlCacheBehavior"
        //string(34) "Admin\Controller\ManagerController"
        //string(12) "Think\Verify"
        //string(30) "Behavior\ShowPageTraceBehavior"
        //string(21) "Think\Log\Driver\File"
        //即我们实例化验证码时$class=Think\Verify

        // 检查是否存在映射
        if(isset(self::$_map[$class])) {
            include self::$_map[$class];
        }elseif(false !== strpos($class,'\\')){
          //2、
          //strstr(Think\Verify, '\\'); 将返回Verify
          //strstr(Think\Verify, '\\', true); 将返回Think
          //上面中'\\'的第一个斜杠是转义符,所以生效的只有一个斜杠
          //此时$name=Think
          $name           =   strstr($class, '\\', true);
          if(in_array($name,array('Think','Org','Behavior','Com','Vendor')) || is_dir(LIB_PATH.$name)){ 
              // Library目录下面的命名空间自动定位
              // 3、
              // LIB_PATH= ThinkPHP/Library
              $path       =   LIB_PATH;
          }else{
              // 检测自定义命名空间 否则就以模块为命名空间
              $namespace  =   C('AUTOLOAD_NAMESPACE');
              $path       =   isset($namespace[$name])? dirname($namespace[$name]).'/' : APP_PATH;
          }
          //4、
          //$filename = ThinkPHP/Library/Think/Verify.class.php
          $filename       =   $path . str_replace('\\', '/', $class) . EXT;
          if(is_file($filename)) {
              // Win环境下面严格区分大小写
              if (IS_WIN && false === strpos(str_replace('/', '\\', realpath($filename)), $class . EXT)){
                  return ;
              }
              include $filename;
          }
        }elseif (!C('APP_USE_NAMESPACE')) {
            // 自动加载的类库层
            foreach(explode(',',C('APP_AUTOLOAD_LAYER')) as $layer){
                if(substr($class,-strlen($layer))==$layer){
                    if(require_cache(MODULE_PATH.$layer.'/'.$class.EXT)) {
                        return ;
                    }
                }            
            }
            // 根据自动加载路径设置进行尝试搜索
            foreach (explode(',',C('APP_AUTOLOAD_PATH')) as $path){
                if(import($path.'.'.$class))
                    // 如果加载类成功则返回
                    return ;
            }
        }
    }

  ThinkPHP/Library/Think/Verify.class.php的构造方法__construct()
程序代码如下:

    /**
     * 架构方法 设置参数
     * @access public     
     * @param  array $config 配置参数
     */    
    //当前类中定义的$config作为参数传入
    public function __construct($config=array()){
        //与类中当前的属性config进行合并,最后传入$this->config
        $this->config   =   array_merge($this->config, $config);
    }

  当前类有config属性如下:

protected $config =    array(
        'seKey'     =>  'ThinkPHP.CN',   // 验证码加密密钥
        'codeSet'   =>  '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY',             // 验证码字符集合
        'expire'    =>  1800,            // 验证码过期时间(s)
        'useZh'     =>  false,           // 使用中文验证码 
        'zhSet'     =>  '们...休借',      // 中文验证码字符串
        'useImgBg'  =>  false,           // 使用背景图片 
        'fontSize'  =>  25,              // 验证码字体大小(px)
        'useCurve'  =>  true,            // 是否画混淆曲线
        'useNoise'  =>  true,            // 是否添加杂点  
        'imageH'    =>  0,               // 验证码图片高度
        'imageW'    =>  0,               // 验证码图片宽度
        'length'    =>  5,               // 验证码位数
        'fontttf'   =>  '',              // 验证码字体,不设置随机获取
        'bg'        =>  array(243, 251, 254),  // 背景颜色
        'reset'     =>  true,           // 验证成功后是否重置
        );
验证码个性化配置

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

    //制作专门方法实现验证码生成
    function verifyImg(){
        $config =  array(  
            'fontSize'  =>  25,              // 验证码字体大小(px)
            'imageH'    =>  50,               // 验证码图片高度
            'imageW'    =>  250,               // 验证码图片宽度
            //ThinkPHP/Library/Think/Verify/ttfs
            'fontttf'   =>  '4.ttf',              // 验证码字体,不设置随机获取
            'length'    =>  5,               // 验证码位数
        );
        //需要传入参数
        $verify = new \Think\Verify($config);
        $verify -> entry();
    }
验证码在模板中使用
<img src="路由地址Manager/verifyImg" alt="">

  shop/Admin/View/Manager/login.html
程序代码如下:

<div class="col-sm-6">
    <img src="{$smarty.const.__CONTROLLER__}/verifyImg" class="verifyimg reloadverify"/>
</div>

  运行http://localhost/ThinkPHP/shop/index.php/Admin/Manager/login

运行效果
运行效果


2.验证码有效性验证

  本身验证码信息存储在session中,session存储的验证按是加密后的数据,Verity类提供了一个方法进行验证码的有效性校验。

$verify -> check(用户输入验证码); 返回真,表示验证码是正确的

  shop/Admin/View/Manager/login.html
程序代码如下:

<form class="form-horizontal" action="{$smarty.const.__SELF__}" role="form" method="post">
...
<input type="text" class="form-control" id="verify" name="verify" placeholder="验证码"  required />
...
</form>

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

    public function login(){
        if (!empty($_POST)) {
            //可以输出当前返回的信息
            //print_r($_POST);
            //验证码校验
            $verify = new \Think\Verify();
            if (!$verify->check($_POST['verify'])) {
                echo  "<script>alert('验证码错误')</script>";
            } else {
                echo "<script>alert('验证码正确')</script>";
            }       
        } 
            $this->display();
        }   

  运行http://localhost/ThinkPHP/shop/index.php/Admin/Manager/login

运行效果
运行效果


3.登录功能用户名密码判断、获取session信息

  判断用户名、密码是否是正确的,如果是正确的,再把信息存入session中表示登录状态。

  传统方法:select * from sw_manager where name=$name and pwd=$pwd;
    同时查询用户名和密码的信息记录,如果存在就是正确的,否则用户名或密码错误。
    该方式不安全,会增加SQL语句注入的风险。

  可以使用:select * from sw_manager where name=$name;
    首先,查询指定名字的记录信息
    其次,如果记录存在,再把记录中的密码拿出来与用户输入的密码进行比较
    如果比较一致,就说明用户名和密码正确。

TP框架关于session操作(cookie一样)

session(name,value,有效时间); 设置session
session([name]); 获取session
session(name,null); 删除指定session
session(null); 清空全部session

  新建shop/Model/ManagerModel.class.php
程序代码如下:

    //制作一个方法对用户名和密码进行校验
    function checkNamePwd($name,$pwd){
        //1、根据$name查询是否有此记录
        //select * from sw_manager where mg_name=$name;
        //select()  find()
        //2、根据指定字段进行查询getByXxx(),getByMg_name($name)
        //getBymg_pwd()  父类Model利用__call()封装的方法
        //getByXxx()函数返回一维数组信息
        $info = $this ->getByMg_name($name);

        //$info = null; 说明用户名错误
        //$info = 一维数组;说明用户名正确
        //show_bug($info);

        //$info不为null,就可以继续验证密码
        if ($info != null) {
            if ($info['mg_pwd' != $pwd]) {
                return false;
            } else {
                //返回$info来设置session信息
                return $info;
            }
        } else {
            return false;
        }           
    }

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

    public function login(){

        if (!empty($_POST)) {
            $verify = new \Think\Verify();
            if (!$verify->check($_POST['verify'])) {
                echo  "<script>alert('验证码错误')</script>";
            } else {
                //判断用户名和密码
                //在Model模型中制作一个专门方法进行验证
                $user = new \Model\ManagerModel();
                $rst=$user->checkNamePwd($_POST['username'],$_POST['password']);

                if ($rst === false) {
                    echo "用户名或密码错误";
                } else {
                    print_r($rst['mg_name']) ;
                    //登录信息持久化$_SESSION
                    session('username',$rst['mg_name']);
                    session('id',$rst['mg_id']);
                    //页面跳转到后台首页
                    //$this -> redirect($url, $params, $delay, $msg);
                    //$this -> redirect('Index/index', array('id'=>100,'name'=>'Tom'), 2, '即将跳转');
                    $this -> redirect('Index/index');
                }   
            }
        } 
        $this->display();      
    }

    //退出系统
    function logout(){
        session(null);
        $this -> redirect('Manager/login');
    }

  shop/Admin/View/Index/head.html
程序代码如下:

<td style="font-weight: bold; color: #fff; padding-top: 20px" 
                    align=middle>当前用户:{$smarty.session.username}&nbsp;&nbsp; 
    <a style="color: #fff" href="" target=main>修改口令</a> &nbsp;&nbsp; 
    <a style="color: #fff" onclick="if (confirm('确定要退出吗?')) return true; else return false;" href="{$smarty.const.__MODULE__}/Manager/logout" target=_top>退出系统</a> 
</td>

  运行http://localhost/ThinkPHP/shop/index.php/Admin/Manager/login.html

运行效果
运行效果
运行效果
运行效果


4.分页效果及自定义类文件引入框架

  1、TP框架爱使用自定义功能类
  2、具体分页类实现

  新建自定义类文件夹并将该类放入
  shop/Tool/Page.class.php
程序代码如下:

<?php
namespace Tool;
    class Page {
        private $total; //数据表中总记录数
        private $listRows; //每页显示行数
        private $limit;
        private $uri;
        private $pageNum; //页数
        private $config=array('header'=>"个记录", "prev"=>"上一页", "next"=>"下一页", "first"=>"首 页", "last"=>"尾 页");
        private $listNum=8;
        /*
         * $total 
         * $listRows
         */
        public function __construct($total, $listRows=10, $pa=""){
            $this->total=$total;
            $this->listRows=$listRows;
            $this->uri=$this->getUri($pa);
            $this->page=!empty($_GET["page"]) ? $_GET["page"] : 1;
            $this->pageNum=ceil($this->total/$this->listRows);
            $this->limit=$this->setLimit();
        }

        private function setLimit(){
            return "Limit ".($this->page-1)*$this->listRows.", {$this->listRows}";
        }

        private function getUri($pa){
            $url=$_SERVER["REQUEST_URI"].(strpos($_SERVER["REQUEST_URI"], '?')?'':"?").$pa;
            $parse=parse_url($url);



            if(isset($parse["query"])){
                parse_str($parse['query'],$params);
                unset($params["page"]);
                $url=$parse['path'].'?'.http_build_query($params);

            }

            return $url;
        }

        function __get($args){
            if($args=="limit")
                return $this->limit;
            else
                return null;
        }

        private function start(){
            if($this->total==0)
                return 0;
            else
                return ($this->page-1)*$this->listRows+1;
        }

        private function end(){
            return min($this->page*$this->listRows,$this->total);
        }

        private function first(){
            $html = "";
            if($this->page==1)
                $html.='';
            else
                $html.="&nbsp;&nbsp;<a href='{$this->uri}&page=1'>{$this->config["first"]}</a>&nbsp;&nbsp;";

            return $html;
        }

        private function prev(){
            $html = "";
            if($this->page==1)
                $html.='';
            else
                $html.="&nbsp;&nbsp;<a href='{$this->uri}&page=".($this->page-1)."'>{$this->config["prev"]}</a>&nbsp;&nbsp;";

            return $html;
        }

        private function pageList(){
            $linkPage="";

            $inum=floor($this->listNum/2);

            for($i=$inum; $i>=1; $i--){
                $page=$this->page-$i;

                if($page<1)
                    continue;

                $linkPage.="&nbsp;<a href='{$this->uri}&page={$page}'>{$page}</a>&nbsp;";

            }

            $linkPage.="&nbsp;{$this->page}&nbsp;";


            for($i=1; $i<=$inum; $i++){
                $page=$this->page+$i;
                if($page<=$this->pageNum)
                    $linkPage.="&nbsp;<a href='{$this->uri}&page={$page}'>{$page}</a>&nbsp;";
                else
                    break;
            }

            return $linkPage;
        }

        private function next(){
            $html = "";
            if($this->page==$this->pageNum)
                $html.='';
            else
                $html.="&nbsp;&nbsp;<a href='{$this->uri}&page=".($this->page+1)."'>{$this->config["next"]}</a>&nbsp;&nbsp;";

            return $html;
        }

        private function last(){
            $html = "";
            if($this->page==$this->pageNum)
                $html.='';
            else
                $html.="&nbsp;&nbsp;<a href='{$this->uri}&page=".($this->pageNum)."'>{$this->config["last"]}</a>&nbsp;&nbsp;";

            return $html;
        }

        private function goPage(){
            return '&nbsp;&nbsp;<input type="text" onkeydown="javascript:if(event.keyCode==13){var page=(this.value>'.$this->pageNum.')?'.$this->pageNum.':this.value;location=\''.$this->uri.'&page=\'+page+\'\'}" value="'.$this->page.'" style="width:25px"><input type="button" value="GO" onclick="javascript:var page=(this.previousSibling.value>'.$this->pageNum.')?'.$this->pageNum.':this.previousSibling.value;location=\''.$this->uri.'&page=\'+page+\'\'">&nbsp;&nbsp;';
        }
        function fpage($display=array(0,1,2,3,4,5,6,7,8)){
            $html[0]="&nbsp;&nbsp;共有<b>{$this->total}</b>{$this->config["header"]}&nbsp;&nbsp;";
            $html[1]="&nbsp;&nbsp;每页显示<b>".($this->end()-$this->start()+1)."</b>条,本页<b>{$this->start()}-{$this->end()}</b>条&nbsp;&nbsp;";
            $html[2]="&nbsp;&nbsp;<b>{$this->page}/{$this->pageNum}</b>页&nbsp;&nbsp;";

            $html[3]=$this->first();
            $html[4]=$this->prev();
            $html[5]=$this->pageList();
            $html[6]=$this->next();
            $html[7]=$this->last();
            $html[8]=$this->goPage();
            $fpage='';
            foreach($display as $index){
                $fpage.=$html[$index];
            }
            return $fpage;
        }
    }

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

    //商品列表展示
    public function showlist(){
        $goods = D("Goods");

        //1、获取当前记录总条数
        $total = $goods -> count();
        $per = 3;

        //2、实例化分页类对象
        $page = new \Tool\Page($total,$per);

        //3、拼装SQL语句获得每页信息
        $sql = "select * from sw_goods ".$page->limit;
        $info = $goods -> query($sql);
        //4、获得页码列表
        $pagelist = $page ->fpage();

        $this -> assign('info',$info);
        $this->assign('page',$pagelist);

        $this -> display();
    }

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

<tr>
    <td colspan="20"  style="text-align: center;" >{$page}</td>
</tr>

5.缓存应用

  数据缓存介质:file文件、memory内存、数据库。
  可以把一些不经常使用的MySQL数据临时放入缓存中,每次用户获得信息就从缓存中获得,大大提升MySQL的性能,减少服务器发的开销。
  Smarty中也有缓存,是页面静态化的缓存——页面缓存

文件缓存

    fopen() fwrite() fread()

memory内存缓存

    安装内存缓存软件。启动软件服务,set() get()方法对内存数据进行读入读出操作

数据库缓存

    建立临时数据表。启动MySQL数据,insert() select() update()

  不同介质的缓存操作的手段也不同。TP框架已经把各种缓存设置好了,我们可以通过统一的行为操作不同类型的的缓存。

缓存操作

S(n**ame,value,有效期);    设置缓存
S(name);    读取缓存变量信息
S(name,null);    删除指定的缓存变量

  TP默认缓存为文件缓存
  ThinkPHP/Conf/convention.php

    /* 数据缓存设置 */
    'DATA_CACHE_TIME'       =>  0,      // 数据缓存有效期 0表示永久缓存
    'DATA_CACHE_COMPRESS'   =>  false,   // 数据缓存是否压缩缓存
    'DATA_CACHE_CHECK'      =>  false,   // 数据缓存是否校验缓存
    'DATA_CACHE_PREFIX'     =>  '',     // 缓存前缀
    'DATA_CACHE_TYPE'       =>  'File',  // 数据缓存类型,支持:File|Db|Apc|Memcache|Shmop|Sqlite|Xcache|Apachenote|Eaccelerator
    'DATA_CACHE_PATH'       =>  TEMP_PATH,// 缓存路径设置 (仅对File方式缓存有效)
    'DATA_CACHE_KEY'        =>  '', // 缓存文件KEY (仅对File方式缓存有效)    
    'DATA_CACHE_SUBDIR'     =>  false,    // 使用子目录缓存 (自动根据缓存标识的哈希创建子目录)
    'DATA_PATH_LEVEL'       =>  1,        // 子目录缓存级别

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

    //设置缓存
    function s1(){
        //name在10秒后失效
        S('name','Tom',10);
        S('age',25);
        S('hobby',array('篮球','排球','乒乓球'));
        echo "设置文件缓存成功";
    }

    //读取缓存
    function s2(){
        echo S('name'),"<br/>";
        echo S('age'),"<br/>";
        print_r(S('hobby'));
        echo "<br/>";
    }

    //删除缓存
    function s3(){
        S('name',null);
        S('age',null);
        echo "删除文件缓存成功";
    }

  缓存信息存储在shop/Runtime/Temp

常规缓存流程

  缓存中有数据直接返回使用
  否则去数据库查询信息,再缓存,再供使用
  下次就会到缓存中获得指定的信息,过了有效期重新到数据库获取数据

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

    function y1(){
        //外部用户访问的方法
        show_bug($this -> y2());
    }

    function y2(){
        //被其他方法调用的方法,获得指定信息
        //第一次从数据库中获得,后续在有效期从缓存中获得
        $info = S('goods_info');
        if ($info) {
            return $info;
        } else {
            //没有缓存数据,就从数据库中获得数据,再把数据缓存起来
            //模仿连接数据库
            $dt = "这是加了时间戳的缓存".time();
            S('goods_info',$dt,10);
            return dt;
        }   
    }

6.图片附件上传

前台上传:<form enctype="multipart/form-data">
后台接收:$_FILES
    调用函数:move_uploaded_file(临时路径名,真实路径名);

  TP系统类:ThinkPHP/Library/Think/Upload.class.php
    该类设置的上传驱动对应的是常量'FILE_UPLOAD_TYPE' => 'Local', // 文件上传方式
  即调用系统类:ThinkPHP/Library/Think/Upload/Driver/Local.class.php
    该类是实现文件上传的具体操作

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

    private $config = array(
        'mimes'         =>  array(), //允许上传的文件MiMe类型
        'maxSize'       =>  0, //上传的文件大小限制 (0-不做限制)
        'exts'          =>  array(), //允许上传的文件后缀
        'autoSub'       =>  true, //自动子目录保存文件
        'subName'       =>  array('date', 'Y-m-d'), //子目录创建方式,[0]-函数名,[1]-参数,多个参数使用数组
        'rootPath'      =>  './Uploads/', //保存根路径
        'savePath'      =>  '', //保存路径
        'saveName'      =>  array('uniqid', ''), //上传文件命名规则,[0]-函数名,[1]-参数,多个参数使用数组
        'saveExt'       =>  '', //文件保存后缀,空则使用原后缀
        'replace'       =>  false, //存在同名是否覆盖
        'hash'          =>  true, //是否生成hash编码
        'callback'      =>  false, //检测文件是否存在回调,如果存在返回文件信息数组
        'driver'        =>  '', // 文件上传驱动
        'driverConfig'  =>  array(), // 上传驱动配置
    );

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

    //添加商品
    public function add(){
        $goods = D("Goods");
        if (!empty($_POST)) {
            //判断附件是否上传
            //如果有则实例化Upload,把附件上传到服务器指定位置
            //然后把附件的路径名得到,存入$_POST
            if (!empty($_FILES)) {
                //print_r($_FILES);
                $upload = new \Think\Upload();
                //show_bug($upload);
                //uploadOne会返回已经上传的附件信息
                $z = $upload -> uploadOne($_FILES['goods_img']);
                $config = array(
                    'rootPath'      =>  '', //保存根路径
                    'savePath'      =>  'Uploads/', //保存路径
                );
                //附件上传到路径:根目录/保存目录路径/创建日期目录
                if (!$z) {
                    show_bug($upload -> getError()); 
                } else {
                    //show_bug($z); 
                    //拼装图片的路径名
                    $bigimg = $z['savepath'].$z['savename'];
                    $_POST['goods_big_img'] = $bigimg;
                }   
            }   
            $goods -> create();
            $z = $goods -> add($ar);
            if ($z) {
                echo "success";
            } else {
                echo "failure";
            }       
        } else {
        }       
        $this->display();
    }

  建立上传目录ThinkPHP\shop\Uploads

  定义上传路径常量
  shop/index.php
程序代码如下:

//为上传图片设置路径
define("IMG_UPLOAD",SITE_URL."../ThinkPHP/shop/Uploads/");

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

<form action="{$smarty.const.__SELF__}" method="post" enctype="multipart/form-data">
    ...
    <tr>
        <td>商品图片</td>
        <td><input type="file" name="goods_img" /></td>
    </tr>
    ...
</form>

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

<img src="{$smarty.const.IMG_UPLOAD}{$v.goods_big_img}" height="60" width="60"/>

7.给已上传图片生成缩略图

  原理:利用已有图片创建一个画板
    把画板给缩小一点imagecopyresampled

imagepng($img,路径名); 保存到系统一个指定目录
ThinkPHP/Library/Think/Image.class.php
open()  打开一个图像资源
thumb()  制作缩略图,设置图像的宽度、高度、达到制作缩略图效果
save()  保存图像

  TP系统类:ThinkPHP/Library/Think/Image.class.php

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

    //添加商品
    public function add(){
        $goods = D("Goods");
        if (!empty($_POST)) {
            //判断附件是否上传
            //如果有则实例化Upload,把附件上传到服务器指定位置
            //然后把附件的路径名得到,存入$_POST
            if (!empty($_FILES)) {
                //print_r($_FILES);
                $upload = new \Think\Upload();
                //show_bug($upload);
                //uploadOne会返回已经上传的附件信息
                $z = $upload -> uploadOne($_FILES['goods_img']);
                $config = array(
                    'rootPath'      =>  '', //保存根路径
                    'savePath'      =>  'Uploads/', //保存路径
                );
                //附件上传到路径:根目录/保存目录路径/创建日期目录
                if (!$z) {
                    show_bug($upload -> getError()); 
                } else {
                    //show_bug($z); 
                    //拼装图片的路径名
                    $bigimg = $z['savepath'].$z['savename'];
                    $_POST['goods_big_img'] = $bigimg;

                    //把已经上传好的图片制作缩略图Image.class.php
                    $image = new \Think\Image();
                    //open();打开图像资源,通过路径名找到图像
                    //$upload -> rootPath 直接调用
                    $srcimg = $upload -> rootPath.$bigimg;
                    $image -> open($srcimg);
                    $image -> thumb(150,150);//按照比例缩小
                    $smallimg = $z['savepath']."small_".$z['savename'];
                    $image ->save($upload->rootPath.$smallimg);
                    $_POST['goods_small_img'] = $smallimg;
                }   
            }
            $goods -> create();
            $z = $goods -> add($ar);
            if ($z) {
                echo "success";
            } else {
                echo "failure";
            }       
        } else {
        }   
        $this->display();
    }

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

<img src="{$smarty.const.IMG_UPLOAD}{$v.goods_small_img}" height="40" width="40"/>

8.面向切面编程Behavior分析

  面向切面是一种设置模式
  把一个大块的功能分解成小块的功能
  这样小块的功能利于开发、维护、升级、部署

TP框架的行为Behavior执行

1、框架执行流程分析:index.php、ThinkPHP.php、Think.class.php(主要体现)、App.class.php
//TP框架的面向切面编程设计体现在Behavior行为中

2、Think::start();
//index.php包含ThinkPHP.php,ThinkPHP.php应用初始化Think::start();

3、ThinkPHP/Conf/Mode/common.php中的tags标签内容就是行为的内容
//Think.class.php的start()方法读取、加载应用模式(ThinkPHP/Conf/Mode/common.php)并进行相关操作

4、自定义shop/Common/conf/tags.php文件
//自定义tags.php内容会覆盖指定的common.php的配置内容

App.class.php
Think.class.php调用App.class.php

1function run();
//Think.class.php的start()方法中运行应用App::run();

2、Hook::listen('app_begin');
//App.class.php中run()方法,调用Hook.class.php的listen()方法

3、tags标签的内容解析出来:CheckLang
//Hook.class.php的listen()处理传入的tags标签内容

4self::exec('CheckLang');
//listen()方法内调用当前类的exec()方法实例化对象new CheckLangBehavior并处理CheckLangBehavior

5、obj -> run(); 运行具体行为
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值