1. 程式人生 > >PHP.25-TP框架商城應用實例-後臺1-添加商品功能、鉤子函數、在線編輯器、過濾XSS、上傳圖片並生成縮略圖

PHP.25-TP框架商城應用實例-後臺1-添加商品功能、鉤子函數、在線編輯器、過濾XSS、上傳圖片並生成縮略圖

引用傳遞 none move 名稱 textarea 如果 library time fields

添加商品功能

  1、創建商品控制器【C】  /www.test.com/shop/Admin/Controller/GoodsController.class.php

技術分享
<?php
namespace Admin\Controller;
use Think\Controller;

//後臺添加商品功能控制器
class GoodsController extends Controller 
{   
    //顯示和處理表單
    public function add()
    {
        //判斷用戶是否提交了表單(如果提交了,就在if中處理表單,否則顯示表單)
        if(IS_POST){    //
IS_POST:TP自帶常量:當前是否POST請求 $model = D(‘goods‘); //D()實例化/Model/中模型goods //2.CREATE方法:a.接收數據並保存到模型中 b.根據模型中定義的規則驗證表單 /** *第一個參數:要接收的數據默認是$_POST *第二個參數:表單的類型。當前是添加還是修改的表單,1:添加 2:修改 *$_POST:表單中原始的數據,I(‘post.‘):過濾後的$_POST的數據,過濾XSS攻擊 *
*/ if($model->create(I(‘post‘), 1)) { //插入數據庫中 if($model->add()) { //顯示成功信息並等待1秒之後跳轉 $this->success(‘操作成功!‘, U(‘lst‘)); exit; } }
//如果上面失敗了在這裏處理失敗的請求 //從模型中取出失敗的原因 $error = $model->getError(); //由控制器顯示錯誤信息,並在3秒跳回上一個頁面[error()默認3秒] $this->error($error); } //顯示表單 $this->display(); } //商品列表頁 public function lst() { echo "列表頁"; } }
GoodsController.class.php

註意:控制器中的代碼都很少,具體的業務代碼都寫到模型中,所有的控制器其他curd的代碼基本相同,區別就是生成不同的模型

  2、創建商品模型【M】  /www.test.com/shop/Admin/Model/GoodsModel.class.php

技術分享
<?php
    namespace Admin\Model;
    use Think\Model;
    
    class GoodsModel extends Model
    {    
        //添加調用create方法允許接收的字段
        protected $insertFields = ‘goods_name,market_price,shop_price,is_on_sale,goods_desc‘;
        //定義驗證規則    validate:TP模型層提供的一種數據驗證方法 
            //a.靜態方式:在模型類裏面通過$_validate屬性定義驗證規則。b.動態方式:使用模型類的validate方法動態創建自動驗證規則 
            //定義好驗證規則後,就可以在使用create方法創建數據對象的時候自動調用
        protected $_validate = array(
            array(‘goods_name‘, ‘require‘, ‘商品名稱不能為空!‘, ‘1‘),
            array(‘market_price‘, ‘currency‘, ‘市場價格必須是貨幣!‘, ‘1‘),
            array(‘shop_price‘, ‘currency‘, ‘本店價格必須是貨幣類型!‘, ‘1‘),
        );
        
        //鉤子方法_before_insert:添加前插入,在添加前會自動調用
        //第一個參數:表單中即將要被插入數據庫中的數據=>數組
        //&按引用傳遞:函數外部的變量的值要在函數內部修改的話,必須按引用傳遞,除非傳遞的為對象,因為對象默認按引用傳遞
        protected function _before_insert(&$data, $option)
        {
            /**************處理LOGO******************/
            //判斷有沒有選擇圖片
            if($_FILES[‘logo‘][‘error‘] == 0){
                $upload = new \Think\Upload();    //實例化上傳類
                $upload->maxSize = 1024*1024;    //1M
                $upload->exts = array(‘jpg‘, ‘gif‘, ‘png‘, ‘jpeg‘);    //設置附件上傳類型
                $upload->rootPath = ‘./Public/Uploads/‘;        //設置附件上傳根目錄
                $upload->savePath = ‘Goods/‘;        //設置附件上傳子目錄
                //上傳文件
                $info =  $upload->upload();
                if(!$info){
                    //獲取失敗原因把錯誤信息保存到模型的error屬性中,然後在控制器裏調用$model—>getError()獲取錯誤信息並由控制器打印
                    $this->error = $upload->getError();
                    return FALSE;
                }else{
                    //上傳成功,並生成縮略圖
                    //先拼成原圖上的路徑
                    $logo = $info[‘logo‘][‘savepath‘] . $info[‘logo‘][‘savename‘];
                    //拼出縮略圖的路徑和名稱
                    $mbiglogo = $info[‘logo‘][‘savepath‘] .‘mbig_‘. $info[‘logo‘][‘savename‘];
                    $biglogo = $info[‘logo‘][‘savepath‘] .‘big_‘. $info[‘logo‘][‘savename‘];
                    $midlogo = $info[‘logo‘][‘savepath‘] .‘mid_‘. $info[‘logo‘][‘savename‘];
                    $smlogo = $info[‘logo‘][‘savepath‘] .‘sm_‘. $info[‘logo‘][‘savename‘];
                    $image = new \Think\Image();
                    //打開要生成縮略圖的圖片
                    $image->open(‘./Public/Uploads/‘.$logo);
                    //生成縮略圖
                    $image->thumb(700, 700)->save(‘./Public/Uploads/‘.$mbiglogo);
                    $image->thumb(350, 350)->save(‘./Public/Uploads/‘.$biglogo);
                    $image->thumb(130, 130)->save(‘./Public/Uploads/‘.$midlogo);
                    $image->thumb(50, 50)->save(‘./Public/Uploads/‘.$smlogo);
                    /**************把路徑放到表單中*****************/
                    $data[‘logo‘] = $logo;
                    $data[‘mbig_logo‘] = $mbiglogo;
                    $data[‘big_logo‘] = $biglogo;
                    $data[‘mid_logo‘] = $midlogo;
                    $data[‘sm_logo‘] = $smlogo;
                }
            }
            //獲取當前時間並添加到表單中,這樣就會插入數據庫中
            $data[‘addtime‘] = date(‘Y-m-d H:i:s‘, time());
            //過濾這個字段
            $data[‘goods_desc‘] = removeXSS($_POST[‘goods_desc‘]);
        }
    }
?>
GoodsModel.class.php

  3、創建一個添加商品的表單【V】  /www.test.com/shop/Admin/View/Goods/add.html

技術分享
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>ECSHOP 管理中心 - 添加新商品 </title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<link href="__PUB__/Admin/Styles/general.css" rel="stylesheet" type="text/css" />
<link href="__PUB__/Admin/Styles/main.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>
    <span class="action-span"><a href="__GROUP__/Goods/goodsList">商品列表</a>
    </span>
    <span class="action-span1"><a href="__GROUP__">ECSHOP 管理中心</a></span>
    <span id="search_id" class="action-span1"> - 添加新商品 </span>
    <div style="clear:both"></div>
</h1>

<div class="tab-div">
    <div id="tabbar-div">
        <p>
            <span class="tab-front" id="general-tab">通用信息</span>
        </p>
    </div>
    <div id="tabbody-div">
        <form enctype="multipart/form-data" action="__SELF__" method="post" >
            <table width="90%" id="general-table" align="center">
                <tr>
                    <td class="label">商品名稱:</td>
                    <td><input type="text" name="goods_name" value=""size="30" />
                    <span class="require-field">*</span></td>
                </tr>
                <tr>
                    <td class="label">市場售價:</td>
                    <td>
                        <input type="text" name="market_price" value="0" size="20" />
                         <span class="require-field">*</span>
                    </td>
                </tr>
                <tr>
                    <td class="label">本店售價:</td>
                    <td>
                        <input type="text" name="shop_price" value="0" size="20"/>
                        <span class="require-field">*</span>
                    </td>
                </tr> 
                <tr>
                    <td class="label">是否上架:</td>
                    <td>
                        <input type="radio" name="is_on_sale" value="1" checked="checked" /><input type="radio" name="is_on_sale" value="0" /></td>
                </tr>
                <tr>
                    <td class="label">商品描述:</td>
                    <td>
                        <textarea id="goods_desc" name="goods_desc"></textarea>
                    </td>
                </tr>
            </table>
            <div class="button-div">
                <input type="submit" value=" 確定 " class="button"/>
                <input type="reset" value=" 重置 " class="button" />
            </div>
        </form>
    </div>
</div>

<div id="footer">
共執行 9 個查詢,用時 0.025161 秒,Gzip 已禁用,內存占用 3.258 MB<br />
版權所有 &copy; 2005-2012 上海商派網絡科技有限公司,並保留所有權利。</div>
</body>
</html>

<!--導入在線編輯器-->
   <link href="__PUB__/umeditor1.2.3-utf8-php/themes/default/css/umeditor.css" type="text/css" rel="stylesheet">
    <script type="text/javascript" src="__PUB__/umeditor1.2.3-utf8-php/third-party/jquery.min.js"></script>
    <script type="text/javascript" src="__PUB__/umeditor1.2.3-utf8-php/third-party/template.min.js"></script>
    <script type="text/javascript" charset="utf-8" src="__PUB__/umeditor1.2.3-utf8-php/umeditor.config.js"></script>
    <script type="text/javascript" charset="utf-8" src="__PUB__/umeditor1.2.3-utf8-php/umeditor.min.js"></script>
    <script type="text/javascript" src="__PUB__/umeditor1.2.3-utf8-php/lang/zh-cn/zh-cn.js"></script>
    <script>
        UM.getEditor(‘goods_desc‘, {
            initialFrameWidth: "100%",
            initialFrameHeight: 150
        });
    </script>
add.html

   註意:修改Js、Images、Styles等路徑。提交到當前方法add,一般為action=__SELF__;商品名稱等提交數據名要與數據庫中的表字段名相同可通過配置文件修改,以防止數據庫表字段名被人窺探。

  4、修改配置文件添加DB配置,連接數據庫  /www.test.com/shop/Common/Conf/conf.php

技術分享Conf.php

  註意問題:

1.模型GoodsModel.class.php中表單規則的第四個參數1:代表必須驗證,不寫會默認為0【存在字段就驗證】,防止用戶偽造不合法表單

技術分享

技術分享

2.在GoodsModel.class.php中,防止表單出現非法字段,以免數據庫被插入非法字段數據【例如:傳入超額id(自增),導致後繼數據無法插入】

技術分享

3.在TP中接收用戶的數據必須使用I函數接收:

用法:

      $_GET[‘name’] --> I(‘get.name’);

      $_POST[‘name’] --> I(‘post.name’);

      $_POST --> I(‘post.’);

在conf.php配置文件中重新定義過濾函數

技術分享

4.鉤子函數:tp提供的可在數據添加、修改、刪除之前或者之後要執行某些動作代碼,在模型類中使用,類似自定義函數

  如:數據在添加到數據之前先獲取當前系統時間添加到表單中

技術分享

    基本上所有的代碼都寫在模型中,還有其他的鉤子方法:

      _before_insert(&$data, $option)  _after_insert($data, $option)

      _before_update(&$data, $option)  _after_update($data, $option)

      _before_delete($option)      _after_delete($option)

      比如上傳圖片的代碼等等。

5.在線編輯器--UM

技術分享

下載,解壓到Public

技術分享

在需要放編輯器的頁面底部(可以是其他地方,js代碼一般放底部),首先要先給需要編輯器的地方加個id,如:<textarea id="goods_desc">

技術分享

    :記得修改路徑

6.文本域過濾XSS

下載HtmlPrifier,解壓,將library取到根目錄改名為HtmlPrifier,在/www.39.com/Common/Common/functions.php指定函數調用HtmlPrifier

技術分享

技術分享
 <?php
    //有選擇性的過濾XSS --》說明:性能非常低-》盡量少用
    function removeXSS($data)
    {
        require_once ‘./HtmlPurifier.auto.php‘;
        
        $_clean_xss_config = HTMLPurifier_Config::createDefault();
        $_clean_xss_config->set(‘Core.Encoding‘, ‘UTF-8‘);
        //設置保留的標簽
        $_clean_xss_config->set(‘HTML.Allowed‘,‘div,b,strong,i,em,a[href|title],ul,ol,li,p[style],br,span[style],img[width|height|alt|src]‘);
        $_clean_xss_config->set(‘CSS.AllowedProperties‘, ‘font,font-size,font-weight,font-style,font-family,text-decoration,padding-left,color,background-color,text-align‘);
        $_clean_xss_config->set(‘HTML.TargetBlank‘, TRUE);
        $_clean_xss_obj = new HTMLPurifier($_clean_xss_config);
        //執行過濾
        return $_clean_xss_obj->purify($data);
    }
 ?>
removeXSS

技術分享

  

  添加商品時為商品上傳圖片並生成縮略圖

作用:1. 節省帶寬;2. 瀏覽加載快,提高用戶體驗

根據前臺頁面圖片尺寸需要,決定生成幾張縮略圖以及其尺寸。如:列表頁:130*130;商品詳情頁:350*350;商品詳情頁小圖:50*50;放大鏡:700*700

1、先在數據庫中添加好相應的字段[ALTER TABLE]

ALTER TABLE p39_goods ADD logo varchar(150) not null default ‘‘ comment ‘原圖‘;
ALTER TABLE p39_goods ADD sm_logo varchar(150) not null default ‘‘ comment ‘小圖‘;
ALTER TABLE p39_goods ADD mid_logo varchar(150) not null default ‘‘ comment ‘中圖‘;
ALTER TABLE p39_goods ADD big_logo varchar(150) not null default ‘‘ comment ‘大圖‘;
ALTER TABLE p39_goods ADD mbig_logo varchar(150) not null default ‘‘ comment ‘特大圖‘;

    2、在頁面中add.html中增加文件上傳按鈕,註意表單一定要加上enctype="multipart/form-data" 才能上傳文件

技術分享

3、在模型類GoodsModel.class.php中的_before_insert()函數中,執行上傳和縮略圖

在tp手冊中有實例

技術分享

技術分享
protected function _before_insert(&$data, $option)
        {
            /**************處理LOGO******************/
            //判斷有沒有選擇圖片
            if($_FILES[‘logo‘][‘error‘] == 0){
                $upload = new \Think\Upload();    //實例化上傳類
                $upload->maxSize = 1024*1024;    //1M
                $upload->exts = array(‘jpg‘, ‘gif‘, ‘png‘, ‘jpeg‘);    //設置附件上傳類型
                $upload->rootPath = ‘./Public/Uploads/‘;        //設置附件上傳根目錄
                $upload->savePath = ‘Goods/‘;        //設置附件上傳子目錄
                //上傳文件
                $info =  $upload->upload();
                if(!$info){
                    //獲取失敗原因把錯誤信息保存到模型的error屬性中,然後在控制器裏調用$model—>getError()獲取錯誤信息並由控制器打印
                    $this->error = $upload->getError();
                    return FALSE;
                }else{
                    //上傳成功,並生成縮略圖
                    //先拼成原圖上的路徑
                    $logo = $info[‘logo‘][‘savepath‘] . $info[‘logo‘][‘savename‘];
                    //拼出縮略圖的路徑和名稱
                    $mbiglogo = $info[‘logo‘][‘savepath‘] .‘mbig_‘. $info[‘logo‘][‘savename‘];
                    $biglogo = $info[‘logo‘][‘savepath‘] .‘big_‘. $info[‘logo‘][‘savename‘];
                    $midlogo = $info[‘logo‘][‘savepath‘] .‘mid_‘. $info[‘logo‘][‘savename‘];
                    $smlogo = $info[‘logo‘][‘savepath‘] .‘sm_‘. $info[‘logo‘][‘savename‘];
                    $image = new \Think\Image();
                    //打開要生成縮略圖的圖片
                    $image->open(‘./Public/Uploads/‘.$logo);
                    //生成縮略圖
                    $image->thumb(700, 700)->save(‘./Public/Uploads/‘.$mbiglogo);
                    $image->thumb(350, 350)->save(‘./Public/Uploads/‘.$biglogo);
                    $image->thumb(130, 130)->save(‘./Public/Uploads/‘.$midlogo);
                    $image->thumb(50, 50)->save(‘./Public/Uploads/‘.$smlogo);
                    /**************把路徑放到表單中*****************/
                    $data[‘logo‘] = $logo;
                    $data[‘mbig_logo‘] = $mbiglogo;
                    $data[‘big_logo‘] = $biglogo;
                    $data[‘mid_logo‘] = $midlogo;
                    $data[‘sm_logo‘] = $smlogo;
                }
            }
            //獲取當前時間並添加到表單中,這樣就會插入數據庫中
            $data[‘addtime‘] = date(‘Y-m-d H:i:s‘, time());
            //過濾這個字段
            $data[‘goods_desc‘] = removeXSS($_POST[‘goods_desc‘]);
        }
圖片處理

PHP.25-TP框架商城應用實例-後臺1-添加商品功能、鉤子函數、在線編輯器、過濾XSS、上傳圖片並生成縮略圖