<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TP5.0 &#8211; 个人随笔</title>
	<atom:link href="/classify/%E5%90%8E%E5%8F%B0%E6%A1%86%E6%9E%B6/tp5-0/feed" rel="self" type="application/rss+xml" />
	<link>/</link>
	<description></description>
	<lastBuildDate>Sun, 17 Jun 2018 08:03:35 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6.1</generator>

<image>
	<url>/wp-content/uploads/2022/01/cropped-截屏2022-01-01-18.57.09-32x32.png</url>
	<title>TP5.0 &#8211; 个人随笔</title>
	<link>/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>TP5.0（一）部署、控制器、模块、命令行、路由、视图、模板赋值、常用标签、搭建后台首页、搭建登录页、页面跳转与重定向、Request 对象</title>
		<link>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7391.html</link>
					<comments>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7391.html#respond</comments>
		
		<dc:creator><![CDATA[Mr.Lee]]></dc:creator>
		<pubDate>Sat, 09 Jun 2018 00:44:26 +0000</pubDate>
				<category><![CDATA[TP5.0]]></category>
		<category><![CDATA[后台框架]]></category>
		<category><![CDATA[Request 对象]]></category>
		<category><![CDATA[命令行]]></category>
		<category><![CDATA[常用标签]]></category>
		<category><![CDATA[控制器]]></category>
		<category><![CDATA[搭建后台首页]]></category>
		<category><![CDATA[搭建登录页]]></category>
		<category><![CDATA[模块]]></category>
		<category><![CDATA[模板赋值]]></category>
		<category><![CDATA[视图]]></category>
		<category><![CDATA[路由]]></category>
		<category><![CDATA[部署]]></category>
		<category><![CDATA[页面跳转与重定向]]></category>
		<guid isPermaLink="false">/?p=7391</guid>

					<description><![CDATA[一、框架概述 1、什么是框架 框架即英文名为Framework,它是许多代码文件的集合，这些代码文件是程序结构 [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>一、框架概述</h1>
<h2>1、什么是框架</h2>
<p>框架即英文名为Framework,它是许多代码文件的集合，这些代码文件是程序结构的代码，不是业务代码，里面包含了许多函数、类库(分页类、验证码类、文件上传类、DB类、Image类&#8230;)、设计模式(mvc、单例、AR..)等。</p>
<p>以后使用框架开发项目只需要写业务代码即可。</p>
<p>现在企业中开发模式基本有三种:</p>
<p>从快到慢排序：二次开发(需要修改源码)&#8212;&gt;框架开发&#8212;-&gt;源码开发</p>
<p>源码开发建房子：从0开始，打地基.、浇筑水泥、、</p>
<p>框架开发建房子：相当于毛坯房,各种装修。</p>
<p>源码开发建房子：相当于精装修的房子，只需要拎包入住.</p>
<p>现在企业开发较多的模式属框架开发。</p>
<h2>2、框架开发的好处</h2>
<ul>
<li>框架能节省开发时间</li>
</ul>
<p>每个项目中常用的类库框架都已经封装好，如分页类、图像类,文件上传类等，直接调用即可,非常方便。（减少重复造轮子）</p>
<ul>
<li>利于团队的合作开发</li>
</ul>
<p>因为框架都是mvc设计模式,模块划分清晰，可以帮助我们快速、稳定、高效搭建web应用，从而提高开发效率。</p>
<ul>
<li>使用框架的过程中可以使得我们的注意力全部集中在业务层面，而无需关心程序的底层架构。</li>
</ul>
<h2>3、框架的设计模式(MVC)</h2>
<p>基本现在主流的框架(CI、TP、laravel、YII、zend framework、symfony、cakephp),都是采用单一入口(index.php),且都是采用mvc的设计模式，把一个web应用程序分为三块,控制器、模型、视图。</p>
<p>C-Controller 控制器</p>
<p>主要作用:就是接收用户的请求,在模型和视图之间起一个调度的作用</p>
<p>M-Model 模型</p>
<p>作用:对数据库做增删改查(curd)的</p>
<p>V-View视图</p>
<p>展示模板内容,给用户一个可操作的界面</p>
<p><strong>mvc(框架)形象理解-酒店（难以理解的东西一定要把抽象的东西给生活化）：</strong></p>
<p><img fetchpriority="high" decoding="async" width="1185" height="451" class="wp-image-7392" src="/wp-content/uploads/2018/06/word-image.png" srcset="/wp-content/uploads/2018/06/word-image.png 1185w, /wp-content/uploads/2018/06/word-image-300x114.png 300w, /wp-content/uploads/2018/06/word-image-768x292.png 768w, /wp-content/uploads/2018/06/word-image-1024x390.png 1024w" sizes="(max-width: 1185px) 100vw, 1185px" /></p>
<h2>常见的php开发框架</h2>
<h3>ThinkPHP框架（TP框架）</h3>
<p>TP框架的logo：</p>
<p><img decoding="async" width="102" height="70" class="wp-image-7393" src="/wp-content/uploads/2018/06/word-image-1.png" /></p>
<p>主要开发中小型项目</p>
<p>ThinkPHP框架是我们国人开发采用mvc模式设计的一款比较优秀的框架。在我们国内使用量较多，且开发文档也多，方便学习。</p>
<h3>（2）CodeIgniter 框架</h3>
<p>CodeIgniter框架：简称CI框架,</p>
<p>主要开发中小型项目</p>
<p><img decoding="async" width="823" height="376" class="wp-image-7394" src="/wp-content/uploads/2018/06/word-image-2.png" srcset="/wp-content/uploads/2018/06/word-image-2.png 823w, /wp-content/uploads/2018/06/word-image-2-300x137.png 300w, /wp-content/uploads/2018/06/word-image-2-768x351.png 768w" sizes="(max-width: 823px) 100vw, 823px" /></p>
<h3>YII(易框架)</h3>
<p>YII(简称易框架):主要开发大型的web应用程序:</p>
<p><img loading="lazy" decoding="async" width="818" height="417" class="wp-image-7395" src="/wp-content/uploads/2018/06/word-image-3.png" srcset="/wp-content/uploads/2018/06/word-image-3.png 818w, /wp-content/uploads/2018/06/word-image-3-300x153.png 300w, /wp-content/uploads/2018/06/word-image-3-768x392.png 768w" sizes="(max-width: 818px) 100vw, 818px" /></p>
<h3>Laravel框架</h3>
<p>此框架使用量世界排名第一,有最”优雅”的框架称号。</p>
<p>注：Laravel底层代码很多都是借鉴了SymFony的优点。</p>
<p><img loading="lazy" decoding="async" width="727" height="477" class="wp-image-7396" src="/wp-content/uploads/2018/06/word-image-4.png" srcset="/wp-content/uploads/2018/06/word-image-4.png 727w, /wp-content/uploads/2018/06/word-image-4-300x197.png 300w" sizes="(max-width: 727px) 100vw, 727px" /></p>
<p>&nbsp;</p>
<h3>（5）Zend官方框架</h3>
<p>Zend Framework：php官方提供的框架，非常笨重，主要开发大型的web应用程序。</p>
<p><img loading="lazy" decoding="async" width="729" height="346" class="wp-image-7397" src="/wp-content/uploads/2018/06/word-image-5.png" srcset="/wp-content/uploads/2018/06/word-image-5.png 729w, /wp-content/uploads/2018/06/word-image-5-300x142.png 300w" sizes="(max-width: 729px) 100vw, 729px" /></p>
<h3>（6）Symfony国外框架</h3>
<p><img loading="lazy" decoding="async" width="687" height="480" class="wp-image-7398" src="/wp-content/uploads/2018/06/word-image-6.png" srcset="/wp-content/uploads/2018/06/word-image-6.png 687w, /wp-content/uploads/2018/06/word-image-6-300x210.png 300w" sizes="(max-width: 687px) 100vw, 687px" /></p>
<p>框架只有最合适的，没有最好的，需结合自己的系统业务去选择最合适的。</p>
<p>国内使用最多的框架是TP、laravel、CI。YII框架外企使用较多</p>
<h1>ThinkPHP5框架</h1>
<h2>下载TP5框架</h2>
<p>下载地址：<a href="/goto/rc3y" rel="nofollow">http://www.thinkphp.cn/down.html</a></p>
<p><img loading="lazy" decoding="async" width="671" height="101" class="wp-image-7399" src="/wp-content/uploads/2018/06/word-image-7.png" srcset="/wp-content/uploads/2018/06/word-image-7.png 671w, /wp-content/uploads/2018/06/word-image-7-300x45.png 300w" sizes="(max-width: 671px) 100vw, 671px" /></p>
<p><img loading="lazy" decoding="async" width="192" height="27" class="wp-image-7400" src="/wp-content/uploads/2018/06/word-image-8.png" /></p>
<h2>TP5框架的目录认识</h2>
<p>手册位置：基础&#8211;&gt;目录结构</p>
<ol>
<li>project 应用部署目录</li>
<li>├─application 应用目录（可设置）</li>
<li>│ ├─common 公共模块目录（可更改）</li>
<li>│ ├─index 模块目录(可更改)</li>
<li>│ │ ├─config.php 模块配置文件</li>
<li>│ │ ├─common.php 模块函数文件</li>
<li>│ │ ├─controller 控制器目录</li>
<li>│ │ ├─model 模型目录</li>
<li>│ │ ├─view 视图目录</li>
<li>│ │ └─ &#8230; 更多类库目录</li>
<li>│ ├─command.php 命令行工具配置文件</li>
<li>│ ├─common.php 应用公共（函数）文件</li>
<li>│ ├─config.php 应用（公共）配置文件</li>
<li>│ ├─database.php 数据库配置文件</li>
<li>│ ├─tags.php 应用行为扩展定义文件</li>
<li>│ └─route.php 路由配置文件</li>
<li>├─extend 扩展类库目录（可定义）</li>
<li>├─public WEB 部署目录（对外访问目录）</li>
<li>│ ├─static 静态资源存放目录(css,js,image)</li>
<li>│ ├─index.php 应用入口文件</li>
<li>│ ├─router.php 快速测试文件</li>
<li>│ └─.htaccess 用于 apache 的重写</li>
<li>├─runtime 应用的运行时目录（可写，可设置）</li>
<li>├─vendor 第三方类库目录（Composer）</li>
<li>├─thinkphp 框架系统目录</li>
<li>│ ├─lang 语言包目录</li>
<li>│ ├─library 框架核心类库目录</li>
<li>│ │ ├─think Think 类库包目录</li>
<li>│ │ └─traits 系统 Traits 目录</li>
<li>│ ├─tpl 系统模板目录</li>
<li>│ ├─.htaccess 用于 apache 的重写</li>
<li>│ ├─.travis.yml CI 定义文件</li>
<li>│ ├─base.php 基础定义文件</li>
<li>│ ├─composer.json composer 定义文件</li>
<li>│ ├─console.php 控制台入口文件</li>
<li>│ ├─convention.php 惯例配置文件</li>
<li>│ ├─helper.php 助手函数文件（可选）</li>
<li>│ ├─LICENSE.txt 授权说明文件</li>
<li>│ ├─phpunit.xml 单元测试配置文件</li>
<li>│ ├─README.md README 文件</li>
<li>│ └─start.php 框架引导文件</li>
<li>├─build.php 自动生成定义文件（参考）</li>
<li>├─composer.json composer 定义文件</li>
<li>├─LICENSE.txt 授权说明文件</li>
<li>├─README.md README 文件</li>
<li>├─think 命令行入口文件</li>
</ol>
<p>每个application下面的模块目录都有mvc分层结构：</p>
<p><img loading="lazy" decoding="async" width="380" height="187" class="wp-image-7401" src="/wp-content/uploads/2018/06/word-image-9.png" srcset="/wp-content/uploads/2018/06/word-image-9.png 380w, /wp-content/uploads/2018/06/word-image-9-300x148.png 300w" sizes="(max-width: 380px) 100vw, 380px" /></p>
<p>可参考手册：</p>
<p><img loading="lazy" decoding="async" width="979" height="138" class="wp-image-7402" src="/wp-content/uploads/2018/06/word-image-10.png" srcset="/wp-content/uploads/2018/06/word-image-10.png 979w, /wp-content/uploads/2018/06/word-image-10-300x42.png 300w, /wp-content/uploads/2018/06/word-image-10-768x108.png 768w" sizes="(max-width: 979px) 100vw, 979px" /></p>
<h1>三、使用TP5框架部署项目</h1>
<p>我们是使用ThinkPHP5+ajax+jquery以及和第三方插件结合起来，做一个文章管理系统，掌握怎样使用ThinkPHP5快速开发一个项目。</p>
<h2>配置项目虚拟主机</h2>
<p>主要三个核心步骤：1、使用phpStudy建立虚拟主机 2、设置hosts文件映射 3、重启apache服务器</p>
<p>把框架的文件复制到我们的虚拟主机目录中去：</p>
<p><img loading="lazy" decoding="async" width="652" height="417" class="wp-image-7403" src="/wp-content/uploads/2018/06/word-image-11.png" srcset="/wp-content/uploads/2018/06/word-image-11.png 652w, /wp-content/uploads/2018/06/word-image-11-300x192.png 300w" sizes="(max-width: 652px) 100vw, 652px" /></p>
<ol>
<li>使用phpStudy建立虚拟主机 (www.article.com)</li>
</ol>
<p><img loading="lazy" decoding="async" width="287" height="109" class="wp-image-7404" src="/wp-content/uploads/2018/06/word-image-12.png" /></p>
<p>最终生成的虚拟主机文件（vhosts.conf）配置如下：</p>
<p><img loading="lazy" decoding="async" width="488" height="206" class="wp-image-7405" src="/wp-content/uploads/2018/06/word-image-13.png" srcset="/wp-content/uploads/2018/06/word-image-13.png 488w, /wp-content/uploads/2018/06/word-image-13-300x127.png 300w" sizes="(max-width: 488px) 100vw, 488px" /></p>
<ol>
<li>设置hosts文件映射</li>
</ol>
<p><img loading="lazy" decoding="async" width="374" height="27" class="wp-image-7406" src="/wp-content/uploads/2018/06/word-image-14.png" srcset="/wp-content/uploads/2018/06/word-image-14.png 374w, /wp-content/uploads/2018/06/word-image-14-300x22.png 300w" sizes="(max-width: 374px) 100vw, 374px" /></p>
<ol>
<li>重启apache服务器</li>
</ol>
<h2>2、访问虚拟主机</h2>
<p>输入配置的域名直接访问：</p>
<p><img loading="lazy" decoding="async" width="806" height="368" class="wp-image-7407" src="/wp-content/uploads/2018/06/word-image-15.png" srcset="/wp-content/uploads/2018/06/word-image-15.png 806w, /wp-content/uploads/2018/06/word-image-15-300x137.png 300w, /wp-content/uploads/2018/06/word-image-15-768x351.png 768w" sizes="(max-width: 806px) 100vw, 806px" /></p>
<p>为什么会出现上面的一个笑脸？</p>
<p>答：那是因为受到框架的配置文件application/config.php的影响，默认访问index模块的index控制器的index方法，如下：</p>
<p><img loading="lazy" decoding="async" width="682" height="269" class="wp-image-7408" src="/wp-content/uploads/2018/06/word-image-16.png" srcset="/wp-content/uploads/2018/06/word-image-16.png 682w, /wp-content/uploads/2018/06/word-image-16-300x118.png 300w" sizes="(max-width: 682px) 100vw, 682px" /></p>
<p>可以对index控制器的index方法的内容进行更改：</p>
<p><img loading="lazy" decoding="async" width="668" height="231" class="wp-image-7409" src="/wp-content/uploads/2018/06/word-image-17.png" srcset="/wp-content/uploads/2018/06/word-image-17.png 668w, /wp-content/uploads/2018/06/word-image-17-300x104.png 300w" sizes="(max-width: 668px) 100vw, 668px" /></p>
<p>再次访问如下：</p>
<p><img loading="lazy" decoding="async" width="230" height="70" class="wp-image-7410" src="/wp-content/uploads/2018/06/word-image-18.png" /></p>
<p>注：tp5默认值支持老本tp3的pathinfo模式进行访问。</p>
<p>如：<a href="/goto/sbfh" rel="nofollow">http://域名/index.php/</a><a href="/goto/sbfh" rel="nofollow">模块/控制器/方法名</a><a href="/goto/sbfh" rel="nofollow">/参数1/值1/参数2/值2/</a></p>
<p>例：访问index模块的index 控制器的index方法</p>
<p>http://域名/index.php/index/index/index/参数1/值1/参数2/值2/</p>
<h2>3、响应输出</h2>
<p>控制器的所有操作方法都是return返回而不是直接输出，系统会调用Response::send方法将最终的应用返回的数据输出到页面或者客户端，并自动转换成default_return_type参数配置的格式。所以，应用执行的数据输出只需要返回一个正常的PHP数据即可。</p>
<p>tp5也是建议统一使用return返回数据，而不是echo输出，如非必要，请不要使用exit或者die中断执行。</p>
<p><img loading="lazy" decoding="async" width="509" height="59" class="wp-image-7411" src="/wp-content/uploads/2018/06/word-image-19.png" srcset="/wp-content/uploads/2018/06/word-image-19.png 509w, /wp-content/uploads/2018/06/word-image-19-300x35.png 300w" sizes="(max-width: 509px) 100vw, 509px" /></p>
<h1>四、控制器</h1>
<h2>控制器的作用</h2>
<p>C：Controller</p>
<p>作用：主要是接受用户的请求，在模型和视图之间起调度的作用。</p>
<h2>创建控制器</h2>
<h3>（1）修改控制器后缀</h3>
<p>由于国人命名的习惯，我们可以通过以下配置文件给控制器文件名加个Controller后缀。</p>
<p>打开配置文件，[项目目录]/application/config.php，做如下修改：</p>
<p><img loading="lazy" decoding="async" width="999" height="207" class="wp-image-7412" src="/wp-content/uploads/2018/06/word-image-20.png" srcset="/wp-content/uploads/2018/06/word-image-20.png 999w, /wp-content/uploads/2018/06/word-image-20-300x62.png 300w, /wp-content/uploads/2018/06/word-image-20-768x159.png 768w" sizes="(max-width: 999px) 100vw, 999px" /></p>
<h3>创建控制器语法</h3>
<p>语法规则：</p>
<p>控制器类名：控制器名+Controller</p>
<p>控制器文件名：控制器名+Controller.php</p>
<p>控制器文件所在路径：application/模块名/controller/</p>
<p>如在index模块下定义一个Test控制器：</p>
<p>控制器类名： TestController</p>
<p>控制器类文件名： TestController.php</p>
<p>文件定义位置：index/controller/TestController.php</p>
<p>注：类名首字母大写</p>
<p>代码如下：</p>
<p><img loading="lazy" decoding="async" width="683" height="298" class="wp-image-7413" src="/wp-content/uploads/2018/06/word-image-21.png" srcset="/wp-content/uploads/2018/06/word-image-21.png 683w, /wp-content/uploads/2018/06/word-image-21-300x131.png 300w" sizes="(max-width: 683px) 100vw, 683px" /></p>
<p>访问：</p>
<p><img loading="lazy" decoding="async" width="499" height="64" class="wp-image-7414" src="/wp-content/uploads/2018/06/word-image-22.png" srcset="/wp-content/uploads/2018/06/word-image-22.png 499w, /wp-content/uploads/2018/06/word-image-22-300x38.png 300w" sizes="(max-width: 499px) 100vw, 499px" /></p>
<h3>访问控制器</h3>
<p>1、可以通过tp3老版本的pathInfo模式进行访问。</p>
<p><a href="/goto/ghx2" rel="nofollow">http://网址/index.php/分组/控制器名称/操作方法名称</a></p>
<p>如访问Index模块的index控制器的test1方法</p>
<p><img loading="lazy" decoding="async" width="795" height="74" class="wp-image-7415" src="/wp-content/uploads/2018/06/word-image-23.png" srcset="/wp-content/uploads/2018/06/word-image-23.png 795w, /wp-content/uploads/2018/06/word-image-23-300x28.png 300w, /wp-content/uploads/2018/06/word-image-23-768x71.png 768w" sizes="(max-width: 795px) 100vw, 795px" /></p>
<p>2、也可以把index.php入口文件给隐藏掉，变为下边的路由形式：</p>
<p><a href="/goto/ghx2" rel="nofollow">http://网址/分组/控制器名称/操作方法名称</a></p>
<p>省去index.php入口访问，修改项目的重写文件.htaaccess。</p>
<p>第一步：文件位置：[项目根目录]/Public/.htaccess ,做如下修改：</p>
<p><img loading="lazy" decoding="async" width="514" height="211" class="wp-image-7416" src="/wp-content/uploads/2018/06/word-image-24.png" srcset="/wp-content/uploads/2018/06/word-image-24.png 514w, /wp-content/uploads/2018/06/word-image-24-300x123.png 300w" sizes="(max-width: 514px) 100vw, 514px" /></p>
<p>(注：上图在index.php后边加”?”号)</p>
<p>重写文件.htaccsee解释：</p>
<p>&lt;IfModule mod_rewrite.c&gt;</p>
<p>Options +FollowSymlinks -Multiviews</p>
<p>RewriteEngine On #开启重写规则</p>
<p>RewriteCond %{REQUEST_FILENAME} !-d #如果请求的不是一个目录（-d 代表目录）</p>
<p>RewriteCond %{REQUEST_FILENAME} !-f #且如果请求的不是一个文件（-f 代表文件）</p>
<p>RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L] #上面两个条件都不满足，执行RewriteRule重写规则</p>
<p>&lt;/IfModule&gt;</p>
<p>重写规则: RewriteRule 虚拟规则（正则写） 服务器真实文件路径</p>
<p>即用户输入的域名后面的规则若满足虚拟规则，就会访问对应的真实文件。</p>
<p>第二步：修改虚拟主机vhosts.conf的配置：加上AllowOverride All ，默认phpstudy创建的虚拟主机自带这一行。</p>
<p><img loading="lazy" decoding="async" width="558" height="213" class="wp-image-7417" src="/wp-content/uploads/2018/06/word-image-25.png" srcset="/wp-content/uploads/2018/06/word-image-25.png 558w, /wp-content/uploads/2018/06/word-image-25-300x115.png 300w" sizes="(max-width: 558px) 100vw, 558px" /></p>
<p>第三步。再去httpd.conf开启重写文件：</p>
<p><img loading="lazy" decoding="async" width="747" height="169" class="wp-image-7418" src="/wp-content/uploads/2018/06/word-image-26.png" srcset="/wp-content/uploads/2018/06/word-image-26.png 747w, /wp-content/uploads/2018/06/word-image-26-300x68.png 300w" sizes="(max-width: 747px) 100vw, 747px" /></p>
<p>重启apache服务器，省去入口文件index.php进行访问:</p>
<p><img loading="lazy" decoding="async" width="352" height="74" class="wp-image-7419" src="/wp-content/uploads/2018/06/word-image-27.png" srcset="/wp-content/uploads/2018/06/word-image-27.png 352w, /wp-content/uploads/2018/06/word-image-27-300x63.png 300w" sizes="(max-width: 352px) 100vw, 352px" /></p>
<h3>开启调试模式</h3>
<p>为了在开发过程中，开发者能够及时看到详细的错误信息，我们在开发阶段可以把以下config配置文件中的app_debug配置设置为true,</p>
<p><img loading="lazy" decoding="async" width="700" height="173" class="wp-image-7420" src="/wp-content/uploads/2018/06/word-image-28.png" srcset="/wp-content/uploads/2018/06/word-image-28.png 700w, /wp-content/uploads/2018/06/word-image-28-300x74.png 300w" sizes="(max-width: 700px) 100vw, 700px" /></p>
<p>访问一个不存在的方法,会报详细的错误。</p>
<p><img loading="lazy" decoding="async" width="955" height="167" class="wp-image-7421" src="/wp-content/uploads/2018/06/word-image-29.png" srcset="/wp-content/uploads/2018/06/word-image-29.png 955w, /wp-content/uploads/2018/06/word-image-29-300x52.png 300w, /wp-content/uploads/2018/06/word-image-29-768x134.png 768w" sizes="(max-width: 955px) 100vw, 955px" /></p>
<p>若设置为false,则会出现友好的提示：</p>
<p><img loading="lazy" decoding="async" width="461" height="147" class="wp-image-7422" src="/wp-content/uploads/2018/06/word-image-30.png" srcset="/wp-content/uploads/2018/06/word-image-30.png 461w, /wp-content/uploads/2018/06/word-image-30-300x96.png 300w" sizes="(max-width: 461px) 100vw, 461px" /></p>
<p>所以，项目上线后，我们要把此配置改为false。不要让用户看到我们网站报错。</p>
<h1>五、项目分组（模块）</h1>
<h2>1、创建分组</h2>
<p>一个项目中一般都有Home、Admin分组，即前台和后台，那对应框架中就是一个具体的文件夹，每个项目文件夹都有对应的控制器、模型、视图对应的文件夹，tp5框架中默认有一个分组index。</p>
<p>我们只需要把index分组复制一份改名（如admin）放在Application目录下即可，同时修改对应类所在分组的命名空间即可。</p>
<p><img loading="lazy" decoding="async" width="689" height="231" class="wp-image-7423" src="/wp-content/uploads/2018/06/word-image-31.png" srcset="/wp-content/uploads/2018/06/word-image-31.png 689w, /wp-content/uploads/2018/06/word-image-31-300x101.png 300w" sizes="(max-width: 689px) 100vw, 689px" /></p>
<p>也需要改对应类的命名空间：</p>
<p><img loading="lazy" decoding="async" width="808" height="332" class="wp-image-7424" src="/wp-content/uploads/2018/06/word-image-32.png" srcset="/wp-content/uploads/2018/06/word-image-32.png 808w, /wp-content/uploads/2018/06/word-image-32-300x123.png 300w, /wp-content/uploads/2018/06/word-image-32-768x316.png 768w" sizes="(max-width: 808px) 100vw, 808px" /></p>
<p>访问如下：</p>
<p><img loading="lazy" decoding="async" width="454" height="64" class="wp-image-7425" src="/wp-content/uploads/2018/06/word-image-33.png" srcset="/wp-content/uploads/2018/06/word-image-33.png 454w, /wp-content/uploads/2018/06/word-image-33-300x42.png 300w" sizes="(max-width: 454px) 100vw, 454px" /></p>
<h2>2、默认分组的设置</h2>
<p>需修改框架的application/config.php的配置文件，如默认访问admin分组的index控制器的index方法，做如下修改：</p>
<p><img loading="lazy" decoding="async" width="834" height="301" class="wp-image-7426" src="/wp-content/uploads/2018/06/word-image-34.png" srcset="/wp-content/uploads/2018/06/word-image-34.png 834w, /wp-content/uploads/2018/06/word-image-34-300x108.png 300w, /wp-content/uploads/2018/06/word-image-34-768x277.png 768w" sizes="(max-width: 834px) 100vw, 834px" /></p>
<p>直接输入域名访问的则是admin模块下的index控制器的index方法：</p>
<p><img loading="lazy" decoding="async" width="416" height="103" class="wp-image-7427" src="/wp-content/uploads/2018/06/word-image-35.png" srcset="/wp-content/uploads/2018/06/word-image-35.png 416w, /wp-content/uploads/2018/06/word-image-35-300x74.png 300w" sizes="(max-width: 416px) 100vw, 416px" /></p>
<h2>3、分组的访问权限控制</h2>
<p>需修改框架的application/config.php的配置文件：</p>
<p><img loading="lazy" decoding="async" width="612" height="78" class="wp-image-7428" src="/wp-content/uploads/2018/06/word-image-36.png" srcset="/wp-content/uploads/2018/06/word-image-36.png 612w, /wp-content/uploads/2018/06/word-image-36-300x38.png 300w" sizes="(max-width: 612px) 100vw, 612px" /></p>
<p>上图是设置禁止访问common和index分组。</p>
<p>再次访问index模块，会报错。</p>
<p><img loading="lazy" decoding="async" width="625" height="210" class="wp-image-7429" src="/wp-content/uploads/2018/06/word-image-37.png" srcset="/wp-content/uploads/2018/06/word-image-37.png 625w, /wp-content/uploads/2018/06/word-image-37-300x101.png 300w" sizes="(max-width: 625px) 100vw, 625px" /></p>
<h1>六、【了解】命令行操作</h1>
<h2>命令行创建分组</h2>
<p>创建文件application/build.php并填充内容，可以参考根目录 build.php</p>
<p>[项目根目录] &gt; php think build</p>
<p>创建application/build.php并填充如下内容：</p>
<p><img loading="lazy" decoding="async" width="1209" height="397" class="wp-image-7430" src="/wp-content/uploads/2018/06/word-image-38.png" srcset="/wp-content/uploads/2018/06/word-image-38.png 1209w, /wp-content/uploads/2018/06/word-image-38-300x99.png 300w, /wp-content/uploads/2018/06/word-image-38-768x252.png 768w, /wp-content/uploads/2018/06/word-image-38-1024x336.png 1024w" sizes="(max-width: 1209px) 100vw, 1209px" /></p>
<p>执行命令</p>
<p><img loading="lazy" decoding="async" width="365" height="79" class="wp-image-7431" src="/wp-content/uploads/2018/06/word-image-39.png" srcset="/wp-content/uploads/2018/06/word-image-39.png 365w, /wp-content/uploads/2018/06/word-image-39-300x65.png 300w" sizes="(max-width: 365px) 100vw, 365px" /></p>
<p>创建分组的效果</p>
<h2>命令行创建控制器</h2>
<p>[项目根目录] &gt; php think make:controller 分组/名称</p>
<p>注：不写分组名会直接创建在common分组中</p>
<p>例：在Common中生成一个Demo的控制器</p>
<p><img loading="lazy" decoding="async" width="433" height="44" class="wp-image-7432" src="/wp-content/uploads/2018/06/word-image-40.png" srcset="/wp-content/uploads/2018/06/word-image-40.png 433w, /wp-content/uploads/2018/06/word-image-40-300x30.png 300w" sizes="(max-width: 433px) 100vw, 433px" /></p>
<p>生成如下所示：</p>
<p><img loading="lazy" decoding="async" width="881" height="331" class="wp-image-7433" src="/wp-content/uploads/2018/06/word-image-41.png" srcset="/wp-content/uploads/2018/06/word-image-41.png 881w, /wp-content/uploads/2018/06/word-image-41-300x113.png 300w, /wp-content/uploads/2018/06/word-image-41-768x289.png 768w" sizes="(max-width: 881px) 100vw, 881px" /></p>
<p>例如下述，要给index分组创建UserController.php控制器文件</p>
<p>[项目根目录] &gt; php think make:controller index/User</p>
<p>命令如下；</p>
<p><img loading="lazy" decoding="async" width="494" height="48" class="wp-image-7434" src="/wp-content/uploads/2018/06/word-image-42.png" srcset="/wp-content/uploads/2018/06/word-image-42.png 494w, /wp-content/uploads/2018/06/word-image-42-300x29.png 300w" sizes="(max-width: 494px) 100vw, 494px" /></p>
<p>生成的文件：</p>
<p><img loading="lazy" decoding="async" width="817" height="341" class="wp-image-7435" src="/wp-content/uploads/2018/06/word-image-43.png" srcset="/wp-content/uploads/2018/06/word-image-43.png 817w, /wp-content/uploads/2018/06/word-image-43-300x125.png 300w, /wp-content/uploads/2018/06/word-image-43-768x321.png 768w" sizes="(max-width: 817px) 100vw, 817px" /></p>
<h1>七、使用路由访问</h1>
<p>老版本TP3.2多种访问模式（了解）：</p>
<ul>
<li>pathinfo模式（默认形式,,重点掌握）：http://域名/index.php/模块/控制器名/方法名/参数名/参数值/参数名/参数值&#8230;</li>
</ul>
<p><img loading="lazy" decoding="async" width="578" height="38" class="wp-image-7436" src="/wp-content/uploads/2018/06/word-image-44.png" srcset="/wp-content/uploads/2018/06/word-image-44.png 578w, /wp-content/uploads/2018/06/word-image-44-300x20.png 300w" sizes="(max-width: 578px) 100vw, 578px" /></p>
<ul>
<li>普通模式（get形式）：http://域名/index.php?m=模块&amp;c=控制器名&amp;a=方法名&amp;参数名=参数值&#8230;</li>
</ul>
<p><img loading="lazy" decoding="async" width="605" height="79" class="wp-image-7437" src="/wp-content/uploads/2018/06/word-image-45.png" srcset="/wp-content/uploads/2018/06/word-image-45.png 605w, /wp-content/uploads/2018/06/word-image-45-300x39.png 300w" sizes="(max-width: 605px) 100vw, 605px" /></p>
<ul>
<li>rewrite模式（隐藏入口文件）：<a href="/goto/98sz" rel="nofollow">http://域名/模块/控制器名/方法名/参数名/参数值/参数名/参数值&#8230;</a></li>
</ul>
<p><img loading="lazy" decoding="async" width="515" height="82" class="wp-image-7438" src="/wp-content/uploads/2018/06/word-image-46.png" srcset="/wp-content/uploads/2018/06/word-image-46.png 515w, /wp-content/uploads/2018/06/word-image-46-300x48.png 300w" sizes="(max-width: 515px) 100vw, 515px" /></p>
<ul>
<li>兼容模式：http://域名/inde.php?s=/模块/控制器名/方法名/参数名/参数值&#8230;</li>
</ul>
<p><img loading="lazy" decoding="async" width="534" height="83" class="wp-image-7439" src="/wp-content/uploads/2018/06/word-image-47.png" srcset="/wp-content/uploads/2018/06/word-image-47.png 534w, /wp-content/uploads/2018/06/word-image-47-300x47.png 300w" sizes="(max-width: 534px) 100vw, 534px" /></p>
<p>上面的四种模式在tp5默认都是支持的。其在tp5框架中还可以单独定义路由规则来访问某个控制器中的某个方法。</p>
<p>只要配置文件config.php中开启路由功能，访问的时候就会经过路由规则，根据定义的路由规则从而访问到某个控制器中的方法。</p>
<p>路由图解：</p>
<p><img loading="lazy" decoding="async" width="697" height="91" class="wp-image-7440" src="/wp-content/uploads/2018/06/word-image-48.png" srcset="/wp-content/uploads/2018/06/word-image-48.png 697w, /wp-content/uploads/2018/06/word-image-48-300x39.png 300w" sizes="(max-width: 697px) 100vw, 697px" /></p>
<ol>
<li>开启路由，修改application/config.php配置文件</li>
</ol>
<p>&#8216;url_route_on&#8217; =&gt; true, // 开启路由</p>
<p>&#8216;url_route_must&#8217; =&gt; true, // 必须使用路由(即不能使用之前的pathinfo模式访问)</p>
<p>注：若url_route_must设置为true,就不就可以通过上面四种模式来访问，只能通过定义的路由规则访问。</p>
<p>2、定义路由规则，定义在application/route.php文件中</p>
<p>Route::rule(&#8216;路由表达式&#8217;,&#8217;路由地址&#8217;,&#8217;请求类型&#8217;,&#8217;路由参数(数组)&#8217;,&#8217;变量规则(数组)&#8217;);</p>
<p>说明：</p>
<p><strong>路由表达式</strong>：静态地址、动态地址、可选动态地址</p>
<p><strong>路由地址</strong>：表示路由表达式最终需要路由到的地址，有多种定义方式，常用的是”模块/控制器/操作?额外参数1=值1&amp;额外参数2=值2”形式</p>
<p><strong>请求类型</strong>：GET、POST 必须是大写的</p>
<p><strong>路由参数</strong>：</p>
<p>method:请求类型</p>
<p>ext:允许的后缀</p>
<p>deny_ext:禁止的访问后缀</p>
<p>domain:允许什么样的域名访问有效</p>
<p>https:检测是否是https请求</p>
<p>before_behavior:行为发生前，进行路由检查</p>
<p>after_behavior:行为发生后，要执行的动作</p>
<p>&#8230;</p>
<p>详情参考：手册路由&#8211;&gt;路由参数</p>
<p>变量规则：检查传递的变量是否符合某个(正则)规则,规则可以通过正则定义</p>
<p>例如规则：</p>
<p>Route::rule(‘login’,’home/User/login’,’GET’,[‘ext’=&gt;’html’]);</p>
<p>访问：<a href="/goto/dzl6" rel="nofollow">http://servername/index.php/login</a>.html</p>
<p>路由到：<a href="/goto/5h9l" rel="nofollow">http://servername/index.php/home/User/login</a></p>
<p>Route::rule(‘login/:id’,’home/User/login’,’GET’,[‘ext’=&gt;’html’],[‘id’=&gt;’\d+’]);</p>
<p>访问：<a href="/goto/dzl6" rel="nofollow">http://servername/index.php/login</a>/101.html</p>
<p>路由到：<a href="/goto/5h9l" rel="nofollow">http://servername/index.php/home/User/login</a>/id/101</p>
<p>Route::rule(‘login/:id/:name’,’home/User/login’,’GET’,[‘ext’=&gt;’html’],[‘id’=&gt;’\d+’,’name’=&gt;’[a-zA-Z]+’]);</p>
<p>访问：<a href="/goto/dzl6" rel="nofollow">http://servername/index.php/login</a>/101/tom.html</p>
<p>路由到：</p>
<p><a href="/goto/5h9l" rel="nofollow">http://servername/index.php/home/User/login</a>/id/101/name/tom</p>
<p>也可以像下边这样定义:</p>
<p>Route::get(&#8216;路由表达式&#8217;,&#8217;路由地址&#8217;,&#8217;路由参数(数组)&#8217;,&#8217;变量规则(数组)&#8217;);</p>
<p>Route::post(&#8216;路由表达式&#8217;,&#8217;路由地址&#8217;,&#8217;路由参数(数组)&#8217;,&#8217;变量规则(数组)&#8217;);</p>
<p>如一个控制器中的方法在路由规则中没有定义则是不允许被访问，报以下错误：</p>
<p><img loading="lazy" decoding="async" width="701" height="144" class="wp-image-7441" src="/wp-content/uploads/2018/06/word-image-49.png" srcset="/wp-content/uploads/2018/06/word-image-49.png 701w, /wp-content/uploads/2018/06/word-image-49-300x62.png 300w" sizes="(max-width: 701px) 100vw, 701px" /></p>
<p>解决办法，把application/config.php文件中的以下配置改为false,就说明路由规则和pathinfo形式两者都可以进行访问。</p>
<p>&#8216;url_route_must&#8217; =&gt; false, // 是否强制使用路由</p>
<p>在application/route.php中定义路由规则：</p>
<p><img loading="lazy" decoding="async" width="1171" height="392" class="wp-image-7442" src="/wp-content/uploads/2018/06/word-image-50.png" srcset="/wp-content/uploads/2018/06/word-image-50.png 1171w, /wp-content/uploads/2018/06/word-image-50-300x100.png 300w, /wp-content/uploads/2018/06/word-image-50-768x257.png 768w, /wp-content/uploads/2018/06/word-image-50-1024x343.png 1024w" sizes="(max-width: 1171px) 100vw, 1171px" /></p>
<p>访问如下：</p>
<p><img loading="lazy" decoding="async" width="323" height="71" class="wp-image-7443" src="/wp-content/uploads/2018/06/word-image-51.png" srcset="/wp-content/uploads/2018/06/word-image-51.png 323w, /wp-content/uploads/2018/06/word-image-51-300x66.png 300w" sizes="(max-width: 323px) 100vw, 323px" /></p>
<p><img loading="lazy" decoding="async" width="328" height="64" class="wp-image-7444" src="/wp-content/uploads/2018/06/word-image-52.png" srcset="/wp-content/uploads/2018/06/word-image-52.png 328w, /wp-content/uploads/2018/06/word-image-52-300x59.png 300w" sizes="(max-width: 328px) 100vw, 328px" /></p>
<p><img loading="lazy" decoding="async" width="317" height="66" class="wp-image-7445" src="/wp-content/uploads/2018/06/word-image-53.png" srcset="/wp-content/uploads/2018/06/word-image-53.png 317w, /wp-content/uploads/2018/06/word-image-53-300x62.png 300w" sizes="(max-width: 317px) 100vw, 317px" /></p>
<h1>展示视图</h1>
<p>语法：控制器中调用fetch方法</p>
<p>return $this -&gt; fetch(模块@控制器/操作);</p>
<p>注意：</p>
<p>控制器要想正常调用fetch方法，则必须继承Controller类：use think\Controller</p>
<p>fetch()具体有下述5种用法：</p>
<ul>
<li>调用：view下当前控制器名/当前操作名.html模版文件</li>
</ul>
<p>return $this -&gt; fetch();</p>
<ul>
<li>调用：view下当前控制器的/add.html模版文件</li>
</ul>
<p>return $this -&gt; fetch(‘add’);</p>
<ul>
<li>找到view下边user目录的login.html模版文件[跨控制器]</li>
</ul>
<p>return $this -&gt; fetch(&#8216;user/login&#8217;);</p>
<ul>
<li>找到admin分组view目录的manager下边的login.html模版文件[跨分组]</li>
</ul>
<p>return $this -&gt; fetch(&#8216;admin@manager/login&#8217;);</p>
<p>代码如下：</p>
<p><img loading="lazy" decoding="async" width="879" height="322" class="wp-image-7446" src="/wp-content/uploads/2018/06/word-image-54.png" srcset="/wp-content/uploads/2018/06/word-image-54.png 879w, /wp-content/uploads/2018/06/word-image-54-300x110.png 300w, /wp-content/uploads/2018/06/word-image-54-768x281.png 768w" sizes="(max-width: 879px) 100vw, 879px" /></p>
<p>结果：</p>
<p><img loading="lazy" decoding="async" width="428" height="86" class="wp-image-7447" src="/wp-content/uploads/2018/06/word-image-55.png" srcset="/wp-content/uploads/2018/06/word-image-55.png 428w, /wp-content/uploads/2018/06/word-image-55-300x60.png 300w" sizes="(max-width: 428px) 100vw, 428px" /></p>
<h1>九、模板赋值</h1>
<p>语法：在控制器调用assign方法</p>
<ol>
<li>public function index()</li>
<li>{</li>
<li>// 模板变量赋值</li>
<li>$this-&gt;assign(&#8216;name&#8217;,&#8217;ThinkPHP&#8217;);</li>
<li>$this-&gt;assign(&#8217;email&#8217;,&#8217;thinkphp@qq.com&#8217;);</li>
<li>// 或者批量赋值</li>
<li>$this-&gt;assign([</li>
<li>&#8216;name&#8217; =&gt; &#8216;ThinkPHP&#8217;,</li>
<li>&#8217;email&#8217; =&gt; &#8216;thinkphp@qq.com&#8217;</li>
<li>]);</li>
<li>// 模板输出</li>
<li>return $this-&gt;fetch(&#8216;index&#8217;);</li>
<li>}</li>
</ol>
<p>或者把模板变量直接传递给fetch方法：</p>
<ol>
<li>public function index()</li>
<li>{</li>
<li>return $this-&gt;fetch(&#8216;index&#8217;, [</li>
<li>&#8216;name&#8217; =&gt; &#8216;ThinkPHP&#8217;,</li>
<li>&#8217;email&#8217; =&gt; &#8216;thinkphp@qq.com&#8217;</li>
<li>]);</li>
<li>}</li>
</ol>
<p>代码如下：</p>
<p><img loading="lazy" decoding="async" width="611" height="174" class="wp-image-7448" src="/wp-content/uploads/2018/06/word-image-56.png" srcset="/wp-content/uploads/2018/06/word-image-56.png 611w, /wp-content/uploads/2018/06/word-image-56-300x85.png 300w" sizes="(max-width: 611px) 100vw, 611px" /></p>
<p>模板中显示：</p>
<p><img loading="lazy" decoding="async" width="392" height="94" class="wp-image-7449" src="/wp-content/uploads/2018/06/word-image-57.png" srcset="/wp-content/uploads/2018/06/word-image-57.png 392w, /wp-content/uploads/2018/06/word-image-57-300x72.png 300w" sizes="(max-width: 392px) 100vw, 392px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="414" height="132" class="wp-image-7450" src="/wp-content/uploads/2018/06/word-image-58.png" srcset="/wp-content/uploads/2018/06/word-image-58.png 414w, /wp-content/uploads/2018/06/word-image-58-300x96.png 300w" sizes="(max-width: 414px) 100vw, 414px" /></p>
<p>建议使用如下方式，分配模板变量：<br />
<img loading="lazy" decoding="async" width="735" height="212" class="wp-image-7451" src="/wp-content/uploads/2018/06/word-image-59.png" srcset="/wp-content/uploads/2018/06/word-image-59.png 735w, /wp-content/uploads/2018/06/word-image-59-300x87.png 300w" sizes="(max-width: 735px) 100vw, 735px" /></p>
<p>模板中显示：</p>
<p><img loading="lazy" decoding="async" width="630" height="265" class="wp-image-7452" src="/wp-content/uploads/2018/06/word-image-60.png" srcset="/wp-content/uploads/2018/06/word-image-60.png 630w, /wp-content/uploads/2018/06/word-image-60-300x126.png 300w" sizes="(max-width: 630px) 100vw, 630px" /></p>
<h1>十、模板常用标签</h1>
<h2>volist标签</h2>
<p>作用：主要用来遍历数组</p>
<p>语法：</p>
<p><img loading="lazy" decoding="async" width="966" height="275" class="wp-image-7453" src="/wp-content/uploads/2018/06/word-image-61.png" srcset="/wp-content/uploads/2018/06/word-image-61.png 966w, /wp-content/uploads/2018/06/word-image-61-300x85.png 300w, /wp-content/uploads/2018/06/word-image-61-768x219.png 768w" sizes="(max-width: 966px) 100vw, 966px" /></p>
<p>Volist标签的name属性表示模板赋值的变量名称，因此不可随意在模板文件中改变。id表示当前的循环变量，可以随意指定，但确保不要和name属性值冲突。</p>
<p>代码如下：</p>
<p>控制器对模板赋值：</p>
<p><img loading="lazy" decoding="async" width="706" height="394" class="wp-image-7454" src="/wp-content/uploads/2018/06/word-image-62.png" srcset="/wp-content/uploads/2018/06/word-image-62.png 706w, /wp-content/uploads/2018/06/word-image-62-300x167.png 300w" sizes="(max-width: 706px) 100vw, 706px" /></p>
<p>模板遍历：</p>
<p><img loading="lazy" decoding="async" width="802" height="375" class="wp-image-7455" src="/wp-content/uploads/2018/06/word-image-63.png" srcset="/wp-content/uploads/2018/06/word-image-63.png 802w, /wp-content/uploads/2018/06/word-image-63-300x140.png 300w, /wp-content/uploads/2018/06/word-image-63-768x359.png 768w" sizes="(max-width: 802px) 100vw, 802px" /></p>
<p>效果：<br />
<img loading="lazy" decoding="async" width="448" height="272" class="wp-image-7456" src="/wp-content/uploads/2018/06/word-image-64.png" srcset="/wp-content/uploads/2018/06/word-image-64.png 448w, /wp-content/uploads/2018/06/word-image-64-300x182.png 300w" sizes="(max-width: 448px) 100vw, 448px" /></p>
<p>循环数组序号（标号）：</p>
<p><img loading="lazy" decoding="async" width="809" height="253" class="wp-image-7457" src="/wp-content/uploads/2018/06/word-image-65.png" srcset="/wp-content/uploads/2018/06/word-image-65.png 809w, /wp-content/uploads/2018/06/word-image-65-300x94.png 300w, /wp-content/uploads/2018/06/word-image-65-768x240.png 768w" sizes="(max-width: 809px) 100vw, 809px" /></p>
<p>注：如果不知道key属性，默认{$key}从0开始，所以需要加1{$key+1}</p>
<h2>比较标签</h2>
<p>参考手册：</p>
<p><img loading="lazy" decoding="async" width="788" height="449" class="wp-image-7458" src="/wp-content/uploads/2018/06/word-image-66.png" srcset="/wp-content/uploads/2018/06/word-image-66.png 788w, /wp-content/uploads/2018/06/word-image-66-300x171.png 300w, /wp-content/uploads/2018/06/word-image-66-768x438.png 768w" sizes="(max-width: 788px) 100vw, 788px" /></p>
<p>使用范例：</p>
<p><img loading="lazy" decoding="async" width="387" height="123" class="wp-image-7459" src="/wp-content/uploads/2018/06/word-image-67.png" srcset="/wp-content/uploads/2018/06/word-image-67.png 387w, /wp-content/uploads/2018/06/word-image-67-300x95.png 300w" sizes="(max-width: 387px) 100vw, 387px" /></p>
<p>代码如下：</p>
<p>模板赋值遍历：</p>
<p><img loading="lazy" decoding="async" width="600" height="50" class="wp-image-7460" src="/wp-content/uploads/2018/06/word-image-68.png" srcset="/wp-content/uploads/2018/06/word-image-68.png 600w, /wp-content/uploads/2018/06/word-image-68-300x25.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></p>
<p>模板判断：</p>
<p><img loading="lazy" decoding="async" width="326" height="146" class="wp-image-7461" src="/wp-content/uploads/2018/06/word-image-69.png" srcset="/wp-content/uploads/2018/06/word-image-69.png 326w, /wp-content/uploads/2018/06/word-image-69-300x134.png 300w" sizes="(max-width: 326px) 100vw, 326px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="165" height="83" class="wp-image-7462" src="/wp-content/uploads/2018/06/word-image-70.png" /></p>
<h2>php标签</h2>
<p>如果模板标签太多记不住，这里可以使用php标签统一进行一些代码的编写：</p>
<p><img loading="lazy" decoding="async" width="716" height="258" class="wp-image-7463" src="/wp-content/uploads/2018/06/word-image-71.png" srcset="/wp-content/uploads/2018/06/word-image-71.png 716w, /wp-content/uploads/2018/06/word-image-71-300x108.png 300w" sizes="(max-width: 716px) 100vw, 716px" /></p>
<p>例1：代码如下：</p>
<p><img loading="lazy" decoding="async" width="885" height="546" class="wp-image-7464" src="/wp-content/uploads/2018/06/word-image-72.png" srcset="/wp-content/uploads/2018/06/word-image-72.png 885w, /wp-content/uploads/2018/06/word-image-72-300x185.png 300w, /wp-content/uploads/2018/06/word-image-72-768x474.png 768w" sizes="(max-width: 885px) 100vw, 885px" /></p>
<p>例2：代码如下：</p>
<p>控制器赋值：</p>
<p><img loading="lazy" decoding="async" width="512" height="63" class="wp-image-7465" src="/wp-content/uploads/2018/06/word-image-73.png" srcset="/wp-content/uploads/2018/06/word-image-73.png 512w, /wp-content/uploads/2018/06/word-image-73-300x37.png 300w" sizes="(max-width: 512px) 100vw, 512px" /></p>
<p>模板获取：</p>
<p><img loading="lazy" decoding="async" width="549" height="191" class="wp-image-7466" src="/wp-content/uploads/2018/06/word-image-74.png" srcset="/wp-content/uploads/2018/06/word-image-74.png 549w, /wp-content/uploads/2018/06/word-image-74-300x104.png 300w" sizes="(max-width: 549px) 100vw, 549px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="100" height="77" class="wp-image-7467" src="/wp-content/uploads/2018/06/word-image-75.png" /></p>
<h2>include包含标签</h2>
<p><strong>作用</strong>：</p>
<p>一般网站页面的头部或尾部的网页效果都是一样的，我们就可以把这些网页的代码抽离出来放在一个html文件中，需要使用这些文件的时候，在模板中用include标签引入即可，从而提高代码的复用性。</p>
<p><strong>include语法：</strong></p>
<p><img loading="lazy" decoding="async" width="482" height="57" class="wp-image-7468" src="/wp-content/uploads/2018/06/word-image-76.png" srcset="/wp-content/uploads/2018/06/word-image-76.png 482w, /wp-content/uploads/2018/06/word-image-76-300x35.png 300w" sizes="(max-width: 482px) 100vw, 482px" /></p>
<p>注意：file的路径是从当前模块的view目录下开始找起。</p>
<p>如：有一个header.html模板，其所在路径为：Admin/view/public/header.html</p>
<p>在模板中引入此文件： &lt;include file=”public/header” /&gt;</p>
<p><strong>代码如下：</strong></p>
<p>控制器输出模板：</p>
<p><img loading="lazy" decoding="async" width="567" height="202" class="wp-image-7469" src="/wp-content/uploads/2018/06/word-image-77.png" srcset="/wp-content/uploads/2018/06/word-image-77.png 567w, /wp-content/uploads/2018/06/word-image-77-300x107.png 300w" sizes="(max-width: 567px) 100vw, 567px" /></p>
<p>在模板中引入公共的文件：</p>
<p><img loading="lazy" decoding="async" width="1019" height="353" class="wp-image-7470" src="/wp-content/uploads/2018/06/word-image-78.png" srcset="/wp-content/uploads/2018/06/word-image-78.png 1019w, /wp-content/uploads/2018/06/word-image-78-300x104.png 300w, /wp-content/uploads/2018/06/word-image-78-768x266.png 768w" sizes="(max-width: 1019px) 100vw, 1019px" /></p>
<p>注：文件名后缀不要加html</p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="136" height="66" class="wp-image-7471" src="/wp-content/uploads/2018/06/word-image-79.png" /></p>
<h1>十一、搭建后台首页</h1>
<p>第一步：在后台Admin建立一个Index的控制器，输出模板内容</p>
<p><img loading="lazy" decoding="async" width="885" height="275" class="wp-image-7472" src="/wp-content/uploads/2018/06/word-image-80.png" srcset="/wp-content/uploads/2018/06/word-image-80.png 885w, /wp-content/uploads/2018/06/word-image-80-300x93.png 300w, /wp-content/uploads/2018/06/word-image-80-768x239.png 768w" sizes="(max-width: 885px) 100vw, 885px" /></p>
<p>第二步：把我们的后台模板index.html复制到/admin/view/index/目录下面</p>
<p><img loading="lazy" decoding="async" width="1028" height="383" class="wp-image-7473" src="/wp-content/uploads/2018/06/word-image-81.png" srcset="/wp-content/uploads/2018/06/word-image-81.png 1028w, /wp-content/uploads/2018/06/word-image-81-300x112.png 300w, /wp-content/uploads/2018/06/word-image-81-768x286.png 768w, /wp-content/uploads/2018/06/word-image-81-1024x382.png 1024w" sizes="(max-width: 1028px) 100vw, 1028px" /></p>
<p>第三步：把后台模板的left.html 、 top.html 、main.html复复制到/admin/view/index/目录下面.</p>
<p><img loading="lazy" decoding="async" width="744" height="472" class="wp-image-7474" src="/wp-content/uploads/2018/06/word-image-82.png" srcset="/wp-content/uploads/2018/06/word-image-82.png 744w, /wp-content/uploads/2018/06/word-image-82-300x190.png 300w" sizes="(max-width: 744px) 100vw, 744px" /></p>
<p>第四步：在建立left、top、main三个方法</p>
<p><img loading="lazy" decoding="async" width="835" height="533" class="wp-image-7475" src="/wp-content/uploads/2018/06/word-image-83.png" srcset="/wp-content/uploads/2018/06/word-image-83.png 835w, /wp-content/uploads/2018/06/word-image-83-300x191.png 300w, /wp-content/uploads/2018/06/word-image-83-768x490.png 768w" sizes="(max-width: 835px) 100vw, 835px" /></p>
<p>第五步：设置index.html模板的iframe的src路径：</p>
<p><img loading="lazy" decoding="async" width="1238" height="324" class="wp-image-7476" src="/wp-content/uploads/2018/06/word-image-84.png" srcset="/wp-content/uploads/2018/06/word-image-84.png 1238w, /wp-content/uploads/2018/06/word-image-84-300x79.png 300w, /wp-content/uploads/2018/06/word-image-84-768x201.png 768w, /wp-content/uploads/2018/06/word-image-84-1024x268.png 1024w" sizes="(max-width: 1238px) 100vw, 1238px" /></p>
<p>注：助手函数：url(‘模块/控制器/方法’) 生成url地址，在模板中使用函数需要在一对花括号{}前面加个冒号：</p>
<p>第六步：把后台资源（img、css、js）,复制到网站根目录public/admin/目录下面</p>
<p><img loading="lazy" decoding="async" width="1062" height="209" class="wp-image-7477" src="/wp-content/uploads/2018/06/word-image-85.png" srcset="/wp-content/uploads/2018/06/word-image-85.png 1062w, /wp-content/uploads/2018/06/word-image-85-300x59.png 300w, /wp-content/uploads/2018/06/word-image-85-768x151.png 768w, /wp-content/uploads/2018/06/word-image-85-1024x202.png 1024w" sizes="(max-width: 1062px) 100vw, 1062px" /></p>
<p>同时config.php配置文件中，定义一个后台资源目录的路径，在模板中进行统一替换：</p>
<p><img loading="lazy" decoding="async" width="860" height="300" class="wp-image-7478" src="/wp-content/uploads/2018/06/word-image-86.png" srcset="/wp-content/uploads/2018/06/word-image-86.png 860w, /wp-content/uploads/2018/06/word-image-86-300x105.png 300w, /wp-content/uploads/2018/06/word-image-86-768x268.png 768w" sizes="(max-width: 860px) 100vw, 860px" /></p>
<p>第七步：模板中替换使用config函数获取配置进行替换：</p>
<p><img loading="lazy" decoding="async" width="1358" height="710" class="wp-image-7479" src="/wp-content/uploads/2018/06/word-image-87.png" srcset="/wp-content/uploads/2018/06/word-image-87.png 1358w, /wp-content/uploads/2018/06/word-image-87-300x157.png 300w, /wp-content/uploads/2018/06/word-image-87-768x402.png 768w, /wp-content/uploads/2018/06/word-image-87-1024x535.png 1024w" sizes="(max-width: 1358px) 100vw, 1358px" /></p>
<p>和上面操作一样分别替换top.html、left.html、main.html的静态资源目录。</p>
<p>最终效果：</p>
<p><img loading="lazy" decoding="async" width="761" height="479" class="wp-image-7480" src="/wp-content/uploads/2018/06/word-image-88.png" srcset="/wp-content/uploads/2018/06/word-image-88.png 761w, /wp-content/uploads/2018/06/word-image-88-300x189.png 300w" sizes="(max-width: 761px) 100vw, 761px" /></p>
<p>注：助手函数config(‘配置名’)，是获取配置文件中的值。模板中使用需要在{}前面加个冒号：。</p>
<p>助手函数手册位置：附录&#8211;》助手函数</p>
<h1>十二、搭建登录页</h1>
<p>第一步：在后台admin建立一个Public控制器，并建立一个login的方法，输出模板内容</p>
<p><img loading="lazy" decoding="async" width="815" height="262" class="wp-image-7482" src="/wp-content/uploads/2018/06/word-image-89.png" srcset="/wp-content/uploads/2018/06/word-image-89.png 815w, /wp-content/uploads/2018/06/word-image-89-300x96.png 300w, /wp-content/uploads/2018/06/word-image-89-768x247.png 768w" sizes="(max-width: 815px) 100vw, 815px" /></p>
<p>第二步：把后台模板login.html赋值到/admin/view/public/目录下面，并替换静态资源文件路径</p>
<p><img loading="lazy" decoding="async" width="1221" height="368" class="wp-image-7483" src="/wp-content/uploads/2018/06/word-image-90.png" srcset="/wp-content/uploads/2018/06/word-image-90.png 1221w, /wp-content/uploads/2018/06/word-image-90-300x90.png 300w, /wp-content/uploads/2018/06/word-image-90-768x231.png 768w, /wp-content/uploads/2018/06/word-image-90-1024x309.png 1024w" sizes="(max-width: 1221px) 100vw, 1221px" /></p>
<p>效果：<br />
<img loading="lazy" decoding="async" width="775" height="341" class="wp-image-7484" src="/wp-content/uploads/2018/06/word-image-91.png" srcset="/wp-content/uploads/2018/06/word-image-91.png 775w, /wp-content/uploads/2018/06/word-image-91-300x132.png 300w, /wp-content/uploads/2018/06/word-image-91-768x338.png 768w" sizes="(max-width: 775px) 100vw, 775px" /></p>
<p>sublime快捷键：</p>
<p>替换：ctrl+h</p>
<p>找文件：ctrl+p</p>
<h1>十三、控制器中的页面跳转和重定向</h1>
<h2>1、跳转</h2>
<p>在应用开发中，经常会遇到一些带有提示信息的跳转页面，例如操作成功或者操作错误页面，并且自动跳转到另外一个目标页面。系统的\think\Controller类内置了两个跳转方法success和error，用于页面跳转提示</p>
<p>成功跳转：$this-&gt;success($msg,$url,$data,$time)</p>
<p>失败跳转：$this-&gt;error($msg,$url,$data,$time))</p>
<p>参数说明：</p>
<ul>
<li>msg:跳转的提示信息</li>
<li>url:跳转的地址。 建议用助手函数url()生成地址。，失败默认跳回上一页。一般不需要指定</li>
<li>data: 返回的数据，没有则留空</li>
<li>time:默认成功和失败都是3秒，</li>
</ul>
<p>代码如下：</p>
<p><img loading="lazy" decoding="async" width="786" height="379" class="wp-image-7485" src="/wp-content/uploads/2018/06/word-image-92.png" srcset="/wp-content/uploads/2018/06/word-image-92.png 786w, /wp-content/uploads/2018/06/word-image-92-300x145.png 300w, /wp-content/uploads/2018/06/word-image-92-768x370.png 768w" sizes="(max-width: 786px) 100vw, 786px" /></p>
<p>success和error方法源码位置： <img loading="lazy" decoding="async" width="392" height="26" class="wp-image-7486" src="/wp-content/uploads/2018/06/word-image-93.png" srcset="/wp-content/uploads/2018/06/word-image-93.png 392w, /wp-content/uploads/2018/06/word-image-93-300x20.png 300w" sizes="(max-width: 392px) 100vw, 392px" /></p>
<h2>重定向</h2>
<p>语法:</p>
<p>$this-&gt; redirect(url,[$params])</p>
<p>参数说明：</p>
<p>第一个参数必填，后面两个个参数可缺省。</p>
<ul>
<li>$url：跳转的地址, 形式为 “模块/控制器/方法&#8221; 。</li>
</ul>
<p>若直接写方法名如：$this-&gt; redirect(‘index’)，默认会重定向到当前模块的当前控制器的index方法。</p>
<p>若直接写控制器名和方法名如：$this-&gt; redirect(‘index/index’)，默认会重定向到当前模块的index控制器的index方法。</p>
<ul>
<li>$params：跳转携带的参数，数组形式如：传id等于3，array(“id”=&gt;3)</li>
</ul>
<p>$this -&gt; redirect(分组/控制器/操作方法)</p>
<p>跳转到的地址：http://网址/分组/控制器/操作方法</p>
<p>$this -&gt; redirect(分组/控制器/操作方法,[参数1=&gt;值1,参数2=&gt;值2])</p>
<p>跳转到的地址：<a href="/goto/8icy" rel="nofollow">http://网址/分组/控制器/操作方法/参数1/值1/参数2/值</a>2</p>
<p>代码如下：</p>
<p><img loading="lazy" decoding="async" width="800" height="196" class="wp-image-7487" src="/wp-content/uploads/2018/06/word-image-94.png" srcset="/wp-content/uploads/2018/06/word-image-94.png 800w, /wp-content/uploads/2018/06/word-image-94-300x74.png 300w, /wp-content/uploads/2018/06/word-image-94-768x188.png 768w" sizes="(max-width: 800px) 100vw, 800px" /></p>
<p>问：什么时候使用跳转和重定向？</p>
<p>答：</p>
<p>1、需要给用户操作的提示信息，则用跳转。</p>
<p>一般是删除或编辑失败的时候，这需要给用户提示错误信息，操作失败则用跳转error，成功用success。</p>
<p>2、不需要给任何提示信息，则用重定向。</p>
<p>如用户登录成功不需要给提示信息则直接redirect重定向到首页，登录失败就用error给用户提示错误信息。</p>
<h1>请求Request</h1>
<p>手册参考位置：请求&#8211;&gt;请求信息</p>
<h2>获取Request对象</h2>
<p>图解Request对象、response对象：</p>
<p><img loading="lazy" decoding="async" width="744" height="109" class="wp-image-7488" src="/wp-content/uploads/2018/06/word-image-95.png" srcset="/wp-content/uploads/2018/06/word-image-95.png 744w, /wp-content/uploads/2018/06/word-image-95-300x44.png 300w" sizes="(max-width: 744px) 100vw, 744px" /></p>
<p>图解说明：</p>
<ul>
<li>服务端server把客户端请求过来的相关信息都封装在一个Request对象中。如请求地址、请求参数、请求类型、上传的文件信息等。</li>
<li>服务端server把响应给浏览器的相关信息都封装在一个Response对象。如响应http状态码200给客户端等。</li>
</ul>
<p>获取Request对象的方式：</p>
<p>方式一：</p>
<p>引用\think\Request类 ，$request = Request::instance();</p>
<p><img loading="lazy" decoding="async" width="673" height="350" class="wp-image-7489" src="/wp-content/uploads/2018/06/word-image-96.png" srcset="/wp-content/uploads/2018/06/word-image-96.png 673w, /wp-content/uploads/2018/06/word-image-96-300x156.png 300w" sizes="(max-width: 673px) 100vw, 673px" /></p>
<p>助手调试函数dump()；内部封装pre格式化标签。</p>
<p>方式二（最简单的方式）：</p>
<p>通过tp5框架提供的助手函数request()</p>
<p>$request = request();</p>
<p><img loading="lazy" decoding="async" width="698" height="240" class="wp-image-7490" src="/wp-content/uploads/2018/06/word-image-97.png" srcset="/wp-content/uploads/2018/06/word-image-97.png 698w, /wp-content/uploads/2018/06/word-image-97-300x103.png 300w" sizes="(max-width: 698px) 100vw, 698px" /></p>
<p>方式三：</p>
<p>通过依赖注入（闭包）的方式，把Request对象注入到方法内部</p>
<p>public function 方法名(Request $request){}</p>
<p><img loading="lazy" decoding="async" width="640" height="349" class="wp-image-7491" src="/wp-content/uploads/2018/06/word-image-98.png" srcset="/wp-content/uploads/2018/06/word-image-98.png 640w, /wp-content/uploads/2018/06/word-image-98-300x164.png 300w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<p>相当于把Request类的对象$request作为p4的参数。</p>
<h2>2、获取请求信息</h2>
<p>手册参考位置：请求&#8211;&gt;请求信息</p>
<p>$request-&gt;domain(); // 获取当前域名</p>
<p>$request-&gt;baseFile(); // 获取当前入口文件,不含域名</p>
<p>$request-&gt;url(); // 获取当前URL地址</p>
<p>$request-&gt;url(true); // 包含域名的完整URL地址</p>
<p>$request-&gt;baseUrl(); // 获取当前URL地址 不含QUERY_STRING</p>
<p>$request-&gt;pathinfo(); // 获取URL地址中的PATH_INFO信息</p>
<p>$request-&gt;path(); // 获取URL地址中的PATH_INFO信息 不含后缀</p>
<p>$request-&gt;ext(); // 获取URL地址中的后缀信息</p>
<p>$request-&gt;header(); // 获取当前请求的HTTP 请求头信息</p>
<p>$request-&gt;module(); // 获取当前模块名称</p>
<p>$request-&gt;controller(); // 获取当前控制器名称</p>
<p>$request-&gt;action(); // 获取当前操作名称</p>
<p>$request-&gt;method(); // 获取请求方法</p>
<p>$request-&gt;type(); // 获取资源类型</p>
<p>$request-&gt;ip(); // 获取访问ip地址</p>
<p>$request-&gt;isAjax(); // 判断 是否是ajax请求</p>
<p>$request-&gt;isPost(); // 判断 是否是post请求</p>
<p>$request-&gt;isGet(); // 判断 是否是get请求</p>
<p>代码如下：</p>
<p><img loading="lazy" decoding="async" width="967" height="334" class="wp-image-7492" src="/wp-content/uploads/2018/06/word-image-99.png" srcset="/wp-content/uploads/2018/06/word-image-99.png 967w, /wp-content/uploads/2018/06/word-image-99-300x104.png 300w, /wp-content/uploads/2018/06/word-image-99-768x265.png 768w" sizes="(max-width: 967px) 100vw, 967px" /></p>
<h2>3、获取请求参数</h2>
<p>手册参考位置：请求&#8211;&gt;输入变量</p>
<p>语法：变量类型方法(&#8216;变量名/变量修饰符&#8217;,&#8217;默认值&#8217;,&#8217;过滤方法&#8217;)</p>
<table>
<thead>
<tr>
<th><strong>方法</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>param</td>
<td>获取当前请求的变量信息</td>
</tr>
<tr>
<td>get</td>
<td>获取 $_GET 变量</td>
</tr>
<tr>
<td>post</td>
<td>获取 $_POST 变量</td>
</tr>
<tr>
<td>session</td>
<td>获取 $_SESSION 变量</td>
</tr>
<tr>
<td>cookie</td>
<td>获取 $_COOKIE 变量</td>
</tr>
<tr>
<td>request</td>
<td>获取 $_REQUEST 变量</td>
</tr>
<tr>
<td>server</td>
<td>获取 $_SERVER 变量</td>
</tr>
<tr>
<td>env</td>
<td>获取 $_ENV 变量</td>
</tr>
<tr>
<td>route</td>
<td>获取 路由（包括PATHINFO） 变量</td>
</tr>
<tr>
<td>file</td>
<td>获取 $_FILES 变量</td>
</tr>
</tbody>
</table>
<h3>（1）获取PARAM变量</h3>
<p>PARAM变量是框架提供的用于自动识别GET、POST或者的一种变量获取方式，是系统推荐的获取请求参数的方法，用法如下：</p>
<p>// 获取当前请求的name变量</p>
<p>$request-&gt;param(&#8216;name&#8217;);</p>
<p>// 获取当前请求的所有变量（经过过滤）</p>
<p>$request-&gt;param();</p>
<p>// 获取当前请求的所有变量（原始数据）</p>
<p>$request-&gt;param(false);</p>
<p>// 获取当前请求的所有变量（包含上传文件）</p>
<p>$request-&gt;param(true);</p>
<p>注：param方法会把当前请求类型的参数和PATH_INFO变量以及GET请求合并。</p>
<p>或使用助手函数实现：</p>
<p>input(&#8216;param.name&#8217;);</p>
<p>input(&#8216;param.&#8217;);</p>
<p>或者</p>
<p>input(&#8216;name&#8217;);</p>
<p>input(&#8221;);</p>
<p>因为input函数默认底默认就采用PARAM方式进行读取变量。</p>
<h3>（2）获取GET变量</h3>
<p>使用内置的助手函数input获取get参数</p>
<p>input(&#8216;id&#8217;);</p>
<p>input(&#8216;name&#8217;);</p>
<p>input(&#8216;get.&#8217;); //获取整个get数组参数</p>
<p>代码如下：</p>
<ol>
<li>把表单设置get方式提交，不写action默认跳转到当前地址</li>
</ol>
<p><img loading="lazy" decoding="async" width="844" height="299" class="wp-image-7493" src="/wp-content/uploads/2018/06/word-image-100.png" srcset="/wp-content/uploads/2018/06/word-image-100.png 844w, /wp-content/uploads/2018/06/word-image-100-300x106.png 300w, /wp-content/uploads/2018/06/word-image-100-768x272.png 768w" sizes="(max-width: 844px) 100vw, 844px" /></p>
<p>假设输入的数据如下：</p>
<p><img loading="lazy" decoding="async" width="492" height="230" class="wp-image-7494" src="/wp-content/uploads/2018/06/word-image-101.png" srcset="/wp-content/uploads/2018/06/word-image-101.png 492w, /wp-content/uploads/2018/06/word-image-101-300x140.png 300w" sizes="(max-width: 492px) 100vw, 492px" /></p>
<p>b、在当前方法p3中接收整个get参数和单个get参数，结果</p>
<p><img loading="lazy" decoding="async" width="1047" height="260" class="wp-image-7495" src="/wp-content/uploads/2018/06/word-image-102.png" srcset="/wp-content/uploads/2018/06/word-image-102.png 1047w, /wp-content/uploads/2018/06/word-image-102-300x74.png 300w, /wp-content/uploads/2018/06/word-image-102-768x191.png 768w, /wp-content/uploads/2018/06/word-image-102-1024x254.png 1024w" sizes="(max-width: 1047px) 100vw, 1047px" /></p>
<h3>（3）获取POST变量</h3>
<p>使用助手函数实现：</p>
<p>input(&#8216;name&#8217;);</p>
<p>input(&#8216;post.&#8217;); //获取整个post数组参数</p>
<p>代码如下：</p>
<p>a、把表单设置post方式提交，不写action默认跳转到当前地址</p>
<p><img loading="lazy" decoding="async" width="756" height="285" class="wp-image-7496" src="/wp-content/uploads/2018/06/word-image-103.png" srcset="/wp-content/uploads/2018/06/word-image-103.png 756w, /wp-content/uploads/2018/06/word-image-103-300x113.png 300w" sizes="(max-width: 756px) 100vw, 756px" /></p>
<p>假设输入的数据如下：</p>
<p><img loading="lazy" decoding="async" width="426" height="126" class="wp-image-7497" src="/wp-content/uploads/2018/06/word-image-104.png" srcset="/wp-content/uploads/2018/06/word-image-104.png 426w, /wp-content/uploads/2018/06/word-image-104-300x89.png 300w" sizes="(max-width: 426px) 100vw, 426px" /></p>
<p>b、在当前方法p3中判断是否是post请求，获取整个post参数和单个post参数</p>
<p><img loading="lazy" decoding="async" width="939" height="355" class="wp-image-7498" src="/wp-content/uploads/2018/06/word-image-105.png" srcset="/wp-content/uploads/2018/06/word-image-105.png 939w, /wp-content/uploads/2018/06/word-image-105-300x113.png 300w, /wp-content/uploads/2018/06/word-image-105-768x290.png 768w" sizes="(max-width: 939px) 100vw, 939px" /></p>
]]></content:encoded>
					
					<wfw:commentRss>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7391.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TP5.0（二）数据库操作、模型 CURD 操作、常用函数、时间戳自动维护、DB 构造器操作数据库、后台登录、后台退出、登录防翻墙、登录验证</title>
		<link>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7499.html</link>
					<comments>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7499.html#respond</comments>
		
		<dc:creator><![CDATA[Mr.Lee]]></dc:creator>
		<pubDate>Sat, 09 Jun 2018 00:43:29 +0000</pubDate>
				<category><![CDATA[TP5.0]]></category>
		<category><![CDATA[后台框架]]></category>
		<category><![CDATA[DB 构造器操作数据库]]></category>
		<category><![CDATA[后台登录]]></category>
		<category><![CDATA[后台退出]]></category>
		<category><![CDATA[常用函数]]></category>
		<category><![CDATA[数据库操作]]></category>
		<category><![CDATA[时间戳自动维护]]></category>
		<category><![CDATA[模型 CURD 操作]]></category>
		<category><![CDATA[登录防翻墙]]></category>
		<category><![CDATA[登录验证]]></category>
		<guid isPermaLink="false">/?p=7499</guid>

					<description><![CDATA[TP5第二天 十五、数据库操作 在TP5操作数据库常用有两种方式： 通过Db构造器 如：Db::table(&#038; [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>TP5第二天</h1>
<h1>十五、数据库操作</h1>
<p>在TP5操作数据库常用有两种方式：</p>
<ul>
<li>通过Db构造器</li>
</ul>
<p>如：Db::table(&#8216;think_user&#8217;)-&gt;where(&#8216;status&#8217;,1)-&gt;select(); // #带数据表前缀</p>
<p>如：Db::name(&#8216;user&#8217;)-&gt;where(&#8216;status&#8217;,1)-&gt;select(); #不带表前缀</p>
<ul>
<li>通过模型类</li>
</ul>
<p>如：取出主键为1的数据</p>
<p>$user = User::get(1);</p>
<p>首先配置数据库的连接信息</p>
<h2>创建数据库数据表，配置数据库信息</h2>
<p>在application/database.php文件中添加下面的配置参数：</p>
<p><img loading="lazy" decoding="async" width="871" height="556" class="wp-image-7500" src="/wp-content/uploads/2018/06/word-image-106.png" srcset="/wp-content/uploads/2018/06/word-image-106.png 871w, /wp-content/uploads/2018/06/word-image-106-300x192.png 300w, /wp-content/uploads/2018/06/word-image-106-768x490.png 768w" sizes="(max-width: 871px) 100vw, 871px" /></p>
<p>同时创建好数据库和数据表：</p>
<ol>
<li>创建数据库article:</li>
</ol>
<p>create database article;</p>
<p>2、创建数据表tp_user(用户表)、tp_category（分类表）、tp_article（文章表）</p>
<p>tp_user表结构：</p>
<p>create table tp_user(</p>
<p>user_id int not null auto_increment,</p>
<p>username varchar(30) not null default &#8221; comment &#8216;用户名&#8217;,</p>
<p>password char(32) not null default &#8221; comment &#8216;密码&#8217;,</p>
<p>primary key(user_id)</p>
<p>)engine = Innodb default charset = utf8;</p>
<p>tp_category表结构：</p>
<p>create table tp_category(</p>
<p>cat_id smallint not null auto_increment,</p>
<p>cat_name varchar(30) not null default &#8221; comment &#8216;分类名称&#8217;,</p>
<p>pid smallint not null default 0 comment &#8216;父分类的id&#8217;,</p>
<p>create_time int not null default 0 comment &#8216;创建时间&#8217;,</p>
<p>update_time int not null default 0 comment &#8216;更新时间&#8217;,</p>
<p>primary key(cat_id)</p>
<p>)engine = Innodb default charset = utf8;</p>
<p>tp_article表结构：</p>
<p>create table tp_article(</p>
<p>article_id smallint not null auto_increment,</p>
<p>title varchar(30) not null default &#8221; comment &#8216;文章标题&#8217;,</p>
<p>content text comment &#8216;文章内容&#8217;,</p>
<p>cat_id smallint not null default 0 comment &#8216;文章所属分类&#8217;,</p>
<p>ori_img varchar(150) not null default &#8221; comment &#8216;原图的路径&#8217;,</p>
<p>thumb_img varchar(150) not null default &#8221; comment &#8216;缩略图的路径&#8217;,</p>
<p>create_time int not null default 0 comment &#8216;创建时间&#8217;,</p>
<p>update_time int not null default 0 comment &#8216;更新时间&#8217;,</p>
<p>primary key(article_id)</p>
<p>)engine = Innodb default charset = utf8;</p>
<p>注：表名加前缀tp_,用于区分多个项目。</p>
<ol>
<li>测试数据库是否连接成功，可以向表添加几条数据，进行查询</li>
</ol>
<p><img loading="lazy" decoding="async" width="444" height="79" class="wp-image-7501" src="/wp-content/uploads/2018/06/word-image-107.png" srcset="/wp-content/uploads/2018/06/word-image-107.png 444w, /wp-content/uploads/2018/06/word-image-107-300x53.png 300w" sizes="(max-width: 444px) 100vw, 444px" /></p>
<p><img loading="lazy" decoding="async" width="772" height="250" class="wp-image-7502" src="/wp-content/uploads/2018/06/word-image-108.png" srcset="/wp-content/uploads/2018/06/word-image-108.png 772w, /wp-content/uploads/2018/06/word-image-108-300x97.png 300w, /wp-content/uploads/2018/06/word-image-108-768x249.png 768w" sizes="(max-width: 772px) 100vw, 772px" /></p>
<p>结果：</p>
<p><img loading="lazy" decoding="async" width="266" height="239" class="wp-image-7503" src="/wp-content/uploads/2018/06/word-image-109.png" /></p>
<p>说明连接成功。</p>
<h2>模型</h2>
<h3>模型认识</h3>
<p>M:Model模型</p>
<p>作用：主要对数据库进行一些增删改查的操作。</p>
<h3>模型的定义</h3>
<p>一般而言，一个表对应一个模型，如果只是对表进行最基本的增删改查，不建模型也是可以操作表数据的，但是如果数据逻辑比较复杂，我们可以把这些数据逻辑定义在模型中，为了和业务逻辑分开，代码结构也比较清晰，也方便后期维护。</p>
<p>个人建议最好的做法就是以下两点：</p>
<p>①业务逻辑写在控制器中</p>
<p>②数据逻辑写在模型中</p>
<p>如有一个文章分类表，名为tp_category，此表对应的模型类名和模型文件定义如下：</p>
<p>模型类名： Category 注：驼峰法，除开表前缀的数据表名称。</p>
<p>模型类文件：Category.php 表名+.php</p>
<p>模型类文件所在位置：模块名/model/Category.php</p>
<p>给表tp_category建立模型文件如下：</p>
<p><img loading="lazy" decoding="async" width="692" height="218" class="wp-image-7504" src="/wp-content/uploads/2018/06/word-image-110.png" srcset="/wp-content/uploads/2018/06/word-image-110.png 692w, /wp-content/uploads/2018/06/word-image-110-300x95.png 300w" sizes="(max-width: 692px) 100vw, 692px" /></p>
<p>其中模型中定义的属性pk为表的主键名称，若不指定则框架会自动识别。</p>
<p>有关表名的注意事项：</p>
<p>手册位置： 模型-&gt;定义</p>
<p><img loading="lazy" decoding="async" width="914" height="461" class="wp-image-7505" src="/wp-content/uploads/2018/06/word-image-111.png" srcset="/wp-content/uploads/2018/06/word-image-111.png 914w, /wp-content/uploads/2018/06/word-image-111-300x151.png 300w, /wp-content/uploads/2018/06/word-image-111-768x387.png 768w" sizes="(max-width: 914px) 100vw, 914px" /></p>
<h3>（3）实例化模型</h3>
<p>方式一：在控制器中实例化模型首先引入其模型类所在的命名空间，如引入上面的Category</p>
<p>模型：</p>
<p>use app\admin\model\Category;</p>
<p>然后实例化模型：</p>
<p>// 静态调用</p>
<p>$data = Category::get(1); //获取主键值为1的数据</p>
<p>// 实例化模型</p>
<p>$cate= new Category();</p>
<p>$data = $cate-&gt;get(1);</p>
<p><img loading="lazy" decoding="async" width="503" height="239" class="wp-image-7506" src="/wp-content/uploads/2018/06/word-image-112.png" srcset="/wp-content/uploads/2018/06/word-image-112.png 503w, /wp-content/uploads/2018/06/word-image-112-300x143.png 300w" sizes="(max-width: 503px) 100vw, 503px" /></p>
<p>其中打印$dataObj是一个当前数据的对象：</p>
<p><img loading="lazy" decoding="async" width="479" height="584" class="wp-image-7507" src="/wp-content/uploads/2018/06/word-image-113.png" srcset="/wp-content/uploads/2018/06/word-image-113.png 479w, /wp-content/uploads/2018/06/word-image-113-246x300.png 246w" sizes="(max-width: 479px) 100vw, 479px" /></p>
<p>或者：</p>
<p><img loading="lazy" decoding="async" width="594" height="260" class="wp-image-7508" src="/wp-content/uploads/2018/06/word-image-114.png" srcset="/wp-content/uploads/2018/06/word-image-114.png 594w, /wp-content/uploads/2018/06/word-image-114-300x131.png 300w" sizes="(max-width: 594px) 100vw, 594px" /></p>
<p>方式二：或者直接可以使用助手函数model：</p>
<p>$cate = model(&#8216;Category&#8217;);</p>
<p>$data = $cate-&gt;get(1);</p>
<p><img loading="lazy" decoding="async" width="852" height="331" class="wp-image-7509" src="/wp-content/uploads/2018/06/word-image-115.png" srcset="/wp-content/uploads/2018/06/word-image-115.png 852w, /wp-content/uploads/2018/06/word-image-115-300x117.png 300w, /wp-content/uploads/2018/06/word-image-115-768x298.png 768w" sizes="(max-width: 852px) 100vw, 852px" /></p>
<h1>十六、模型CURD操作</h1>
<p>C-create：新增数据</p>
<p>U-update：更新数据</p>
<p>R-read：查询数据</p>
<p>D-delete：删除数据</p>
<h2>新增数据</h2>
<p>手册位置：模型-&gt;新增</p>
<h3>（1）添加一条数据</h3>
<p>$model-&gt;save($data);</p>
<p>参数：$data为一维数组，其中[‘字段名’=&gt;’数据’]</p>
<p>返回：成功返回写入的记录数</p>
<p><img loading="lazy" decoding="async" width="678" height="198" class="wp-image-7510" src="/wp-content/uploads/2018/06/word-image-116.png" srcset="/wp-content/uploads/2018/06/word-image-116.png 678w, /wp-content/uploads/2018/06/word-image-116-300x88.png 300w" sizes="(max-width: 678px) 100vw, 678px" /></p>
<h3>获取自增后的主键值</h3>
<p>$model-&gt;save($data);</p>
<p>echo $model-&gt;主键字段名;</p>
<p><img loading="lazy" decoding="async" width="598" height="240" class="wp-image-7511" src="/wp-content/uploads/2018/06/word-image-117.png" srcset="/wp-content/uploads/2018/06/word-image-117.png 598w, /wp-content/uploads/2018/06/word-image-117-300x120.png 300w" sizes="(max-width: 598px) 100vw, 598px" /></p>
<p>数据表数据如下：</p>
<p><img loading="lazy" decoding="async" width="541" height="64" class="wp-image-7512" src="/wp-content/uploads/2018/06/word-image-118.png" srcset="/wp-content/uploads/2018/06/word-image-118.png 541w, /wp-content/uploads/2018/06/word-image-118-300x35.png 300w" sizes="(max-width: 541px) 100vw, 541px" /></p>
<h3>（3）过滤非数据表字段</h3>
<ul>
<li>只允许数据表的字段写入</li>
</ul>
<p>$model-&gt;allowField(true)-&gt;save($data) ;</p>
<ul>
<li>只允许name和email字段写入</li>
</ul>
<p>$model-&gt;allowField([‘name’,’email’])-&gt;save($data) ;</p>
<p>代码：</p>
<p><img loading="lazy" decoding="async" width="609" height="138" class="wp-image-7513" src="/wp-content/uploads/2018/06/word-image-119.png" srcset="/wp-content/uploads/2018/06/word-image-119.png 609w, /wp-content/uploads/2018/06/word-image-119-300x68.png 300w" sizes="(max-width: 609px) 100vw, 609px" /></p>
<h3>（4）添加多条数据</h3>
<ul>
<li>$model-&gt;saveAll();</li>
</ul>
<p><img loading="lazy" decoding="async" width="665" height="272" class="wp-image-7514" src="/wp-content/uploads/2018/06/word-image-120.png" srcset="/wp-content/uploads/2018/06/word-image-120.png 665w, /wp-content/uploads/2018/06/word-image-120-300x123.png 300w" sizes="(max-width: 665px) 100vw, 665px" /></p>
<p>成功：返回数组对象集合。</p>
<p><img loading="lazy" decoding="async" width="461" height="207" class="wp-image-7515" src="/wp-content/uploads/2018/06/word-image-121.png" srcset="/wp-content/uploads/2018/06/word-image-121.png 461w, /wp-content/uploads/2018/06/word-image-121-300x135.png 300w" sizes="(max-width: 461px) 100vw, 461px" /></p>
<p>注：其中每条数据都是作为当前模型类的对象。</p>
<p>数据表如下：<br />
<img loading="lazy" decoding="async" width="494" height="55" class="wp-image-7516" src="/wp-content/uploads/2018/06/word-image-122.png" srcset="/wp-content/uploads/2018/06/word-image-122.png 494w, /wp-content/uploads/2018/06/word-image-122-300x33.png 300w" sizes="(max-width: 494px) 100vw, 494px" /></p>
<h2>更新数据-U</h2>
<p>手册位置：模型&#8211;&gt;更新</p>
<h3>更新方式一</h3>
<ul>
<li>$model-&gt;save($data,更新条件)</li>
<li>$model-&gt;isUpdate(true)-&gt;save($data)</li>
</ul>
<p>可以通过isUpdate方法指定save为执行更新操作，其中$data中必须带更新的主键值</p>
<ul>
<li>若需要过滤非数据表的字段数据，使用：</li>
</ul>
<p>$model-&gt;-&gt;isUpdate(true)-&gt;allowField(true)-&gt;save($data)</p>
<p><img loading="lazy" decoding="async" width="633" height="300" class="wp-image-7517" src="/wp-content/uploads/2018/06/word-image-123.png" srcset="/wp-content/uploads/2018/06/word-image-123.png 633w, /wp-content/uploads/2018/06/word-image-123-300x142.png 300w" sizes="(max-width: 633px) 100vw, 633px" /></p>
<p><img loading="lazy" decoding="async" width="651" height="64" class="wp-image-7518" src="/wp-content/uploads/2018/06/word-image-124.png" srcset="/wp-content/uploads/2018/06/word-image-124.png 651w, /wp-content/uploads/2018/06/word-image-124-300x29.png 300w" sizes="(max-width: 651px) 100vw, 651px" /></p>
<h3>（2）更新方式二</h3>
<ul>
<li>$model-&gt;update($data)</li>
</ul>
<p>参数$data为一维数组，键名为表字段名，其中更新必须指定更新条件，否则更新失败。</p>
<p>成功返回当前数据对象。</p>
<p><img loading="lazy" decoding="async" width="571" height="193" class="wp-image-7519" src="/wp-content/uploads/2018/06/word-image-125.png" srcset="/wp-content/uploads/2018/06/word-image-125.png 571w, /wp-content/uploads/2018/06/word-image-125-300x101.png 300w" sizes="(max-width: 571px) 100vw, 571px" /></p>
<p><img loading="lazy" decoding="async" width="471" height="26" class="wp-image-7520" src="/wp-content/uploads/2018/06/word-image-126.png" srcset="/wp-content/uploads/2018/06/word-image-126.png 471w, /wp-content/uploads/2018/06/word-image-126-300x17.png 300w" sizes="(max-width: 471px) 100vw, 471px" /></p>
<h2>删除数据-D</h2>
<h3>（1）调用静态方法删除一条数据</h3>
<p>模型类名::destroy(1); 如：User::destroy(1) 删除主键为1的记录</p>
<h3>（2）调用静态方法批量删除多个数据</h3>
<p>模型类名::destroy(‘1,2,3’); 删除主键为1,2,3的记录</p>
<p>或</p>
<p>模型类名::destroy([1,2,3]);</p>
<p>代码如下：</p>
<p><img loading="lazy" decoding="async" width="627" height="170" class="wp-image-7521" src="/wp-content/uploads/2018/06/word-image-127.png" srcset="/wp-content/uploads/2018/06/word-image-127.png 627w, /wp-content/uploads/2018/06/word-image-127-300x81.png 300w" sizes="(max-width: 627px) 100vw, 627px" /></p>
<h2>查询数据-R</h2>
<h3>（1）根据主键值获取记录一条记录</h3>
<p>$dataObj = 模型类名::get(主键值)</p>
<p>$dataObj = 模型类名::find(主键值)</p>
<p>成功返回当前数据的对象。</p>
<p><img loading="lazy" decoding="async" width="647" height="140" class="wp-image-7522" src="/wp-content/uploads/2018/06/word-image-128.png" srcset="/wp-content/uploads/2018/06/word-image-128.png 647w, /wp-content/uploads/2018/06/word-image-128-300x65.png 300w" sizes="(max-width: 647px) 100vw, 647px" /></p>
<h3>（2）根据主键值获取多条记录</h3>
<p>$dataObj= 模型类名::all(‘1,2,3’); //获取主键值为1,2,3的记录</p>
<p>或</p>
<p>$dataObj= 模型类名::all([1,2,3]); //获取主键值为1,2,3的记录</p>
<p>$dataObj= 模型类名::select(); //获取表中的所有数据</p>
<p>或</p>
<p>$dataObj= 模型类名::all();</p>
<p>all和select都是返回当前查询数组的数据对象集合。</p>
<p><img loading="lazy" decoding="async" width="596" height="223" class="wp-image-7523" src="/wp-content/uploads/2018/06/word-image-129.png" srcset="/wp-content/uploads/2018/06/word-image-129.png 596w, /wp-content/uploads/2018/06/word-image-129-300x112.png 300w" sizes="(max-width: 596px) 100vw, 596px" /></p>
<h2>连贯操作</h2>
<p>手册位置：数据库&#8211;&gt;查询构造器&#8211;&gt;链式操作</p>
<p>注： 模型的链式操作方法和Db构造器链式操作的方法都通用；</p>
<p>TP5常用的模型连贯操作方法如下：</p>
<p>方法说明：</p>
<ul>
<li>field(“field1,field2&#8230;”)：查询指定的字段field1和field2,多个用逗号隔开</li>
<li>alias(‘数据表别名’)：给当前数据表设置别名,join联表时用的多</li>
<li>where(查询条件)：查询条件可以为表达式查询、数组查询、字符串查询。</li>
<li>order(“field desc”)：把查询的到结果集进行字段field降序（desc）或升序(asc)。</li>
<li>group(“field”): 把查询的到结果集进行字段field分组。</li>
<li>limit(offset,length): 获取结果集指定条数的数据， offset为起始位置，length为获取记录的条数。</li>
<li>join()：与其他表进行关联查询</li>
</ul>
<p>注意：</p>
<p>以上的连贯操作方法都是返回当前模型的对象，即方法底层都是返回当前模型对象即return $this,所以他们之间的调用顺序不用按照原生的sql顺序来调用，但如果是查询数据，查询语句的最末端一定要确保是select或者是find方法。</p>
<p>在原生的sql语句中一定要按照先后顺序调用：</p>
<p>原生sql语句执行的先后顺序： join==&gt;where ==&gt; group ==&gt; having==&gt;order==&gt;limit</p>
<p>在tp5中以上的连贯操作都不需要按照顺序。</p>
<h3>（1）where表达式查询条件</h3>
<p><img loading="lazy" decoding="async" width="712" height="587" class="wp-image-7524" src="/wp-content/uploads/2018/06/word-image-130.png" srcset="/wp-content/uploads/2018/06/word-image-130.png 712w, /wp-content/uploads/2018/06/word-image-130-300x247.png 300w" sizes="(max-width: 712px) 100vw, 712px" /></p>
<p>代码如下：</p>
<p>例1：</p>
<p><img loading="lazy" decoding="async" width="798" height="189" class="wp-image-7525" src="/wp-content/uploads/2018/06/word-image-131.png" srcset="/wp-content/uploads/2018/06/word-image-131.png 798w, /wp-content/uploads/2018/06/word-image-131-300x71.png 300w, /wp-content/uploads/2018/06/word-image-131-768x182.png 768w" sizes="(max-width: 798px) 100vw, 798px" /></p>
<p>获取生成组装的sql语句： buildSql()</p>
<p><img loading="lazy" decoding="async" width="1020" height="344" class="wp-image-7526" src="/wp-content/uploads/2018/06/word-image-132.png" srcset="/wp-content/uploads/2018/06/word-image-132.png 1020w, /wp-content/uploads/2018/06/word-image-132-300x101.png 300w, /wp-content/uploads/2018/06/word-image-132-768x259.png 768w" sizes="(max-width: 1020px) 100vw, 1020px" /></p>
<p>可见，多个where连续调用，默认是and连接符。 如果想使用or,可以使用方法whereOr()</p>
<p><img loading="lazy" decoding="async" width="907" height="234" class="wp-image-7527" src="/wp-content/uploads/2018/06/word-image-133.png" srcset="/wp-content/uploads/2018/06/word-image-133.png 907w, /wp-content/uploads/2018/06/word-image-133-300x77.png 300w, /wp-content/uploads/2018/06/word-image-133-768x198.png 768w" sizes="(max-width: 907px) 100vw, 907px" /></p>
<h3>（2）where数组查询条件</h3>
<p>完整语法：</p>
<p>$where = [</p>
<p>‘字段名1’=&gt; [表达式，‘值’]</p>
<p>‘字段名2’=&gt; [表达式，‘值’]</p>
<p>]</p>
<p>如果是等值（=）查询，可以不用指定表达式，直接写值即可</p>
<p>$where = [</p>
<p>‘字段名’ =&gt; ‘值’</p>
<p>]</p>
<p>//默认多字段查询，是and链接。</p>
<p>例1：</p>
<p><img loading="lazy" decoding="async" width="817" height="159" class="wp-image-7528" src="/wp-content/uploads/2018/06/word-image-134.png" srcset="/wp-content/uploads/2018/06/word-image-134.png 817w, /wp-content/uploads/2018/06/word-image-134-300x58.png 300w, /wp-content/uploads/2018/06/word-image-134-768x149.png 768w" sizes="(max-width: 817px) 100vw, 817px" /></p>
<h3>（3）where字符串查询条件</h3>
<p>where(字符串条件)</p>
<p><img loading="lazy" decoding="async" width="764" height="188" class="wp-image-7529" src="/wp-content/uploads/2018/06/word-image-135.png" srcset="/wp-content/uploads/2018/06/word-image-135.png 764w, /wp-content/uploads/2018/06/word-image-135-300x74.png 300w" sizes="(max-width: 764px) 100vw, 764px" /></p>
<p>注：只能是类名::才可以调用方法，如果是对象调用，需要实例化对象，通过对象-&gt;去调用：</p>
<p><img loading="lazy" decoding="async" width="718" height="94" class="wp-image-7530" src="/wp-content/uploads/2018/06/word-image-136.png" srcset="/wp-content/uploads/2018/06/word-image-136.png 718w, /wp-content/uploads/2018/06/word-image-136-300x39.png 300w" sizes="(max-width: 718px) 100vw, 718px" /></p>
<h3>其中连贯操作方法</h3>
<ul>
<li>field(“field1,field2&#8230;”)：查询指定的字段field1和field2,多个用逗号隔开</li>
<li>alias(‘数据表别名’)：给当前数据表设置别名,join联表时用的多</li>
<li>where(查询条件)：查询条件可以为表达式查询、数组查询、字符串查询。</li>
<li>order(“field desc”)：把查询的到结果集进行字段field降序（desc）或升序(asc)。</li>
<li>group(“field”): 把查询的到结果集进行字段field分组。</li>
<li>limit(offset,length): 获取结果集指定条数的数据， offset为起始位置，length为获取记录的条数。</li>
<li>join()：与其他表进行关联查询</li>
</ul>
<p>注意：</p>
<p>以上的连贯操作方法都是返回当前模型的对象，即方法底层都是返回当前模型对象即return $this,所以他们之间的调用顺序不用按照原生的sql顺序来调用，但如果是查询数据，查询语句的最末端一定要确保是select或者是find方法。</p>
<p>例1：</p>
<p><img loading="lazy" decoding="async" width="989" height="116" class="wp-image-7531" src="/wp-content/uploads/2018/06/word-image-137.png" srcset="/wp-content/uploads/2018/06/word-image-137.png 989w, /wp-content/uploads/2018/06/word-image-137-300x35.png 300w, /wp-content/uploads/2018/06/word-image-137-768x90.png 768w" sizes="(max-width: 989px) 100vw, 989px" /></p>
<p>结果:</p>
<p><img loading="lazy" decoding="async" width="309" height="84" class="wp-image-7532" src="/wp-content/uploads/2018/06/word-image-138.png" srcset="/wp-content/uploads/2018/06/word-image-138.png 309w, /wp-content/uploads/2018/06/word-image-138-300x82.png 300w" sizes="(max-width: 309px) 100vw, 309px" /></p>
<p>注：通过模型数据对象-&gt;toArray()；可以转化为关联数组，看起来更加直观。</p>
<p>例2：</p>
<p><img loading="lazy" decoding="async" width="901" height="109" class="wp-image-7533" src="/wp-content/uploads/2018/06/word-image-139.png" srcset="/wp-content/uploads/2018/06/word-image-139.png 901w, /wp-content/uploads/2018/06/word-image-139-300x36.png 300w, /wp-content/uploads/2018/06/word-image-139-768x93.png 768w" sizes="(max-width: 901px) 100vw, 901px" /></p>
<p>例3：</p>
<p><img loading="lazy" decoding="async" width="925" height="105" class="wp-image-7534" src="/wp-content/uploads/2018/06/word-image-140.png" srcset="/wp-content/uploads/2018/06/word-image-140.png 925w, /wp-content/uploads/2018/06/word-image-140-300x34.png 300w, /wp-content/uploads/2018/06/word-image-140-768x87.png 768w" sizes="(max-width: 925px) 100vw, 925px" /></p>
<p>结果：</p>
<p><img loading="lazy" decoding="async" width="505" height="509" class="wp-image-7535" src="/wp-content/uploads/2018/06/word-image-141.png" srcset="/wp-content/uploads/2018/06/word-image-141.png 505w, /wp-content/uploads/2018/06/word-image-141-150x150.png 150w, /wp-content/uploads/2018/06/word-image-141-298x300.png 298w" sizes="(max-width: 505px) 100vw, 505px" /></p>
<p>默认select方法返回数组对象集合，只有取出具体的数据对象才可以调用toArray()转化为关联数组，如何把select方法的返回结果直接变为关联数组？</p>
<p>解决办法：把applciation/database.php文件的以下配置返回结果设置为think\Collection</p>
<p><img loading="lazy" decoding="async" width="747" height="187" class="wp-image-7536" src="/wp-content/uploads/2018/06/word-image-142.png" srcset="/wp-content/uploads/2018/06/word-image-142.png 747w, /wp-content/uploads/2018/06/word-image-142-300x75.png 300w" sizes="(max-width: 747px) 100vw, 747px" /></p>
<p>这样就可以使用select调用toAarray()返回关联数组：</p>
<p><img loading="lazy" decoding="async" width="1088" height="144" class="wp-image-7537" src="/wp-content/uploads/2018/06/word-image-143.png" srcset="/wp-content/uploads/2018/06/word-image-143.png 1088w, /wp-content/uploads/2018/06/word-image-143-300x40.png 300w, /wp-content/uploads/2018/06/word-image-143-768x102.png 768w, /wp-content/uploads/2018/06/word-image-143-1024x136.png 1024w" sizes="(max-width: 1088px) 100vw, 1088px" /></p>
<p><img loading="lazy" decoding="async" width="402" height="189" class="wp-image-7538" src="/wp-content/uploads/2018/06/word-image-144.png" srcset="/wp-content/uploads/2018/06/word-image-144.png 402w, /wp-content/uploads/2018/06/word-image-144-300x141.png 300w" sizes="(max-width: 402px) 100vw, 402px" /></p>
<p>例4、join联表</p>
<ol>
<li>联表查询出分类的所属父分类：</li>
</ol>
<p><img loading="lazy" decoding="async" width="1046" height="462" class="wp-image-7539" src="/wp-content/uploads/2018/06/word-image-145.png" srcset="/wp-content/uploads/2018/06/word-image-145.png 1046w, /wp-content/uploads/2018/06/word-image-145-300x133.png 300w, /wp-content/uploads/2018/06/word-image-145-768x339.png 768w, /wp-content/uploads/2018/06/word-image-145-1024x452.png 1024w" sizes="(max-width: 1046px) 100vw, 1046px" /></p>
<p>使用模型的join方法来实现：</p>
<p>手册位置：数据库&#8211;&gt;查询构造器&#8211;&gt;链式操作&#8211;&gt;join</p>
<p>语法： <img loading="lazy" decoding="async" width="674" height="55" class="wp-image-7540" src="/wp-content/uploads/2018/06/word-image-146.png" srcset="/wp-content/uploads/2018/06/word-image-146.png 674w, /wp-content/uploads/2018/06/word-image-146-300x24.png 300w" sizes="(max-width: 674px) 100vw, 674px" /></p>
<p><img loading="lazy" decoding="async" width="866" height="288" class="wp-image-7541" src="/wp-content/uploads/2018/06/word-image-147.png" srcset="/wp-content/uploads/2018/06/word-image-147.png 866w, /wp-content/uploads/2018/06/word-image-147-300x100.png 300w, /wp-content/uploads/2018/06/word-image-147-768x255.png 768w" sizes="(max-width: 866px) 100vw, 866px" /></p>
<p>结果：</p>
<p><img loading="lazy" decoding="async" width="492" height="409" class="wp-image-7542" src="/wp-content/uploads/2018/06/word-image-148.png" srcset="/wp-content/uploads/2018/06/word-image-148.png 492w, /wp-content/uploads/2018/06/word-image-148-300x249.png 300w" sizes="(max-width: 492px) 100vw, 492px" /></p>
<ol>
<li>联表查询出文章的所属分类：</li>
</ol>
<p><img loading="lazy" decoding="async" width="1045" height="408" class="wp-image-7543" src="/wp-content/uploads/2018/06/word-image-149.png" srcset="/wp-content/uploads/2018/06/word-image-149.png 1045w, /wp-content/uploads/2018/06/word-image-149-300x117.png 300w, /wp-content/uploads/2018/06/word-image-149-768x300.png 768w, /wp-content/uploads/2018/06/word-image-149-1024x400.png 1024w" sizes="(max-width: 1045px) 100vw, 1045px" /></p>
<p>在模型中使用join进行联表</p>
<ol>
<li>给表tp_article建立表模型</li>
</ol>
<p><img loading="lazy" decoding="async" width="396" height="167" class="wp-image-7544" src="/wp-content/uploads/2018/06/word-image-150.png" srcset="/wp-content/uploads/2018/06/word-image-150.png 396w, /wp-content/uploads/2018/06/word-image-150-300x127.png 300w" sizes="(max-width: 396px) 100vw, 396px" /></p>
<p>b、联表</p>
<p><img loading="lazy" decoding="async" width="845" height="363" class="wp-image-7545" src="/wp-content/uploads/2018/06/word-image-151.png" srcset="/wp-content/uploads/2018/06/word-image-151.png 845w, /wp-content/uploads/2018/06/word-image-151-300x129.png 300w, /wp-content/uploads/2018/06/word-image-151-768x330.png 768w" sizes="(max-width: 845px) 100vw, 845px" /></p>
<p>结果：</p>
<p><img loading="lazy" decoding="async" width="453" height="526" class="wp-image-7546" src="/wp-content/uploads/2018/06/word-image-152.png" srcset="/wp-content/uploads/2018/06/word-image-152.png 453w, /wp-content/uploads/2018/06/word-image-152-258x300.png 258w" sizes="(max-width: 453px) 100vw, 453px" /></p>
<h2>6、聚合（统计）函数</h2>
<p>常用的有以下几个聚合（统计）函数</p>
<p><img loading="lazy" decoding="async" width="465" height="273" class="wp-image-7547" src="/wp-content/uploads/2018/06/word-image-153.png" srcset="/wp-content/uploads/2018/06/word-image-153.png 465w, /wp-content/uploads/2018/06/word-image-153-300x176.png 300w" sizes="(max-width: 465px) 100vw, 465px" /></p>
<p>注意:调用统计函数前均支持连贯方法操作，但必须保证最末端是统计函数。</p>
<p>代码如下：</p>
<p><img loading="lazy" decoding="async" width="897" height="438" class="wp-image-7548" src="/wp-content/uploads/2018/06/word-image-154.png" srcset="/wp-content/uploads/2018/06/word-image-154.png 897w, /wp-content/uploads/2018/06/word-image-154-300x146.png 300w, /wp-content/uploads/2018/06/word-image-154-768x375.png 768w" sizes="(max-width: 897px) 100vw, 897px" /></p>
<h2>模型完成时间戳的自动维护</h2>
<p>手册位置：模型&#8211;&gt;时间戳</p>
<ol>
<li>给表设置update_time、create_time字段。</li>
</ol>
<p><img loading="lazy" decoding="async" width="519" height="195" class="wp-image-7549" src="/wp-content/uploads/2018/06/word-image-155.png" srcset="/wp-content/uploads/2018/06/word-image-155.png 519w, /wp-content/uploads/2018/06/word-image-155-300x113.png 300w" sizes="(max-width: 519px) 100vw, 519px" /></p>
<ol>
<li>在当前模型中开启时间戳的自动写入</li>
</ol>
<p><img loading="lazy" decoding="async" width="889" height="289" class="wp-image-7550" src="/wp-content/uploads/2018/06/word-image-156.png" srcset="/wp-content/uploads/2018/06/word-image-156.png 889w, /wp-content/uploads/2018/06/word-image-156-300x98.png 300w, /wp-content/uploads/2018/06/word-image-156-768x250.png 768w" sizes="(max-width: 889px) 100vw, 889px" /></p>
<p>开启时间戳自动写入之后，只要使用模型完成新增或编辑的操作，就会对表的两个时间字段字段自动维护。</p>
<h1>十七、通过Db构造器操作数据库</h1>
<p>通Db构造器查询数据库无需实例化模型也可对数据进行curd操作。</p>
<p>手册位置：数据库&#8211;&gt;查询构造器</p>
<h2>查询数据-R</h2>
<ul>
<li>查询一条数据</li>
</ul>
<p>如：Db::table(&#8216;think_user&#8217;)-&gt;field(‘username,email’)-&gt;where(id,1)-&gt;find();</p>
<ul>
<li>查询多条数据</li>
</ul>
<p>如：Db::table(&#8216;think_user&#8217;)-&gt;where(id,1)-&gt;select();</p>
<p>如：Db::name(&#8216;user&#8217;)-&gt;order(‘id’,’desc’)-&gt;select(); #不带表前缀</p>
<p>注： Db::table()需要完整表名，带表前缀，DB::name()是不带表前缀,且他们都支持连贯操作方法，只需保证最末端是select或是find或统计函数。</p>
<p>代码如下：</p>
<p><img loading="lazy" decoding="async" width="755" height="245" class="wp-image-7551" src="/wp-content/uploads/2018/06/word-image-157.png" srcset="/wp-content/uploads/2018/06/word-image-157.png 755w, /wp-content/uploads/2018/06/word-image-157-300x97.png 300w" sizes="(max-width: 755px) 100vw, 755px" /></p>
<p>结果：</p>
<p><img loading="lazy" decoding="async" width="287" height="366" class="wp-image-7552" src="/wp-content/uploads/2018/06/word-image-158.png" srcset="/wp-content/uploads/2018/06/word-image-158.png 287w, /wp-content/uploads/2018/06/word-image-158-235x300.png 235w" sizes="(max-width: 287px) 100vw, 287px" /></p>
<h2>执行原生sql语句</h2>
<p>查询：Db::query(“select”);</p>
<p>增删改：Db::execute(“insert/update/delete”);</p>
<p><img loading="lazy" decoding="async" width="925" height="90" class="wp-image-7553" src="/wp-content/uploads/2018/06/word-image-159.png" srcset="/wp-content/uploads/2018/06/word-image-159.png 925w, /wp-content/uploads/2018/06/word-image-159-300x29.png 300w, /wp-content/uploads/2018/06/word-image-159-768x75.png 768w" sizes="(max-width: 925px) 100vw, 925px" /></p>
<h2>添加数据-C</h2>
<ul>
<li>添加一条数据</li>
</ul>
<p>$data = [&#8216;foo&#8217; =&gt; &#8216;bar&#8217;, &#8216;bar&#8217; =&gt; &#8216;foo&#8217;];</p>
<p>Db::table(&#8216;think_user&#8217;)-&gt;insert($data);</p>
<p>insert 方法添加数据成功返回添加成功的条数，insert 正常情况返回 1</p>
<ul>
<li>或者直接使用insertGetId方法新增数据并返回主键值：</li>
</ul>
<p>Db::name(&#8216;user&#8217;)-&gt;insertGetId($data);</p>
<ul>
<li>添加多条数据</li>
</ul>
<p>添加多条数据直接向 Db 类的 insertAll 方法传入需要添加的数据即可</p>
<p>$data = [</p>
<p>[&#8216;foo&#8217; =&gt; &#8216;bar&#8217;, &#8216;bar&#8217; =&gt; &#8216;foo&#8217;],</p>
<p>[&#8216;foo&#8217; =&gt; &#8216;bar1&#8217;, &#8216;bar&#8217; =&gt; &#8216;foo1&#8217;],</p>
<p>[&#8216;foo&#8217; =&gt; &#8216;bar2&#8217;, &#8216;bar&#8217; =&gt; &#8216;foo2&#8217;]</p>
<p>];</p>
<p>Db::name(&#8216;user&#8217;)-&gt;insertAll($data);</p>
<p>insertAll 方法添加数据成功返回添加成功的条数</p>
<h2>删除数据-D</h2>
<ul>
<li>根据主键删除</li>
</ul>
<p>Db::table(&#8216;think_user&#8217;)-&gt;delete(1);</p>
<p>Db::table(&#8216;think_user&#8217;)-&gt;delete([1,2,3]);</p>
<ul>
<li>条件删除</li>
</ul>
<p>Db::table(&#8216;think_user&#8217;)-&gt;where(&#8216;id&#8217;,1)-&gt;delete();</p>
<p>Db::table(&#8216;think_user&#8217;)-&gt;where(&#8216;id&#8217;,'&lt;&#8216;,10)-&gt;delete();</p>
<p>delete 方法返回影响数据的条数，没有删除返回 0</p>
<h2>4、更新数据-U</h2>
<p>手册为主：数据库&#8211;&gt;查询构造器&#8211;&gt;更新数据</p>
<h3>更新数据表中的数据</h3>
<p>Db::table(&#8216;think_user&#8217;)-&gt;where(&#8216;id&#8217;, 1)-&gt;update([&#8216;name&#8217; =&gt; &#8216;thinkphp&#8217;]);</p>
<p>如果数据中包含主键，可以直接使用：</p>
<p>Db::table(&#8216;think_user&#8217;)-&gt;update([&#8216;name&#8217; =&gt; &#8216;thinkphp&#8217;,&#8217;id&#8217;=&gt;1]);</p>
<p>update 方法返回影响数据的条数，没修改任何数据返回 0</p>
<h3>更新某个字段的值</h3>
<p>Db::table(&#8216;think_user&#8217;)-&gt;where(&#8216;id&#8217;,1)-&gt;setField(&#8216;name&#8217;, &#8216;thinkphp&#8217;);</p>
<p>setField 方法返回影响数据的条数，没修改任何数据字段返回 0</p>
<h3>自增或自减一个字段的值</h3>
<p>setInc/setDec 如不加第二个参数，默认值为1</p>
<p>// score 字段加 1</p>
<p>Db::table(&#8216;think_user&#8217;)-&gt;where(&#8216;id&#8217;, 1)-&gt;setInc(&#8216;score&#8217;);</p>
<p>// score 字段加 5</p>
<p>Db::table(&#8216;think_user&#8217;)-&gt;where(&#8216;id&#8217;, 1)-&gt;setInc(&#8216;score&#8217;, 5);</p>
<p>// score 字段减 1</p>
<p>Db::table(&#8216;think_user&#8217;)-&gt;where(&#8216;id&#8217;, 1)-&gt;setDec(&#8216;score&#8217;);</p>
<p>// score 字段减 5</p>
<p>Db::table(&#8216;think_user&#8217;)-&gt;where(&#8216;id&#8217;, 1)-&gt;setDec(&#8216;score&#8217;, 5);</p>
<h3>助手db函数完成更新</h3>
<p>// 更新数据表中的数据</p>
<p>db(&#8216;user&#8217;)-&gt;where(&#8216;id&#8217;,1)-&gt;update([&#8216;name&#8217; =&gt; &#8216;thinkphp&#8217;]);</p>
<p>// 更新某个字段的值</p>
<p>db(&#8216;user&#8217;)-&gt;where(&#8216;id&#8217;,1)-&gt;setField(&#8216;name&#8217;,&#8217;thinkphp&#8217;);</p>
<p>// 自增 score 字段</p>
<p>db(&#8216;user&#8217;)-&gt;where(&#8216;id&#8217;, 1)-&gt;setInc(&#8216;score&#8217;);</p>
<p>// 自减 score 字段</p>
<p>db(&#8216;user&#8217;)-&gt;where(&#8216;id&#8217;, 1)-&gt;setDec(&#8216;score&#8217;);</p>
<h1>完成后台登录功能</h1>
<p>般用户表的第一个用户都是自己手工添加的。</p>
<ol>
<li>在配置文件config.php中添加一个password_salt的配置</li>
</ol>
<p><img loading="lazy" decoding="async" width="703" height="301" class="wp-image-7554" src="/wp-content/uploads/2018/06/word-image-160.png" srcset="/wp-content/uploads/2018/06/word-image-160.png 703w, /wp-content/uploads/2018/06/word-image-160-300x128.png 300w" sizes="(max-width: 703px) 100vw, 703px" /></p>
<ol>
<li>把加密的结果复制到用户表的password字段中</li>
</ol>
<p><img loading="lazy" decoding="async" width="762" height="360" class="wp-image-7555" src="/wp-content/uploads/2018/06/word-image-161.png" srcset="/wp-content/uploads/2018/06/word-image-161.png 762w, /wp-content/uploads/2018/06/word-image-161-300x142.png 300w" sizes="(max-width: 762px) 100vw, 762px" /></p>
<ol>
<li>修改login.html登录表单</li>
</ol>
<p><img loading="lazy" decoding="async" width="1112" height="584" class="wp-image-7556" src="/wp-content/uploads/2018/06/word-image-162.png" srcset="/wp-content/uploads/2018/06/word-image-162.png 1112w, /wp-content/uploads/2018/06/word-image-162-300x158.png 300w, /wp-content/uploads/2018/06/word-image-162-768x403.png 768w, /wp-content/uploads/2018/06/word-image-162-1024x538.png 1024w" sizes="(max-width: 1112px) 100vw, 1112px" /></p>
<ol>
<li>在login方法中判断是post请求，完成入库</li>
</ol>
<p><img loading="lazy" decoding="async" width="748" height="651" class="wp-image-7557" src="/wp-content/uploads/2018/06/word-image-163.png" srcset="/wp-content/uploads/2018/06/word-image-163.png 748w, /wp-content/uploads/2018/06/word-image-163-300x261.png 300w" sizes="(max-width: 748px) 100vw, 748px" /></p>
<ol>
<li>在User模型中定义一个检出用户名和密码是否匹配的方法</li>
</ol>
<p><img loading="lazy" decoding="async" width="872" height="654" class="wp-image-7558" src="/wp-content/uploads/2018/06/word-image-164.png" srcset="/wp-content/uploads/2018/06/word-image-164.png 872w, /wp-content/uploads/2018/06/word-image-164-300x225.png 300w, /wp-content/uploads/2018/06/word-image-164-768x576.png 768w" sizes="(max-width: 872px) 100vw, 872px" /></p>
<p>登录成功后，把session中的用户名信息回显到后台首页中（top.html）</p>
<p><img loading="lazy" decoding="async" width="1239" height="291" class="wp-image-7559" src="/wp-content/uploads/2018/06/word-image-165.png" srcset="/wp-content/uploads/2018/06/word-image-165.png 1239w, /wp-content/uploads/2018/06/word-image-165-300x70.png 300w, /wp-content/uploads/2018/06/word-image-165-768x180.png 768w, /wp-content/uploads/2018/06/word-image-165-1024x241.png 1024w" sizes="(max-width: 1239px) 100vw, 1239px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="220" height="82" class="wp-image-7560" src="/wp-content/uploads/2018/06/word-image-166.png" /></p>
<h1>完成后台退出功能</h1>
<p>核心：清除登录成功写入的session信息即可</p>
<ol>
<li>在Public控制器中建立一个logout的方法，清除session</li>
</ol>
<p><img loading="lazy" decoding="async" width="545" height="482" class="wp-image-7561" src="/wp-content/uploads/2018/06/word-image-167.png" srcset="/wp-content/uploads/2018/06/word-image-167.png 545w, /wp-content/uploads/2018/06/word-image-167-300x265.png 300w" sizes="(max-width: 545px) 100vw, 545px" /></p>
<ol>
<li>修改top.html模板的退出链接地址</li>
</ol>
<p><img loading="lazy" decoding="async" width="1230" height="280" class="wp-image-7562" src="/wp-content/uploads/2018/06/word-image-168.png" srcset="/wp-content/uploads/2018/06/word-image-168.png 1230w, /wp-content/uploads/2018/06/word-image-168-300x68.png 300w, /wp-content/uploads/2018/06/word-image-168-768x175.png 768w, /wp-content/uploads/2018/06/word-image-168-1024x233.png 1024w" sizes="(max-width: 1230px) 100vw, 1230px" /></p>
<h1>二十、完成登录防翻墙</h1>
<p>核心思想： 建立一个公共的控制器如：CommonController,在此控制器中做权限验证，判断是否有没有session,其他需要验证用户登录session信息的控制器就需要继承此控制器即可。</p>
<p><img loading="lazy" decoding="async" width="1016" height="371" class="wp-image-7563" src="/wp-content/uploads/2018/06/word-image-169.png" srcset="/wp-content/uploads/2018/06/word-image-169.png 1016w, /wp-content/uploads/2018/06/word-image-169-300x110.png 300w, /wp-content/uploads/2018/06/word-image-169-768x280.png 768w" sizes="(max-width: 1016px) 100vw, 1016px" /></p>
<p>把需要验证session的后台index控制器继承Common控制器即可：</p>
<p><img loading="lazy" decoding="async" width="699" height="234" class="wp-image-7564" src="/wp-content/uploads/2018/06/word-image-170.png" srcset="/wp-content/uploads/2018/06/word-image-170.png 699w, /wp-content/uploads/2018/06/word-image-170-300x100.png 300w" sizes="(max-width: 699px) 100vw, 699px" /></p>
<p>注：Public控制器不可以继承，因为此时还没有session信息。</p>
<h1>二十一、完成登录验证</h1>
<p>概述：ThinkPHP5.0验证使用独立的\think\Validate类或者验证器进行验证。</p>
<p>手册位置：验证器。</p>
<p>手册示例：</p>
<p><img loading="lazy" decoding="async" width="475" height="614" class="wp-image-7565" src="/wp-content/uploads/2018/06/word-image-171.png" srcset="/wp-content/uploads/2018/06/word-image-171.png 475w, /wp-content/uploads/2018/06/word-image-171-232x300.png 232w" sizes="(max-width: 475px) 100vw, 475px" /></p>
<p>//定义验证规则语法：</p>
<p>$rule = [</p>
<p>‘表单name值’ =&gt; 规则（多个规则竖线|隔开）</p>
<p>]</p>
<p>//定义验证不通过的提示信息</p>
<p>$msg = [</p>
<p>‘表单name值.规则名’ =&gt; ‘此规则的不通过的提示信息’</p>
<p>]</p>
<p>代码如下：</p>
<p><img loading="lazy" decoding="async" width="791" height="706" class="wp-image-7566" src="/wp-content/uploads/2018/06/word-image-172.png" srcset="/wp-content/uploads/2018/06/word-image-172.png 791w, /wp-content/uploads/2018/06/word-image-172-300x268.png 300w, /wp-content/uploads/2018/06/word-image-172-768x685.png 768w" sizes="(max-width: 791px) 100vw, 791px" /></p>
<p>提示效果：</p>
<p><img loading="lazy" decoding="async" width="506" height="301" class="wp-image-7567" src="/wp-content/uploads/2018/06/word-image-173.png" srcset="/wp-content/uploads/2018/06/word-image-173.png 506w, /wp-content/uploads/2018/06/word-image-173-300x178.png 300w" sizes="(max-width: 506px) 100vw, 506px" /></p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7499.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TP5.0（三）Composer 安装验证码、登录验证码、AR 模式操作数据库、文章分类添加、文章分类列表展示、文章分类编辑、Ajax 无刷新分类删除、文章添加、富文本编辑器</title>
		<link>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7568.html</link>
					<comments>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7568.html#respond</comments>
		
		<dc:creator><![CDATA[Mr.Lee]]></dc:creator>
		<pubDate>Sat, 09 Jun 2018 00:42:59 +0000</pubDate>
				<category><![CDATA[TP5.0]]></category>
		<category><![CDATA[后台框架]]></category>
		<category><![CDATA[Ajax 无刷新分类删除]]></category>
		<category><![CDATA[AR 模式操作数据库]]></category>
		<category><![CDATA[Composer 安装验证码]]></category>
		<category><![CDATA[富文本编辑器]]></category>
		<category><![CDATA[文章分类列表展示]]></category>
		<category><![CDATA[文章分类添加]]></category>
		<category><![CDATA[文章分类编辑]]></category>
		<category><![CDATA[文章添加]]></category>
		<category><![CDATA[登录验证码]]></category>
		<guid isPermaLink="false">/?p=7568</guid>

					<description><![CDATA[TP5第三天 composer 什么是composer Composer 是 PHP 的一个依赖管理工具。它允 [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>TP5第三天</h1>
<h1>composer</h1>
<h2>什么是composer</h2>
<p>Composer 是 PHP 的一个依赖管理工具。它允许你申明项目所依赖的类库，它会在你的项目中为你安装他们。</p>
<p>假设有个文件A.php,我们项目中使用需要就include A.php 包含进来，但是A.php又基于B.php,所以我们在A.php文件中又需要include B,但是不幸的B.php又基于C.php和D.php,于是又要在B.php进行include C.php和D.php 。假设C和D文件又基于其他文件，那么这样互相依赖的引入是非常麻烦的。</p>
<p><img loading="lazy" decoding="async" width="881" height="132" class="wp-image-7569" src="/wp-content/uploads/2018/06/word-image-174.png" srcset="/wp-content/uploads/2018/06/word-image-174.png 881w, /wp-content/uploads/2018/06/word-image-174-300x45.png 300w, /wp-content/uploads/2018/06/word-image-174-768x115.png 768w" sizes="(max-width: 881px) 100vw, 881px" /></p>
<p>那么在项目中使用composer就可以解决各个文件互相依赖的问题。除了解决文件依赖的关系，它还有更多的优点：</p>
<ul>
<li>下载网络上我们项目所需要的类库。</li>
<li>可对下载的类库进行管理，如：删除、更新等众多便利的操作。</li>
</ul>
<p>其实composer也就类似与Linux中yum，前端中的npm、bower等操作。这些工具都是可以用来管理我们的代码的。</p>
<h2>安装composer</h2>
<p>安装方式一般有两种方式：</p>
<p>第一种：去composer官网( <a href="/goto/poxn" rel="nofollow">https://getcomposer.org/download/</a> )下载Composer-setup.exe进行安装，由于此软件安装需要联网且服务器在国外安装很难成功，所以这里推荐使用下面第二种方式进行安装。</p>
<p><img loading="lazy" decoding="async" width="520" height="174" class="wp-image-7570" src="/wp-content/uploads/2018/06/word-image-175.png" srcset="/wp-content/uploads/2018/06/word-image-175.png 520w, /wp-content/uploads/2018/06/word-image-175-300x100.png 300w" sizes="(max-width: 520px) 100vw, 520px" /></p>
<p>我们使用下面的安装方式</p>
<p>第二种：去官网https://getcomposer.org/download 下载composer.phar文件。</p>
<p><img loading="lazy" decoding="async" width="509" height="448" class="wp-image-7571" src="/wp-content/uploads/2018/06/word-image-176.png" srcset="/wp-content/uploads/2018/06/word-image-176.png 509w, /wp-content/uploads/2018/06/word-image-176-300x264.png 300w" sizes="(max-width: 509px) 100vw, 509px" /></p>
<p>找到并进入 PHP 的安装目录,将下载的composer.phar 复制到 PHP 的安装目录下面，也就是和 php.exe 在同一级目录。</p>
<p><img loading="lazy" decoding="async" width="715" height="462" class="wp-image-7572" src="/wp-content/uploads/2018/06/word-image-177.png" srcset="/wp-content/uploads/2018/06/word-image-177.png 715w, /wp-content/uploads/2018/06/word-image-177-300x194.png 300w" sizes="(max-width: 715px) 100vw, 715px" /></p>
<p>在 PHP 安装目录（D:\phpStudy\php\php-5.6.27-nts）下新建一个 composer.bat 文件，并将下列代码保存到此文件中。</p>
<p>@php &#8220;%~dp0composer.phar&#8221; %*</p>
<p>至此composer的安装就完成。</p>
<p>进入目录D:\phpStudy\php\php-5.6.27-nts中输入composer指令，出现如下提示代表安装成功：</p>
<p><img loading="lazy" decoding="async" width="826" height="366" class="wp-image-7573" src="/wp-content/uploads/2018/06/word-image-178.png" srcset="/wp-content/uploads/2018/06/word-image-178.png 826w, /wp-content/uploads/2018/06/word-image-178-300x133.png 300w, /wp-content/uploads/2018/06/word-image-178-768x340.png 768w" sizes="(max-width: 826px) 100vw, 826px" /></p>
<p>为了可以全局（任意位置）访问composer，可以把php.exe的所在目录（D:\phpStudy\php\php-5.6.27-nts）定义在环境变量path选项中。</p>
<p><img loading="lazy" decoding="async" width="418" height="255" class="wp-image-7574" src="/wp-content/uploads/2018/06/word-image-179.png" srcset="/wp-content/uploads/2018/06/word-image-179.png 418w, /wp-content/uploads/2018/06/word-image-179-300x183.png 300w" sizes="(max-width: 418px) 100vw, 418px" /></p>
<p>设置好后输入php -v即可看到php版本号。</p>
<p><img loading="lazy" decoding="async" width="526" height="76" class="wp-image-7575" src="/wp-content/uploads/2018/06/word-image-180.png" srcset="/wp-content/uploads/2018/06/word-image-180.png 526w, /wp-content/uploads/2018/06/word-image-180-300x43.png 300w" sizes="(max-width: 526px) 100vw, 526px" /></p>
<p>cmd中任意位置输入composer指令：</p>
<p><img loading="lazy" decoding="async" width="513" height="114" class="wp-image-7576" src="/wp-content/uploads/2018/06/word-image-181.png" srcset="/wp-content/uploads/2018/06/word-image-181.png 513w, /wp-content/uploads/2018/06/word-image-181-300x67.png 300w" sizes="(max-width: 513px) 100vw, 513px" /></p>
<h2>配置composer为国内镜像</h2>
<p>由于composer需要去网址为https://packagist.org获取代码库地址，再通过地址去github上去下载代码到我们项目本地，由于这两个地址服务器都在国外，访问比较慢，也不稳定。/</p>
<p><img loading="lazy" decoding="async" width="674" height="360" class="wp-image-7577" src="/wp-content/uploads/2018/06/word-image-182.png" srcset="/wp-content/uploads/2018/06/word-image-182.png 674w, /wp-content/uploads/2018/06/word-image-182-300x160.png 300w" sizes="(max-width: 674px) 100vw, 674px" /></p>
<p>配置国内镜像：输入命令</p>
<p>全局配置：composer config -g repo.packagist composer https://packagist.phpcomposer.com/</p>
<p><img loading="lazy" decoding="async" width="782" height="116" class="wp-image-7578" src="/wp-content/uploads/2018/06/word-image-183.png" srcset="/wp-content/uploads/2018/06/word-image-183.png 782w, /wp-content/uploads/2018/06/word-image-183-300x45.png 300w, /wp-content/uploads/2018/06/word-image-183-768x114.png 768w" sizes="(max-width: 782px) 100vw, 782px" /></p>
<p>局部配置：若只想在当前项目中有效，把上面的命令去掉 -g 即可。</p>
<p>几个有关的composer命令：</p>
<p>查看全局配置信息：composer config -gl</p>
<p>取消镜像：composer config -g &#8211;unset repos.packagist</p>
<p>查看当前版本：composer -v</p>
<p>升级版本：composer selfupdate</p>
<h1>使用composer安装tp5验证码</h1>
<p>手册位置：杂项&#8211;&gt;验证码</p>
<p>composer.json的文件说明和具体使用：</p>
<p>参考网址：http://docs.phpcomposer.com/04-schema.html#archive</p>
<p>第一步：切换到tp5的composer.json 所在的目录，输入指令 composer require topthink/think-captcha进行安装</p>
<p>在当前目录打开cmd：ctrl+shfit+鼠标右键</p>
<p><img loading="lazy" decoding="async" width="356" height="49" class="wp-image-7579" src="/wp-content/uploads/2018/06/word-image-184.png" srcset="/wp-content/uploads/2018/06/word-image-184.png 356w, /wp-content/uploads/2018/06/word-image-184-300x41.png 300w" sizes="(max-width: 356px) 100vw, 356px" /></p>
<p><img loading="lazy" decoding="async" width="712" height="328" class="wp-image-7580" src="/wp-content/uploads/2018/06/word-image-185.png" srcset="/wp-content/uploads/2018/06/word-image-185.png 712w, /wp-content/uploads/2018/06/word-image-185-300x138.png 300w" sizes="(max-width: 712px) 100vw, 712px" /></p>
<p>安装成功后，会在vendor目录多出think-captcha</p>
<p><img loading="lazy" decoding="async" width="701" height="283" class="wp-image-7581" src="/wp-content/uploads/2018/06/word-image-186.png" srcset="/wp-content/uploads/2018/06/word-image-186.png 701w, /wp-content/uploads/2018/06/word-image-186-300x121.png 300w" sizes="(max-width: 701px) 100vw, 701px" /></p>
<p>注：默认下载的tp5框架已经帮我们下载好了验证码，直接使用即可。</p>
<h1>完成登录的验证码功能</h1>
<p>我们需要把通过composer下载下来的验证码应用到我们tp5项目中。</p>
<p>手册位置：杂项&#8211;&gt;验证码</p>
<p>或：<a href="/goto/8fls" rel="nofollow">https://packagist.org/packages/topthink/think-captcha</a></p>
<p>第一步：在login.html显示验证码</p>
<p><img loading="lazy" decoding="async" width="1172" height="519" class="wp-image-7582" src="/wp-content/uploads/2018/06/word-image-187.png" srcset="/wp-content/uploads/2018/06/word-image-187.png 1172w, /wp-content/uploads/2018/06/word-image-187-300x133.png 300w, /wp-content/uploads/2018/06/word-image-187-768x340.png 768w, /wp-content/uploads/2018/06/word-image-187-1024x453.png 1024w" sizes="(max-width: 1172px) 100vw, 1172px" /></p>
<p>第二步：通过配置定义验证码的显示配置</p>
<p><img loading="lazy" decoding="async" width="731" height="422" class="wp-image-7583" src="/wp-content/uploads/2018/06/word-image-188.png" srcset="/wp-content/uploads/2018/06/word-image-188.png 731w, /wp-content/uploads/2018/06/word-image-188-300x173.png 300w" sizes="(max-width: 731px) 100vw, 731px" /></p>
<p>第三步：登录时，判断验证码是否匹配成功</p>
<p><img loading="lazy" decoding="async" width="771" height="629" class="wp-image-7584" src="/wp-content/uploads/2018/06/word-image-189.png" srcset="/wp-content/uploads/2018/06/word-image-189.png 771w, /wp-content/uploads/2018/06/word-image-189-300x245.png 300w, /wp-content/uploads/2018/06/word-image-189-768x627.png 768w" sizes="(max-width: 771px) 100vw, 771px" /></p>
<h1>四、AR模式操作数据库</h1>
<h2>1、AR介绍</h2>
<p>Active Record (AR) 模式 是一个流行的 对象-关系映射 (ORM) 技术。 每个 AR 类代表一个数据表（或视图），数据表（或视图）的列在 AR 类中体现为类的属性，一个 AR 实例则表示表中的一行。 常见的 CRUD 操作作为 AR 的方法实现。因此，我们可以以一种更加面向对象的方式操作数据库。</p>
<p>AR模式三个核心：</p>
<p>表&#8211;&gt;模型类</p>
<p>表中一行&#8211;&gt;模型对象</p>
<p>行的某列&#8211;&gt;模型对象属性</p>
<p><img loading="lazy" decoding="async" width="616" height="259" class="wp-image-7585" src="/wp-content/uploads/2018/06/word-image-190.png" srcset="/wp-content/uploads/2018/06/word-image-190.png 616w, /wp-content/uploads/2018/06/word-image-190-300x126.png 300w" sizes="(max-width: 616px) 100vw, 616px" /></p>
<h2>AR模式完成CURD操作</h2>
<h3>AR完成新增</h3>
<p>手册示例：</p>
<p><img loading="lazy" decoding="async" width="397" height="207" class="wp-image-7586" src="/wp-content/uploads/2018/06/word-image-191.png" srcset="/wp-content/uploads/2018/06/word-image-191.png 397w, /wp-content/uploads/2018/06/word-image-191-300x156.png 300w" sizes="(max-width: 397px) 100vw, 397px" /></p>
<p><img loading="lazy" decoding="async" width="577" height="238" class="wp-image-7587" src="/wp-content/uploads/2018/06/word-image-192.png" srcset="/wp-content/uploads/2018/06/word-image-192.png 577w, /wp-content/uploads/2018/06/word-image-192-300x124.png 300w" sizes="(max-width: 577px) 100vw, 577px" /></p>
<h3>AR完成删除</h3>
<p>手册示例：</p>
<p><img loading="lazy" decoding="async" width="456" height="146" class="wp-image-7588" src="/wp-content/uploads/2018/06/word-image-193.png" srcset="/wp-content/uploads/2018/06/word-image-193.png 456w, /wp-content/uploads/2018/06/word-image-193-300x96.png 300w" sizes="(max-width: 456px) 100vw, 456px" /></p>
<p><img loading="lazy" decoding="async" width="589" height="174" class="wp-image-7589" src="/wp-content/uploads/2018/06/word-image-194.png" srcset="/wp-content/uploads/2018/06/word-image-194.png 589w, /wp-content/uploads/2018/06/word-image-194-300x89.png 300w" sizes="(max-width: 589px) 100vw, 589px" /></p>
<h3>AR完成更新</h3>
<p><img loading="lazy" decoding="async" width="630" height="276" class="wp-image-7590" src="/wp-content/uploads/2018/06/word-image-195.png" srcset="/wp-content/uploads/2018/06/word-image-195.png 630w, /wp-content/uploads/2018/06/word-image-195-300x131.png 300w" sizes="(max-width: 630px) 100vw, 630px" /></p>
<h3>AR完成查询</h3>
<p><img loading="lazy" decoding="async" width="517" height="248" class="wp-image-7591" src="/wp-content/uploads/2018/06/word-image-196.png" srcset="/wp-content/uploads/2018/06/word-image-196.png 517w, /wp-content/uploads/2018/06/word-image-196-300x144.png 300w" sizes="(max-width: 517px) 100vw, 517px" /></p>
<h1>完成文章分类的添加</h1>
<h2>1、完成模板数据的展示</h2>
<p>第一步：修改后台的链接地址（left.html）</p>
<p><img loading="lazy" decoding="async" width="1254" height="314" class="wp-image-7592" src="/wp-content/uploads/2018/06/word-image-197.png" srcset="/wp-content/uploads/2018/06/word-image-197.png 1254w, /wp-content/uploads/2018/06/word-image-197-300x75.png 300w, /wp-content/uploads/2018/06/word-image-197-768x192.png 768w, /wp-content/uploads/2018/06/word-image-197-1024x256.png 1024w" sizes="(max-width: 1254px) 100vw, 1254px" /></p>
<p>第二步:在后台admin建立一个Category的控制器，并建立一个add方法完成添加分类的功能</p>
<p><img loading="lazy" decoding="async" width="921" height="410" class="wp-image-7593" src="/wp-content/uploads/2018/06/word-image-198.png" srcset="/wp-content/uploads/2018/06/word-image-198.png 921w, /wp-content/uploads/2018/06/word-image-198-300x134.png 300w, /wp-content/uploads/2018/06/word-image-198-768x342.png 768w" sizes="(max-width: 921px) 100vw, 921px" /></p>
<p>第三步：在当前模型的中，建立一个无限极分类的函数，完成栏目之间额层级缩进</p>
<p><img loading="lazy" decoding="async" width="1091" height="585" class="wp-image-7594" src="/wp-content/uploads/2018/06/word-image-199.png" srcset="/wp-content/uploads/2018/06/word-image-199.png 1091w, /wp-content/uploads/2018/06/word-image-199-300x161.png 300w, /wp-content/uploads/2018/06/word-image-199-768x412.png 768w, /wp-content/uploads/2018/06/word-image-199-1024x549.png 1024w" sizes="(max-width: 1091px) 100vw, 1091px" /></p>
<p>第四步：模板中显示数据</p>
<p><img loading="lazy" decoding="async" width="1241" height="604" class="wp-image-7595" src="/wp-content/uploads/2018/06/word-image-200.png" srcset="/wp-content/uploads/2018/06/word-image-200.png 1241w, /wp-content/uploads/2018/06/word-image-200-300x146.png 300w, /wp-content/uploads/2018/06/word-image-200-768x374.png 768w, /wp-content/uploads/2018/06/word-image-200-1024x498.png 1024w" sizes="(max-width: 1241px) 100vw, 1241px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="700" height="359" class="wp-image-7596" src="/wp-content/uploads/2018/06/word-image-201.png" srcset="/wp-content/uploads/2018/06/word-image-201.png 700w, /wp-content/uploads/2018/06/word-image-201-300x154.png 300w" sizes="(max-width: 700px) 100vw, 700px" /></p>
<h2>完成数据的入库</h2>
<p>第一步：在add方法中判断是否是post请求，完成数据的入库</p>
<p><img loading="lazy" decoding="async" width="799" height="662" class="wp-image-7597" src="/wp-content/uploads/2018/06/word-image-202.png" srcset="/wp-content/uploads/2018/06/word-image-202.png 799w, /wp-content/uploads/2018/06/word-image-202-300x249.png 300w, /wp-content/uploads/2018/06/word-image-202-768x636.png 768w" sizes="(max-width: 799px) 100vw, 799px" /></p>
<p>第二步：使用验证器Validate进行入库前的数据验证过滤</p>
<p><img loading="lazy" decoding="async" width="797" height="558" class="wp-image-7598" src="/wp-content/uploads/2018/06/word-image-203.png" srcset="/wp-content/uploads/2018/06/word-image-203.png 797w, /wp-content/uploads/2018/06/word-image-203-300x210.png 300w, /wp-content/uploads/2018/06/word-image-203-768x538.png 768w" sizes="(max-width: 797px) 100vw, 797px" /></p>
<p>建议把上面的验证写在一个验证器中，进行统计管理，也方便后期代码的维护，也可以增加代码的可读性。</p>
<p>所以，我们可以把上面的规则和提示信息抽离出来，写在独立的验证器中：</p>
<p><img loading="lazy" decoding="async" width="812" height="650" class="wp-image-7599" src="/wp-content/uploads/2018/06/word-image-204.png" srcset="/wp-content/uploads/2018/06/word-image-204.png 812w, /wp-content/uploads/2018/06/word-image-204-300x240.png 300w, /wp-content/uploads/2018/06/word-image-204-768x615.png 768w" sizes="(max-width: 812px) 100vw, 812px" /></p>
<p>在add的方法中使用上面的验证器进行验证即可：</p>
<p><img loading="lazy" decoding="async" width="1030" height="693" class="wp-image-7600" src="/wp-content/uploads/2018/06/word-image-205.png" srcset="/wp-content/uploads/2018/06/word-image-205.png 1030w, /wp-content/uploads/2018/06/word-image-205-300x202.png 300w, /wp-content/uploads/2018/06/word-image-205-768x517.png 768w, /wp-content/uploads/2018/06/word-image-205-1024x689.png 1024w" sizes="(max-width: 1030px) 100vw, 1030px" /></p>
<p>validate方法的源码位置：</p>
<p><img loading="lazy" decoding="async" width="1088" height="412" class="wp-image-7601" src="/wp-content/uploads/2018/06/word-image-206.png" srcset="/wp-content/uploads/2018/06/word-image-206.png 1088w, /wp-content/uploads/2018/06/word-image-206-300x114.png 300w, /wp-content/uploads/2018/06/word-image-206-768x291.png 768w, /wp-content/uploads/2018/06/word-image-206-1024x388.png 1024w" sizes="(max-width: 1088px) 100vw, 1088px" /></p>
<p>此方法验证成功会返回true。</p>
<p>验证失败会返回错误信息，若不是批量验证返回一个字符串的错误信息，批量验证则返回一个错误的数组，可以使用implode拼接成一个字符串进行提示。</p>
<h1>完成文章分类的列表展示</h1>
<p>第一步：修改left.html加一个链接地址</p>
<p><img loading="lazy" decoding="async" width="1257" height="257" class="wp-image-7602" src="/wp-content/uploads/2018/06/word-image-207.png" srcset="/wp-content/uploads/2018/06/word-image-207.png 1257w, /wp-content/uploads/2018/06/word-image-207-300x61.png 300w, /wp-content/uploads/2018/06/word-image-207-768x157.png 768w, /wp-content/uploads/2018/06/word-image-207-1024x209.png 1024w" sizes="(max-width: 1257px) 100vw, 1257px" /></p>
<p>第二步：在Category控制器加一个index 的方法完成分类的列表数据输出给模板</p>
<p><img loading="lazy" decoding="async" width="601" height="546" class="wp-image-7603" src="/wp-content/uploads/2018/06/word-image-208.png" srcset="/wp-content/uploads/2018/06/word-image-208.png 601w, /wp-content/uploads/2018/06/word-image-208-300x273.png 300w" sizes="(max-width: 601px) 100vw, 601px" /></p>
<p>其中$newlists的数据打印如下：以每个元素cat_id作为下标。</p>
<p><img loading="lazy" decoding="async" width="439" height="254" class="wp-image-7604" src="/wp-content/uploads/2018/06/word-image-209.png" srcset="/wp-content/uploads/2018/06/word-image-209.png 439w, /wp-content/uploads/2018/06/word-image-209-300x174.png 300w" sizes="(max-width: 439px) 100vw, 439px" /></p>
<p>第三步：模板中显示数据</p>
<p><img loading="lazy" decoding="async" width="1262" height="696" class="wp-image-7605" src="/wp-content/uploads/2018/06/word-image-210.png" srcset="/wp-content/uploads/2018/06/word-image-210.png 1262w, /wp-content/uploads/2018/06/word-image-210-300x165.png 300w, /wp-content/uploads/2018/06/word-image-210-768x424.png 768w, /wp-content/uploads/2018/06/word-image-210-1024x565.png 1024w" sizes="(max-width: 1262px) 100vw, 1262px" /></p>
<p>上面的由于数组$lists下标0不存在，所以需要isset判断一下，但是这样写较麻烦，可以通过配置不报这种错误。修改common.php即可。</p>
<p><img loading="lazy" decoding="async" width="811" height="293" class="wp-image-7606" src="/wp-content/uploads/2018/06/word-image-211.png" srcset="/wp-content/uploads/2018/06/word-image-211.png 811w, /wp-content/uploads/2018/06/word-image-211-300x108.png 300w, /wp-content/uploads/2018/06/word-image-211-768x277.png 768w" sizes="(max-width: 811px) 100vw, 811px" /></p>
<p>效果：<br />
<img loading="lazy" decoding="async" width="896" height="234" class="wp-image-7607" src="/wp-content/uploads/2018/06/word-image-212.png" srcset="/wp-content/uploads/2018/06/word-image-212.png 896w, /wp-content/uploads/2018/06/word-image-212-300x78.png 300w, /wp-content/uploads/2018/06/word-image-212-768x201.png 768w" sizes="(max-width: 896px) 100vw, 896px" /></p>
<p>注：其中create_time和update_time在数据库中是时间戳的格式，但是受到配置文件database.php 的影响，获取数据时，自动转化为日期格式：</p>
<p><img loading="lazy" decoding="async" width="856" height="256" class="wp-image-7608" src="/wp-content/uploads/2018/06/word-image-213.png" srcset="/wp-content/uploads/2018/06/word-image-213.png 856w, /wp-content/uploads/2018/06/word-image-213-300x90.png 300w, /wp-content/uploads/2018/06/word-image-213-768x230.png 768w" sizes="(max-width: 856px) 100vw, 856px" /></p>
<h1>完成文章分类的编辑</h1>
<p>第一步：修改列表的编辑的链接地址</p>
<p><img loading="lazy" decoding="async" width="1228" height="238" class="wp-image-7609" src="/wp-content/uploads/2018/06/word-image-214.png" srcset="/wp-content/uploads/2018/06/word-image-214.png 1228w, /wp-content/uploads/2018/06/word-image-214-300x58.png 300w, /wp-content/uploads/2018/06/word-image-214-768x149.png 768w, /wp-content/uploads/2018/06/word-image-214-1024x198.png 1024w" sizes="(max-width: 1228px) 100vw, 1228px" /></p>
<p>第二步：在Controller控制器建立一个upd方法，完成编辑的功能</p>
<p><img loading="lazy" decoding="async" width="820" height="716" class="wp-image-7610" src="/wp-content/uploads/2018/06/word-image-215.png" srcset="/wp-content/uploads/2018/06/word-image-215.png 820w, /wp-content/uploads/2018/06/word-image-215-300x262.png 300w, /wp-content/uploads/2018/06/word-image-215-768x671.png 768w" sizes="(max-width: 820px) 100vw, 820px" /></p>
<p>第三步：模板upd.html设置</p>
<p><img loading="lazy" decoding="async" width="1183" height="717" class="wp-image-7611" src="/wp-content/uploads/2018/06/word-image-216.png" srcset="/wp-content/uploads/2018/06/word-image-216.png 1183w, /wp-content/uploads/2018/06/word-image-216-300x182.png 300w, /wp-content/uploads/2018/06/word-image-216-768x465.png 768w, /wp-content/uploads/2018/06/word-image-216-1024x621.png 1024w" sizes="(max-width: 1183px) 100vw, 1183px" /></p>
<p>小技巧：$(&#8220;select[name=&#8217;pid&#8217;]&#8221;).val(3); //代表把option标签value等于3的父分类默认选中</p>
<p>当然也可以使用下面的eq来判断，但是不推荐，因为比较麻烦，而且还要模板标签还要编译效率低。</p>
<p><img loading="lazy" decoding="async" width="846" height="302" class="wp-image-7612" src="/wp-content/uploads/2018/06/word-image-217.png" srcset="/wp-content/uploads/2018/06/word-image-217.png 846w, /wp-content/uploads/2018/06/word-image-217-300x107.png 300w, /wp-content/uploads/2018/06/word-image-217-768x274.png 768w" sizes="(max-width: 846px) 100vw, 846px" /></p>
<h1>使用Ajax完成文章分类的无刷新删除</h1>
<h2>传统删除</h2>
<p>第一步：给删除设置链接地址</p>
<p><img loading="lazy" decoding="async" width="1259" height="278" class="wp-image-7613" src="/wp-content/uploads/2018/06/word-image-218.png" srcset="/wp-content/uploads/2018/06/word-image-218.png 1259w, /wp-content/uploads/2018/06/word-image-218-300x66.png 300w, /wp-content/uploads/2018/06/word-image-218-768x170.png 768w, /wp-content/uploads/2018/06/word-image-218-1024x226.png 1024w" sizes="(max-width: 1259px) 100vw, 1259px" /></p>
<p>第二步：在Category控制器建立一个del方法，完成分类的删除</p>
<p><img loading="lazy" decoding="async" width="777" height="337" class="wp-image-7614" src="/wp-content/uploads/2018/06/word-image-219.png" srcset="/wp-content/uploads/2018/06/word-image-219.png 777w, /wp-content/uploads/2018/06/word-image-219-300x130.png 300w, /wp-content/uploads/2018/06/word-image-219-768x333.png 768w" sizes="(max-width: 777px) 100vw, 777px" /></p>
<p>作业：删除分类考虑的两点</p>
<ol>
<li>当前分类下面是否有子分类</li>
<li>当前分类下面是否存在文章</li>
</ol>
<p>满足上面两个条件之一都不能删除。</p>
<h2>2、ajax无刷新删除</h2>
<p>删除分类考虑的两点</p>
<ol>
<li>当前分类下面是否有子分类</li>
<li>当前分类下面是否存在文章</li>
</ol>
<p>满足上面两个条件之一都不能删除。</p>
<p>第一步：给删除的a标签阻止默认行为，并且加一个自定义的属性cat_id,为了记录当前要删除的分类cat_id,同时设置一个delCat,目的给这一类的元素绑定单击事件</p>
<p><img loading="lazy" decoding="async" width="1253" height="210" class="wp-image-7615" src="/wp-content/uploads/2018/06/word-image-220.png" srcset="/wp-content/uploads/2018/06/word-image-220.png 1253w, /wp-content/uploads/2018/06/word-image-220-300x50.png 300w, /wp-content/uploads/2018/06/word-image-220-768x129.png 768w, /wp-content/uploads/2018/06/word-image-220-1024x172.png 1024w" sizes="(max-width: 1253px) 100vw, 1253px" /></p>
<p>第二步：给class=’delCat’,绑定单击事件，获取属性cat_id,发送ajax请求</p>
<p><img loading="lazy" decoding="async" width="1009" height="431" class="wp-image-7616" src="/wp-content/uploads/2018/06/word-image-221.png" srcset="/wp-content/uploads/2018/06/word-image-221.png 1009w, /wp-content/uploads/2018/06/word-image-221-300x128.png 300w, /wp-content/uploads/2018/06/word-image-221-768x328.png 768w" sizes="(max-width: 1009px) 100vw, 1009px" /></p>
<p>第三步：去Category控制器，建立一个ajaxDelCat的方法</p>
<p><img loading="lazy" decoding="async" width="842" height="715" class="wp-image-7617" src="/wp-content/uploads/2018/06/word-image-222.png" srcset="/wp-content/uploads/2018/06/word-image-222.png 842w, /wp-content/uploads/2018/06/word-image-222-300x255.png 300w, /wp-content/uploads/2018/06/word-image-222-768x652.png 768w" sizes="(max-width: 842px) 100vw, 842px" /></p>
<p>第四步：ajax根据服务端响应的json数据，删除成功把当前tr给移除掉</p>
<p><img loading="lazy" decoding="async" width="1000" height="605" class="wp-image-7618" src="/wp-content/uploads/2018/06/word-image-223.png" srcset="/wp-content/uploads/2018/06/word-image-223.png 1000w, /wp-content/uploads/2018/06/word-image-223-300x182.png 300w, /wp-content/uploads/2018/06/word-image-223-768x465.png 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></p>
<h1>完成文章的添加</h1>
<h2>完成文章模板的展示</h2>
<p>第一步：修改left.html模板，加一个添加分类的链接地址</p>
<p><img loading="lazy" decoding="async" width="1262" height="365" class="wp-image-7619" src="/wp-content/uploads/2018/06/word-image-224.png" srcset="/wp-content/uploads/2018/06/word-image-224.png 1262w, /wp-content/uploads/2018/06/word-image-224-300x87.png 300w, /wp-content/uploads/2018/06/word-image-224-768x222.png 768w, /wp-content/uploads/2018/06/word-image-224-1024x296.png 1024w" sizes="(max-width: 1262px) 100vw, 1262px" /></p>
<p>第二步：在后台admin创建一个Article控制器，并建立一个add方法，完成文章的入库操作</p>
<p><img loading="lazy" decoding="async" width="749" height="368" class="wp-image-7620" src="/wp-content/uploads/2018/06/word-image-225.png" srcset="/wp-content/uploads/2018/06/word-image-225.png 749w, /wp-content/uploads/2018/06/word-image-225-300x147.png 300w" sizes="(max-width: 749px) 100vw, 749px" /></p>
<p>模板分配数据：</p>
<p><img loading="lazy" decoding="async" width="670" height="389" class="wp-image-7621" src="/wp-content/uploads/2018/06/word-image-226.png" srcset="/wp-content/uploads/2018/06/word-image-226.png 670w, /wp-content/uploads/2018/06/word-image-226-300x174.png 300w" sizes="(max-width: 670px) 100vw, 670px" /></p>
<h2>使用富文本编辑器完成文章的内容添加</h2>
<p>第一步：把课件中的相应的ueditor复制到网站根目录下面的插件目录plugin中</p>
<p><img loading="lazy" decoding="async" width="771" height="251" class="wp-image-7622" src="/wp-content/uploads/2018/06/word-image-227.png" srcset="/wp-content/uploads/2018/06/word-image-227.png 771w, /wp-content/uploads/2018/06/word-image-227-300x98.png 300w, /wp-content/uploads/2018/06/word-image-227-768x250.png 768w" sizes="(max-width: 771px) 100vw, 771px" /></p>
<p>第二步：引入核心js文件，并且给textarea 设置一个id=content</p>
<p><img loading="lazy" decoding="async" width="1304" height="496" class="wp-image-7623" src="/wp-content/uploads/2018/06/word-image-228.png" srcset="/wp-content/uploads/2018/06/word-image-228.png 1304w, /wp-content/uploads/2018/06/word-image-228-300x114.png 300w, /wp-content/uploads/2018/06/word-image-228-768x292.png 768w, /wp-content/uploads/2018/06/word-image-228-1024x389.png 1024w" sizes="(max-width: 1304px) 100vw, 1304px" /></p>
<p><img loading="lazy" decoding="async" width="1277" height="556" class="wp-image-7624" src="/wp-content/uploads/2018/06/word-image-229.png" srcset="/wp-content/uploads/2018/06/word-image-229.png 1277w, /wp-content/uploads/2018/06/word-image-229-300x131.png 300w, /wp-content/uploads/2018/06/word-image-229-768x334.png 768w, /wp-content/uploads/2018/06/word-image-229-1024x446.png 1024w" sizes="(max-width: 1277px) 100vw, 1277px" /></p>
<p>效果如下：</p>
<p><img loading="lazy" decoding="async" width="1040" height="418" class="wp-image-7625" src="/wp-content/uploads/2018/06/word-image-230.png" srcset="/wp-content/uploads/2018/06/word-image-230.png 1040w, /wp-content/uploads/2018/06/word-image-230-300x121.png 300w, /wp-content/uploads/2018/06/word-image-230-768x309.png 768w, /wp-content/uploads/2018/06/word-image-230-1024x412.png 1024w" sizes="(max-width: 1040px) 100vw, 1040px" /></p>
<h2>完成文章数据的入库</h2>
<p>第一步：设置表单name值</p>
<p><img loading="lazy" decoding="async" width="1315" height="712" class="wp-image-7626" src="/wp-content/uploads/2018/06/word-image-231.png" srcset="/wp-content/uploads/2018/06/word-image-231.png 1315w, /wp-content/uploads/2018/06/word-image-231-300x162.png 300w, /wp-content/uploads/2018/06/word-image-231-768x416.png 768w, /wp-content/uploads/2018/06/word-image-231-1024x554.png 1024w" sizes="(max-width: 1315px) 100vw, 1315px" /></p>
<p>第二步：在add方法中，完成数据的入库</p>
<p><img loading="lazy" decoding="async" width="935" height="563" class="wp-image-7627" src="/wp-content/uploads/2018/06/word-image-232.png" srcset="/wp-content/uploads/2018/06/word-image-232.png 935w, /wp-content/uploads/2018/06/word-image-232-300x180.png 300w, /wp-content/uploads/2018/06/word-image-232-768x462.png 768w" sizes="(max-width: 935px) 100vw, 935px" /></p>
<h2>4、使用验证器完成添加文章的验证</h2>
<h2>5、完成文章的图片上传</h2>
<h2>6、完成文章图片缩略图生成</h2>
<h1>十、完成文章的列表展示</h1>
<h2>数据展示</h2>
<h2>2、数据分页</h2>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7568.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TP5.0（四）添加文章、添加验证、图片上传、缩略图、图片预览、文章列表展示、分页、文章编辑、文章删除、XSS 攻击、Jquery-Validate 验证插件、钩子函数</title>
		<link>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7628.html</link>
					<comments>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7628.html#respond</comments>
		
		<dc:creator><![CDATA[Mr.Lee]]></dc:creator>
		<pubDate>Sat, 09 Jun 2018 00:41:37 +0000</pubDate>
				<category><![CDATA[TP5.0]]></category>
		<category><![CDATA[后台框架]]></category>
		<category><![CDATA[Jquery-Validate 验证插件]]></category>
		<category><![CDATA[XSS 攻击]]></category>
		<category><![CDATA[分页]]></category>
		<category><![CDATA[图片上传]]></category>
		<category><![CDATA[图片预览]]></category>
		<category><![CDATA[文章列表展示]]></category>
		<category><![CDATA[文章删除]]></category>
		<category><![CDATA[文章编辑]]></category>
		<category><![CDATA[添加文章]]></category>
		<category><![CDATA[添加验证]]></category>
		<category><![CDATA[缩略图]]></category>
		<category><![CDATA[钩子函数]]></category>
		<guid isPermaLink="false">/?p=7628</guid>

					<description><![CDATA[TP5第四天 一、完成文章的添加 完成文章模板的展示 第一步：修改left.html模板，加一个添加分类的链接 [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>TP5第四天</h1>
<h1>一、完成文章的添加</h1>
<h2>完成文章模板的展示</h2>
<p>第一步：修改left.html模板，加一个添加分类的链接地址</p>
<p><img loading="lazy" decoding="async" width="1262" height="365" class="wp-image-7629" src="/wp-content/uploads/2018/06/word-image-233.png" srcset="/wp-content/uploads/2018/06/word-image-233.png 1262w, /wp-content/uploads/2018/06/word-image-233-300x87.png 300w, /wp-content/uploads/2018/06/word-image-233-768x222.png 768w, /wp-content/uploads/2018/06/word-image-233-1024x296.png 1024w" sizes="(max-width: 1262px) 100vw, 1262px" /></p>
<p>第二步：在后台admin创建一个Article控制器，并建立一个add方法，完成文章的入库操作</p>
<p><img loading="lazy" decoding="async" width="749" height="368" class="wp-image-7630" src="/wp-content/uploads/2018/06/word-image-234.png" srcset="/wp-content/uploads/2018/06/word-image-234.png 749w, /wp-content/uploads/2018/06/word-image-234-300x147.png 300w" sizes="(max-width: 749px) 100vw, 749px" /></p>
<p>模板分配数据：</p>
<p><img loading="lazy" decoding="async" width="670" height="389" class="wp-image-7631" src="/wp-content/uploads/2018/06/word-image-235.png" srcset="/wp-content/uploads/2018/06/word-image-235.png 670w, /wp-content/uploads/2018/06/word-image-235-300x174.png 300w" sizes="(max-width: 670px) 100vw, 670px" /></p>
<h2>使用富文本编辑器完成文章的内容添加</h2>
<p>第一步：把课件中的相应的ueditor复制到网站根目录下面的插件目录plugin中</p>
<p><img loading="lazy" decoding="async" width="771" height="251" class="wp-image-7632" src="/wp-content/uploads/2018/06/word-image-236.png" srcset="/wp-content/uploads/2018/06/word-image-236.png 771w, /wp-content/uploads/2018/06/word-image-236-300x98.png 300w, /wp-content/uploads/2018/06/word-image-236-768x250.png 768w" sizes="(max-width: 771px) 100vw, 771px" /></p>
<p>第二步：引入核心js文件，并且给textarea 设置一个id=content</p>
<p><img loading="lazy" decoding="async" width="1304" height="496" class="wp-image-7633" src="/wp-content/uploads/2018/06/word-image-237.png" srcset="/wp-content/uploads/2018/06/word-image-237.png 1304w, /wp-content/uploads/2018/06/word-image-237-300x114.png 300w, /wp-content/uploads/2018/06/word-image-237-768x292.png 768w, /wp-content/uploads/2018/06/word-image-237-1024x389.png 1024w" sizes="(max-width: 1304px) 100vw, 1304px" /></p>
<p><img loading="lazy" decoding="async" width="1277" height="556" class="wp-image-7634" src="/wp-content/uploads/2018/06/word-image-238.png" srcset="/wp-content/uploads/2018/06/word-image-238.png 1277w, /wp-content/uploads/2018/06/word-image-238-300x131.png 300w, /wp-content/uploads/2018/06/word-image-238-768x334.png 768w, /wp-content/uploads/2018/06/word-image-238-1024x446.png 1024w" sizes="(max-width: 1277px) 100vw, 1277px" /></p>
<p>效果如下：</p>
<p><img loading="lazy" decoding="async" width="1040" height="418" class="wp-image-7635" src="/wp-content/uploads/2018/06/word-image-239.png" srcset="/wp-content/uploads/2018/06/word-image-239.png 1040w, /wp-content/uploads/2018/06/word-image-239-300x121.png 300w, /wp-content/uploads/2018/06/word-image-239-768x309.png 768w, /wp-content/uploads/2018/06/word-image-239-1024x412.png 1024w" sizes="(max-width: 1040px) 100vw, 1040px" /></p>
<h2>完成文章数据的入库</h2>
<p>第一步：设置表单name值</p>
<p><img loading="lazy" decoding="async" width="1315" height="712" class="wp-image-7636" src="/wp-content/uploads/2018/06/word-image-240.png" srcset="/wp-content/uploads/2018/06/word-image-240.png 1315w, /wp-content/uploads/2018/06/word-image-240-300x162.png 300w, /wp-content/uploads/2018/06/word-image-240-768x416.png 768w, /wp-content/uploads/2018/06/word-image-240-1024x554.png 1024w" sizes="(max-width: 1315px) 100vw, 1315px" /></p>
<p>第二步：在add方法中，完成数据的入库</p>
<p><img loading="lazy" decoding="async" width="935" height="563" class="wp-image-7637" src="/wp-content/uploads/2018/06/word-image-241.png" srcset="/wp-content/uploads/2018/06/word-image-241.png 935w, /wp-content/uploads/2018/06/word-image-241-300x180.png 300w, /wp-content/uploads/2018/06/word-image-241-768x462.png 768w" sizes="(max-width: 935px) 100vw, 935px" /></p>
<h2>使用验证器完成添加文章的验证</h2>
<p>在后台的admin的validate目录建立一个Article 的验证器</p>
<p><img loading="lazy" decoding="async" width="853" height="503" class="wp-image-7638" src="/wp-content/uploads/2018/06/word-image-242.png" srcset="/wp-content/uploads/2018/06/word-image-242.png 853w, /wp-content/uploads/2018/06/word-image-242-300x177.png 300w, /wp-content/uploads/2018/06/word-image-242-768x453.png 768w" sizes="(max-width: 853px) 100vw, 853px" /></p>
<p>添加文章的时候，调用验证器的对应场景进行验证：</p>
<p><img loading="lazy" decoding="async" width="977" height="645" class="wp-image-7639" src="/wp-content/uploads/2018/06/word-image-243.png" srcset="/wp-content/uploads/2018/06/word-image-243.png 977w, /wp-content/uploads/2018/06/word-image-243-300x198.png 300w, /wp-content/uploads/2018/06/word-image-243-768x507.png 768w" sizes="(max-width: 977px) 100vw, 977px" /></p>
<h2>完成文章的图片上传</h2>
<p>表单上传文件的要求：1、post提交 2、设置form的enctype=’multipart/form-data’</p>
<p><img loading="lazy" decoding="async" width="747" height="155" class="wp-image-7640" src="/wp-content/uploads/2018/06/word-image-244.png" srcset="/wp-content/uploads/2018/06/word-image-244.png 747w, /wp-content/uploads/2018/06/word-image-244-300x62.png 300w" sizes="(max-width: 747px) 100vw, 747px" /></p>
<p>设置上传文件的input标签</p>
<p><img loading="lazy" decoding="async" width="882" height="213" class="wp-image-7641" src="/wp-content/uploads/2018/06/word-image-245.png" srcset="/wp-content/uploads/2018/06/word-image-245.png 882w, /wp-content/uploads/2018/06/word-image-245-300x72.png 300w, /wp-content/uploads/2018/06/word-image-245-768x185.png 768w" sizes="(max-width: 882px) 100vw, 882px" /></p>
<p>控制器add方法处理上传文件的路径入库：</p>
<p><img loading="lazy" decoding="async" width="1076" height="650" class="wp-image-7642" src="/wp-content/uploads/2018/06/word-image-246.png" srcset="/wp-content/uploads/2018/06/word-image-246.png 1076w, /wp-content/uploads/2018/06/word-image-246-300x180.png 300w, /wp-content/uploads/2018/06/word-image-246-768x464.png 768w, /wp-content/uploads/2018/06/word-image-246-1024x619.png 1024w" sizes="(max-width: 1076px) 100vw, 1076px" /></p>
<p>数据库存储的路径形式如下：</p>
<p><img loading="lazy" decoding="async" width="490" height="44" class="wp-image-7643" src="/wp-content/uploads/2018/06/word-image-247.png" srcset="/wp-content/uploads/2018/06/word-image-247.png 490w, /wp-content/uploads/2018/06/word-image-247-300x27.png 300w" sizes="(max-width: 490px) 100vw, 490px" /></p>
<h2>6、完成文章图片缩略图生成</h2>
<p>在有文件上传成功的前提下，处理缩略图生成：</p>
<p><img loading="lazy" decoding="async" width="1208" height="664" class="wp-image-7644" src="/wp-content/uploads/2018/06/word-image-248.png" srcset="/wp-content/uploads/2018/06/word-image-248.png 1208w, /wp-content/uploads/2018/06/word-image-248-300x165.png 300w, /wp-content/uploads/2018/06/word-image-248-768x422.png 768w, /wp-content/uploads/2018/06/word-image-248-1024x563.png 1024w" sizes="(max-width: 1208px) 100vw, 1208px" /></p>
<p>注：函数thumb(width，height,缩放比例) ，缩放比例默认为1为等比例缩放，为2则是填充补白。</p>
<p>存储如下：</p>
<p><img loading="lazy" decoding="async" width="394" height="139" class="wp-image-7645" src="/wp-content/uploads/2018/06/word-image-249.png" srcset="/wp-content/uploads/2018/06/word-image-249.png 394w, /wp-content/uploads/2018/06/word-image-249-300x106.png 300w" sizes="(max-width: 394px) 100vw, 394px" /></p>
<p>数据库存储的路径：</p>
<p><img loading="lazy" decoding="async" width="548" height="53" class="wp-image-7646" src="/wp-content/uploads/2018/06/word-image-250.png" srcset="/wp-content/uploads/2018/06/word-image-250.png 548w, /wp-content/uploads/2018/06/word-image-250-300x29.png 300w" sizes="(max-width: 548px) 100vw, 548px" /></p>
<h2>实现上传图片的实时预览</h2>
<p>引入核心js文件：</p>
<p><img loading="lazy" decoding="async" width="765" height="177" class="wp-image-7647" src="/wp-content/uploads/2018/06/word-image-251.png" srcset="/wp-content/uploads/2018/06/word-image-251.png 765w, /wp-content/uploads/2018/06/word-image-251-300x69.png 300w" sizes="(max-width: 765px) 100vw, 765px" /></p>
<p><img loading="lazy" decoding="async" width="1115" height="287" class="wp-image-7648" src="/wp-content/uploads/2018/06/word-image-252.png" srcset="/wp-content/uploads/2018/06/word-image-252.png 1115w, /wp-content/uploads/2018/06/word-image-252-300x77.png 300w, /wp-content/uploads/2018/06/word-image-252-768x198.png 768w, /wp-content/uploads/2018/06/word-image-252-1024x264.png 1024w" sizes="(max-width: 1115px) 100vw, 1115px" /></p>
<p>在add.html模板文件设置预览的区域：<br />
<img loading="lazy" decoding="async" width="1205" height="362" class="wp-image-7649" src="/wp-content/uploads/2018/06/word-image-253.png" srcset="/wp-content/uploads/2018/06/word-image-253.png 1205w, /wp-content/uploads/2018/06/word-image-253-300x90.png 300w, /wp-content/uploads/2018/06/word-image-253-768x231.png 768w, /wp-content/uploads/2018/06/word-image-253-1024x308.png 1024w" sizes="(max-width: 1205px) 100vw, 1205px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="554" height="367" class="wp-image-7650" src="/wp-content/uploads/2018/06/word-image-254.png" srcset="/wp-content/uploads/2018/06/word-image-254.png 554w, /wp-content/uploads/2018/06/word-image-254-300x199.png 300w" sizes="(max-width: 554px) 100vw, 554px" /></p>
<h1>完成文章的列表展示</h1>
<h2>数据展示</h2>
<p>第一步：在后台admin的Article控制器中建立一个index方法，完成文章列表展示</p>
<p><img loading="lazy" decoding="async" width="1003" height="370" class="wp-image-7651" src="/wp-content/uploads/2018/06/word-image-255.png" srcset="/wp-content/uploads/2018/06/word-image-255.png 1003w, /wp-content/uploads/2018/06/word-image-255-300x111.png 300w, /wp-content/uploads/2018/06/word-image-255-768x283.png 768w" sizes="(max-width: 1003px) 100vw, 1003px" /></p>
<p>模板中index.php,循环输出</p>
<p><img loading="lazy" decoding="async" width="1287" height="516" class="wp-image-7652" src="/wp-content/uploads/2018/06/word-image-256.png" srcset="/wp-content/uploads/2018/06/word-image-256.png 1287w, /wp-content/uploads/2018/06/word-image-256-300x120.png 300w, /wp-content/uploads/2018/06/word-image-256-768x308.png 768w, /wp-content/uploads/2018/06/word-image-256-1024x411.png 1024w" sizes="(max-width: 1287px) 100vw, 1287px" /></p>
<h2>数据分页</h2>
<p>把模型的select方法改为paginate(每页显示条数)即可</p>
<p><img loading="lazy" decoding="async" width="976" height="366" class="wp-image-7653" src="/wp-content/uploads/2018/06/word-image-257.png" srcset="/wp-content/uploads/2018/06/word-image-257.png 976w, /wp-content/uploads/2018/06/word-image-257-300x113.png 300w, /wp-content/uploads/2018/06/word-image-257-768x288.png 768w" sizes="(max-width: 976px) 100vw, 976px" /></p>
<p>模板中输出分页页码：</p>
<p><img loading="lazy" decoding="async" width="1072" height="636" class="wp-image-7654" src="/wp-content/uploads/2018/06/word-image-258.png" srcset="/wp-content/uploads/2018/06/word-image-258.png 1072w, /wp-content/uploads/2018/06/word-image-258-300x178.png 300w, /wp-content/uploads/2018/06/word-image-258-768x456.png 768w, /wp-content/uploads/2018/06/word-image-258-1024x608.png 1024w" sizes="(max-width: 1072px) 100vw, 1072px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="581" height="249" class="wp-image-7655" src="/wp-content/uploads/2018/06/word-image-259.png" srcset="/wp-content/uploads/2018/06/word-image-259.png 581w, /wp-content/uploads/2018/06/word-image-259-300x129.png 300w" sizes="(max-width: 581px) 100vw, 581px" /></p>
<h1>完成文章编辑</h1>
<p>第一步：给编辑设置链接地址，携带文章的参数id</p>
<p><img loading="lazy" decoding="async" width="1304" height="235" class="wp-image-7656" src="/wp-content/uploads/2018/06/word-image-260.png" srcset="/wp-content/uploads/2018/06/word-image-260.png 1304w, /wp-content/uploads/2018/06/word-image-260-300x54.png 300w, /wp-content/uploads/2018/06/word-image-260-768x138.png 768w, /wp-content/uploads/2018/06/word-image-260-1024x185.png 1024w" sizes="(max-width: 1304px) 100vw, 1304px" /></p>
<p>第二步：建立一个upd方法完成数据回显到模板中</p>
<p><img loading="lazy" decoding="async" width="848" height="400" class="wp-image-7657" src="/wp-content/uploads/2018/06/word-image-261.png" srcset="/wp-content/uploads/2018/06/word-image-261.png 848w, /wp-content/uploads/2018/06/word-image-261-300x142.png 300w, /wp-content/uploads/2018/06/word-image-261-768x362.png 768w" sizes="(max-width: 848px) 100vw, 848px" /></p>
<p>第三步：模板中回显数据</p>
<p><img loading="lazy" decoding="async" width="1226" height="660" class="wp-image-7658" src="/wp-content/uploads/2018/06/word-image-262.png" srcset="/wp-content/uploads/2018/06/word-image-262.png 1226w, /wp-content/uploads/2018/06/word-image-262-300x162.png 300w, /wp-content/uploads/2018/06/word-image-262-768x413.png 768w, /wp-content/uploads/2018/06/word-image-262-1024x551.png 1024w" sizes="(max-width: 1226px) 100vw, 1226px" /></p>
<p><img loading="lazy" decoding="async" width="922" height="352" class="wp-image-7659" src="/wp-content/uploads/2018/06/word-image-263.png" srcset="/wp-content/uploads/2018/06/word-image-263.png 922w, /wp-content/uploads/2018/06/word-image-263-300x115.png 300w, /wp-content/uploads/2018/06/word-image-263-768x293.png 768w" sizes="(max-width: 922px) 100vw, 922px" /></p>
<p>效果：<br />
<img loading="lazy" decoding="async" width="516" height="399" class="wp-image-7660" src="/wp-content/uploads/2018/06/word-image-264.png" srcset="/wp-content/uploads/2018/06/word-image-264.png 516w, /wp-content/uploads/2018/06/word-image-264-300x232.png 300w" sizes="(max-width: 516px) 100vw, 516px" /></p>
<p>第四步：在upd方法中判断是否是post请求，完成数据的编辑入库</p>
<p><img loading="lazy" decoding="async" width="725" height="671" class="wp-image-7661" src="/wp-content/uploads/2018/06/word-image-265.png" srcset="/wp-content/uploads/2018/06/word-image-265.png 725w, /wp-content/uploads/2018/06/word-image-265-300x278.png 300w" sizes="(max-width: 725px) 100vw, 725px" /></p>
<p>可以设置Article模型自动维护时间戳：<br />
<img loading="lazy" decoding="async" width="504" height="236" class="wp-image-7662" src="/wp-content/uploads/2018/06/word-image-266.png" srcset="/wp-content/uploads/2018/06/word-image-266.png 504w, /wp-content/uploads/2018/06/word-image-266-300x140.png 300w" sizes="(max-width: 504px) 100vw, 504px" /></p>
<h1>完成文章删除</h1>
<p>第一步：给删除的链接地址设置链接，并且设置参数</p>
<p><img loading="lazy" decoding="async" width="1249" height="475" class="wp-image-7663" src="/wp-content/uploads/2018/06/word-image-267.png" srcset="/wp-content/uploads/2018/06/word-image-267.png 1249w, /wp-content/uploads/2018/06/word-image-267-300x114.png 300w, /wp-content/uploads/2018/06/word-image-267-768x292.png 768w, /wp-content/uploads/2018/06/word-image-267-1024x389.png 1024w" sizes="(max-width: 1249px) 100vw, 1249px" /></p>
<p>第二步：添加del方法完成删除</p>
<p><img loading="lazy" decoding="async" width="942" height="544" class="wp-image-7664" src="/wp-content/uploads/2018/06/word-image-268.png" srcset="/wp-content/uploads/2018/06/word-image-268.png 942w, /wp-content/uploads/2018/06/word-image-268-300x173.png 300w, /wp-content/uploads/2018/06/word-image-268-768x444.png 768w" sizes="(max-width: 942px) 100vw, 942px" /></p>
<h1>五、XSS攻击</h1>
<h2>xss介绍</h2>
<p><img loading="lazy" decoding="async" width="830" height="141" class="wp-image-7665" src="/wp-content/uploads/2018/06/word-image-269.png" srcset="/wp-content/uploads/2018/06/word-image-269.png 830w, /wp-content/uploads/2018/06/word-image-269-300x51.png 300w, /wp-content/uploads/2018/06/word-image-269-768x130.png 768w" sizes="(max-width: 830px) 100vw, 830px" /></p>
<p>如在输入框输入js代码：</p>
<p><img loading="lazy" decoding="async" width="551" height="67" class="wp-image-7666" src="/wp-content/uploads/2018/06/word-image-270.png" srcset="/wp-content/uploads/2018/06/word-image-270.png 551w, /wp-content/uploads/2018/06/word-image-270-300x36.png 300w" sizes="(max-width: 551px) 100vw, 551px" /></p>
<p>&lt;script&gt;</p>
<p>var cookie = document.cookie</p>
<p>//发送一个jsonp请求</p>
<p>&lt;/script&gt;</p>
<p>访问此标题的时候就会弹出1，从而达成攻击；</p>
<p><img loading="lazy" decoding="async" width="423" height="122" class="wp-image-7667" src="/wp-content/uploads/2018/06/word-image-271.png" srcset="/wp-content/uploads/2018/06/word-image-271.png 423w, /wp-content/uploads/2018/06/word-image-271-300x87.png 300w" sizes="(max-width: 423px) 100vw, 423px" /></p>
<h2>防止xss攻击（防止js攻击）</h2>
<h3>使用htmlspecialchars函数防止</h3>
<p>注： 百度富文本编辑器ueditor自动将危险的代码如js进行转化为实体符号。</p>
<p>htmlspecialchars函数的作用：将html标签符号转化为实体符号。</p>
<p>如：大于号“&gt;”会被转化为 “&amp;gt;”</p>
<p>如：大于号“&lt;”会被转化为 “&amp;lt;”</p>
<p>可以在配置文件config,添加全局的过滤函数：</p>
<p><img loading="lazy" decoding="async" width="933" height="232" class="wp-image-7668" src="/wp-content/uploads/2018/06/word-image-272.png" srcset="/wp-content/uploads/2018/06/word-image-272.png 933w, /wp-content/uploads/2018/06/word-image-272-300x75.png 300w, /wp-content/uploads/2018/06/word-image-272-768x191.png 768w" sizes="(max-width: 933px) 100vw, 933px" /></p>
<p>此种缺点：会把html和js代码的特殊符号都进行转移，不满足我们的要求。我们只需要转移js代码。如下所示：</p>
<p><img loading="lazy" decoding="async" width="1068" height="134" class="wp-image-7669" src="/wp-content/uploads/2018/06/word-image-273.png" srcset="/wp-content/uploads/2018/06/word-image-273.png 1068w, /wp-content/uploads/2018/06/word-image-273-300x38.png 300w, /wp-content/uploads/2018/06/word-image-273-768x96.png 768w, /wp-content/uploads/2018/06/word-image-273-1024x128.png 1024w" sizes="(max-width: 1068px) 100vw, 1068px" /></p>
<p>解决办法：</p>
<ol>
<li>不使用函数htmlspecialchars()进行处理，但可能会出现xss攻击。</li>
<li>使用htmlspecialchars()函数处理，页面的数据（富文本html）又不能正常显示出来，可以借助htmlspecialchars_decode()反转，把html实体符号转化为html标签，但这又可能会造成xss攻击。</li>
</ol>
<p>我们的希望是HTML可以正常显示，但是又不希望js代码被执行。</p>
<p>这时可以借助第三方防止xss攻击的插件如：HTMLPurifier，此插件会把浏览器提交过来的数据有选择性的过滤。只过滤危险的js代码，保留html代码，这就刚好满足我们的需求。</p>
<h3>使用插件HTMLPurifier防止</h3>
<p>复制防止xss攻击的库到项目extend目录中。</p>
<p><img loading="lazy" decoding="async" width="965" height="325" class="wp-image-7670" src="/wp-content/uploads/2018/06/word-image-274.png" srcset="/wp-content/uploads/2018/06/word-image-274.png 965w, /wp-content/uploads/2018/06/word-image-274-300x101.png 300w, /wp-content/uploads/2018/06/word-image-274-768x259.png 768w" sizes="(max-width: 965px) 100vw, 965px" /></p>
<p>把HTMLPurifier中的example.php文件中函数定义在common.php中，并且修改路径</p>
<p><img loading="lazy" decoding="async" width="966" height="455" class="wp-image-7671" src="/wp-content/uploads/2018/06/word-image-275.png" srcset="/wp-content/uploads/2018/06/word-image-275.png 966w, /wp-content/uploads/2018/06/word-image-275-300x141.png 300w, /wp-content/uploads/2018/06/word-image-275-768x362.png 768w" sizes="(max-width: 966px) 100vw, 966px" /></p>
<p>需要把函数名为removeXSS设置为tp的全局的默认过滤函数</p>
<p><img loading="lazy" decoding="async" width="928" height="290" class="wp-image-7672" src="/wp-content/uploads/2018/06/word-image-276.png" srcset="/wp-content/uploads/2018/06/word-image-276.png 928w, /wp-content/uploads/2018/06/word-image-276-300x94.png 300w, /wp-content/uploads/2018/06/word-image-276-768x240.png 768w" sizes="(max-width: 928px) 100vw, 928px" /></p>
<p>使用之后，只会把js代码进行过滤，保留html代码：</p>
<p><img loading="lazy" decoding="async" width="1001" height="163" class="wp-image-7673" src="/wp-content/uploads/2018/06/word-image-277.png" srcset="/wp-content/uploads/2018/06/word-image-277.png 1001w, /wp-content/uploads/2018/06/word-image-277-300x49.png 300w, /wp-content/uploads/2018/06/word-image-277-768x125.png 768w" sizes="(max-width: 1001px) 100vw, 1001px" /></p>
<p>显示就不会造成攻击，html正常显示：</p>
<p><img loading="lazy" decoding="async" width="913" height="159" class="wp-image-7674" src="/wp-content/uploads/2018/06/word-image-278.png" srcset="/wp-content/uploads/2018/06/word-image-278.png 913w, /wp-content/uploads/2018/06/word-image-278-300x52.png 300w, /wp-content/uploads/2018/06/word-image-278-768x134.png 768w" sizes="(max-width: 913px) 100vw, 913px" /></p>
<h1>扩展-验证插件jquery-validate的使用</h1>
<p>前端验证目的：减轻服务器压力，提高用户体验。</p>
<p>后端验证：主要保证数据的安全（不要信任浏览器携带过来的任何数据）</p>
<p>具体使用：<a href="/goto/6kfy" rel="nofollow">https://www.jianshu.com/p/e1d5f0dc2f5d</a></p>
<p>手册：</p>
<p><img loading="lazy" decoding="async" width="261" height="25" class="wp-image-7675" src="/wp-content/uploads/2018/06/word-image-279.png" /></p>
<h1>模型的事件（钩子）</h1>
<p>所谓的事件就类似于svn中的钩子一样，做一件事情都有前事件和后事情发生。</p>
<p>给表tp_category添加一个zhujian字段，目的是记录当前记录的主键值。</p>
<p><img loading="lazy" decoding="async" width="637" height="223" class="wp-image-7676" src="/wp-content/uploads/2018/06/word-image-280.png" srcset="/wp-content/uploads/2018/06/word-image-280.png 637w, /wp-content/uploads/2018/06/word-image-280-300x105.png 300w" sizes="(max-width: 637px) 100vw, 637px" /></p>
<p>让zhujian字段和cat_id的值保持一致，我们一把入库成功后要更新:</p>
<p>常规做法如下：</p>
<p><img loading="lazy" decoding="async" width="770" height="139" class="wp-image-7677" src="/wp-content/uploads/2018/06/word-image-281.png" srcset="/wp-content/uploads/2018/06/word-image-281.png 770w, /wp-content/uploads/2018/06/word-image-281-300x54.png 300w, /wp-content/uploads/2018/06/word-image-281-768x139.png 768w" sizes="(max-width: 770px) 100vw, 770px" /></p>
<p>但是不建议上面写，我们希望只把业务逻辑写在控制器，我们把数据有关的操作写在模型的事件中。</p>
<p>模型中注册事件：</p>
<p><img loading="lazy" decoding="async" width="993" height="349" class="wp-image-7678" src="/wp-content/uploads/2018/06/word-image-282.png" srcset="/wp-content/uploads/2018/06/word-image-282.png 993w, /wp-content/uploads/2018/06/word-image-282-300x105.png 300w, /wp-content/uploads/2018/06/word-image-282-768x270.png 768w" sizes="(max-width: 993px) 100vw, 993px" /></p>
<p>我们可以在模型中注册after_insert事件，即入库成功之后，把zhujian的字段和cat_id的保持一致。</p>
<p><img loading="lazy" decoding="async" width="1076" height="562" class="wp-image-7679" src="/wp-content/uploads/2018/06/word-image-283.png" srcset="/wp-content/uploads/2018/06/word-image-283.png 1076w, /wp-content/uploads/2018/06/word-image-283-300x157.png 300w, /wp-content/uploads/2018/06/word-image-283-768x401.png 768w, /wp-content/uploads/2018/06/word-image-283-1024x535.png 1024w" sizes="(max-width: 1076px) 100vw, 1076px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="698" height="34" class="wp-image-7680" src="/wp-content/uploads/2018/06/word-image-284.png" srcset="/wp-content/uploads/2018/06/word-image-284.png 698w, /wp-content/uploads/2018/06/word-image-284-300x15.png 300w" sizes="(max-width: 698px) 100vw, 698px" /></p>
<p>触发事件的流程：入库前事件&#8212;&gt;save()&#8212;-&gt;入库后的事件，</p>
<p>如果在入库前事件前返回false,则事件不会继续执行。</p>
<p><img loading="lazy" decoding="async" width="995" height="443" class="wp-image-7681" src="/wp-content/uploads/2018/06/word-image-285.png" srcset="/wp-content/uploads/2018/06/word-image-285.png 995w, /wp-content/uploads/2018/06/word-image-285-300x134.png 300w, /wp-content/uploads/2018/06/word-image-285-768x342.png 768w" sizes="(max-width: 995px) 100vw, 995px" /></p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7628.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TP5 商城（一）环境部署、数据表、后台首页、用户 CURD、Ajax 状态切换、后台登录、后台退出、后台防翻墙、RBAC</title>
		<link>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7682.html</link>
					<comments>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7682.html#respond</comments>
		
		<dc:creator><![CDATA[Mr.Lee]]></dc:creator>
		<pubDate>Sat, 09 Jun 2018 00:40:08 +0000</pubDate>
				<category><![CDATA[TP5.0]]></category>
		<category><![CDATA[TP5.0商城]]></category>
		<category><![CDATA[后台框架]]></category>
		<category><![CDATA[Ajax 状态切换]]></category>
		<category><![CDATA[RBAC]]></category>
		<category><![CDATA[后台登录]]></category>
		<category><![CDATA[后台退出]]></category>
		<category><![CDATA[后台防翻墙]]></category>
		<category><![CDATA[后台首页]]></category>
		<category><![CDATA[数据表]]></category>
		<category><![CDATA[环境部署]]></category>
		<category><![CDATA[用户 CURD]]></category>
		<guid isPermaLink="false">/?p=7682</guid>

					<description><![CDATA[商城实战第一天 电商介绍 电子商务模式介绍 现在的电子商务平台主要分为以下几种类型： B2C ：全称-Busi [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>商城实战第一天</h1>
<h1>电商介绍</h1>
<h2>电子商务模式介绍</h2>
<p>现在的电子商务平台主要分为以下几种类型：</p>
<ul>
<li>B2C ：全称-Business to Consumer , 即企业与消费者之间的电子商务。</li>
</ul>
<p>常见的有B2C网站有：天猫（商家入驻（实体店,保证金20W），需要营业许可证等资料）、京东(商家也可入驻)、当当网、唯品会、凡客、小米、华为、oppo等</p>
<ul>
<li>C2C: 全称-Consumer to Consumer，即消费者与消费者之间的电子商务。</li>
</ul>
<p>典型的C2C网站就是国内的淘宝（需要交保证金2000元左右），还有58同城，二手交易网站如：闲鱼二手交易网。</p>
<ul>
<li>O2O: 全称-Online to Offline,线上与线下相结合的电子商务。</li>
</ul>
<p>常见的有：苏宁、美团、国美、滴滴打车等。</p>
<ul>
<li>B2B：全称-Business to Business 即企业与企业之间的电子商务。（阿里妈妈）</li>
</ul>
<h2>常见的开源商城</h2>
<h3>（1）Ecshop</h3>
<p>ECShop是一款B2C独立网店系统，适合企业及个人快速构建个性化网上商店。系统是基于PHP语言及MYSQL数据库构架开发的跨平台开源程序。</p>
<p>网址：<a href="/goto/c9pa" rel="nofollow">http://www.ecshop.com/</a></p>
<p><img loading="lazy" decoding="async" width="1105" height="498" class="wp-image-7684" src="/wp-content/uploads/2018/06/word-image-286.png" srcset="/wp-content/uploads/2018/06/word-image-286.png 1105w, /wp-content/uploads/2018/06/word-image-286-300x135.png 300w, /wp-content/uploads/2018/06/word-image-286-768x346.png 768w, /wp-content/uploads/2018/06/word-image-286-1024x461.png 1024w" sizes="(max-width: 1105px) 100vw, 1105px" /></p>
<p>特点：开源、免费(个人学习使用没有任何问题)。但是企业使用用来盈利的话需要一定的授权费用（3000元左右）。</p>
<h3>（2）shopex</h3>
<p>网址：<a href="/goto/zptp" rel="nofollow">http://www.shopex.cn/</a></p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" width="1087" height="468" class="wp-image-7685" src="/wp-content/uploads/2018/06/word-image-287.png" srcset="/wp-content/uploads/2018/06/word-image-287.png 1087w, /wp-content/uploads/2018/06/word-image-287-300x129.png 300w, /wp-content/uploads/2018/06/word-image-287-768x331.png 768w, /wp-content/uploads/2018/06/word-image-287-1024x441.png 1024w" sizes="(max-width: 1087px) 100vw, 1087px" /></p>
<p>特点：商业版，代码是加密过的。</p>
<h3>（3）shopnc</h3>
<p>网址: <a href="/goto/ajli" rel="nofollow">http://www.shopnc.net/</a></p>
<p>演示地址： <a href="/goto/ubug" rel="nofollow">http://b2b2c.shopnctest.com/dema/shop/index.php</a></p>
<p><img loading="lazy" decoding="async" width="1104" height="416" class="wp-image-7686" src="/wp-content/uploads/2018/06/word-image-288.png" srcset="/wp-content/uploads/2018/06/word-image-288.png 1104w, /wp-content/uploads/2018/06/word-image-288-300x113.png 300w, /wp-content/uploads/2018/06/word-image-288-768x289.png 768w, /wp-content/uploads/2018/06/word-image-288-1024x386.png 1024w" sizes="(max-width: 1104px) 100vw, 1104px" /></p>
<p>特点：不开源、不免费</p>
<p>小结：</p>
<p>开源不代表免费，可以自己学习研究使用，但是以盈利为目的使用需要交一定的授权费用。</p>
<h2>安装Ecshop开源商城</h2>
<p>现在的Ecshop主要有以下两个版本：</p>
<ul>
<li>3.0版本：需要php5.4版本以上</li>
<li>2.7版本：需要在php5.3以下（如：phpstudy集成环境进行php降级），当然5.4、5、5版本也是可以的，只是需要修改部分代码。</li>
</ul>
<p>这里建议安装Ecshop的兼容版本，已经兼容各个php版本。</p>
<p><img loading="lazy" decoding="async" width="246" height="27" class="wp-image-7687" src="/wp-content/uploads/2018/06/word-image-289.png" /></p>
<h3>域名部署访问 ecshop</h3>
<p>一般把第三方开源项目部署在自己的机子上面域名前建议加个vendor,如：vendor.shop.com。明确知道这个程序是第三方程序。本地自己开发的项目话建议使用local进行开头，如:local.shop.com。</p>
<p>步骤1：把ecshop开源程序的所有的文件复制到我们的项目目录</p>
<p><img loading="lazy" decoding="async" width="841" height="424" class="wp-image-7688" src="/wp-content/uploads/2018/06/word-image-290.png" srcset="/wp-content/uploads/2018/06/word-image-290.png 841w, /wp-content/uploads/2018/06/word-image-290-300x151.png 300w, /wp-content/uploads/2018/06/word-image-290-768x387.png 768w" sizes="(max-width: 841px) 100vw, 841px" /></p>
<p>步骤2：配置虚拟主机，如域名为上面的vendor.ecshop.com</p>
<ol>
<li>phpstudy设置虚拟主机</li>
<li>设置host文件映射</li>
<li>重启phpstudy</li>
</ol>
<p>步骤3：输入域名进行安装配置</p>
<ol>
<li>勾选</li>
</ol>
<p><img loading="lazy" decoding="async" width="1088" height="661" class="wp-image-7689" src="/wp-content/uploads/2018/06/word-image-291.png" srcset="/wp-content/uploads/2018/06/word-image-291.png 1088w, /wp-content/uploads/2018/06/word-image-291-300x182.png 300w, /wp-content/uploads/2018/06/word-image-291-768x467.png 768w, /wp-content/uploads/2018/06/word-image-291-1024x622.png 1024w" sizes="(max-width: 1088px) 100vw, 1088px" /></p>
<p>b、配置系统</p>
<p><img loading="lazy" decoding="async" width="861" height="267" class="wp-image-7690" src="/wp-content/uploads/2018/06/word-image-292.png" srcset="/wp-content/uploads/2018/06/word-image-292.png 861w, /wp-content/uploads/2018/06/word-image-292-300x93.png 300w, /wp-content/uploads/2018/06/word-image-292-768x238.png 768w" sizes="(max-width: 861px) 100vw, 861px" /></p>
<p>c、配置数据库的信息</p>
<p><img loading="lazy" decoding="async" width="777" height="650" class="wp-image-7691" src="/wp-content/uploads/2018/06/word-image-293.png" srcset="/wp-content/uploads/2018/06/word-image-293.png 777w, /wp-content/uploads/2018/06/word-image-293-300x251.png 300w, /wp-content/uploads/2018/06/word-image-293-768x642.png 768w" sizes="(max-width: 777px) 100vw, 777px" /> <img loading="lazy" decoding="async" width="834" height="242" class="wp-image-7692" src="/wp-content/uploads/2018/06/word-image-294.png" srcset="/wp-content/uploads/2018/06/word-image-294.png 834w, /wp-content/uploads/2018/06/word-image-294-300x87.png 300w, /wp-content/uploads/2018/06/word-image-294-768x223.png 768w" sizes="(max-width: 834px) 100vw, 834px" /></p>
<p>访问ecshop前台：<a href="/goto/z1k0" rel="nofollow">http:/域名/</a></p>
<p>访问ecshop后台：<a href="/goto/1knx" rel="nofollow">http:/域名/admin/</a></p>
<p><img loading="lazy" decoding="async" width="781" height="382" class="wp-image-7693" src="/wp-content/uploads/2018/06/word-image-295.png" srcset="/wp-content/uploads/2018/06/word-image-295.png 781w, /wp-content/uploads/2018/06/word-image-295-300x147.png 300w, /wp-content/uploads/2018/06/word-image-295-768x376.png 768w" sizes="(max-width: 781px) 100vw, 781px" /></p>
<h1>部署tp5商城项目环境</h1>
<h2>部署虚拟主机</h2>
<p>三步：</p>
<p>步骤1：把tp5项目程序复制指定虚拟目录</p>
<p>步骤2：使用phpstudy配置域名如为：<a href="/goto/x9uh" rel="nofollow">www.php15shop.com</a>，虚拟目录需要绑定到public目录下面</p>
<p>步骤3：设置hosts文件映射</p>
<p>最后访问如下，说明配置成功：</p>
<p><img loading="lazy" decoding="async" width="693" height="379" class="wp-image-7694" src="/wp-content/uploads/2018/06/word-image-296.png" srcset="/wp-content/uploads/2018/06/word-image-296.png 693w, /wp-content/uploads/2018/06/word-image-296-300x164.png 300w" sizes="(max-width: 693px) 100vw, 693px" /></p>
<h2>导入商城项目所有数据表</h2>
<p>建议使用navicat可视化工具进行完成，找到对应的sql文件，进行导入。</p>
<p>要先创建一个数据库，如php15shop</p>
<p><img loading="lazy" decoding="async" width="736" height="210" class="wp-image-7695" src="/wp-content/uploads/2018/06/word-image-297.png" srcset="/wp-content/uploads/2018/06/word-image-297.png 736w, /wp-content/uploads/2018/06/word-image-297-300x86.png 300w" sizes="(max-width: 736px) 100vw, 736px" /></p>
<p>&nbsp;</p>
<p>每张表的字段信息可以参考数据库文档：</p>
<p><img loading="lazy" decoding="async" width="652" height="66" class="wp-image-7696" src="/wp-content/uploads/2018/06/word-image-298.png" srcset="/wp-content/uploads/2018/06/word-image-298.png 652w, /wp-content/uploads/2018/06/word-image-298-300x30.png 300w" sizes="(max-width: 652px) 100vw, 652px" /></p>
<h2>项目前的一些配置</h2>
<p>我们可以先把数据库、控制器后缀、静态资源目录等一些基本配置先定义好。</p>
<ul>
<li>数据库配置</li>
</ul>
<p><img loading="lazy" decoding="async" width="935" height="629" class="wp-image-7697" src="/wp-content/uploads/2018/06/word-image-299.png" srcset="/wp-content/uploads/2018/06/word-image-299.png 935w, /wp-content/uploads/2018/06/word-image-299-300x202.png 300w, /wp-content/uploads/2018/06/word-image-299-768x517.png 768w" sizes="(max-width: 935px) 100vw, 935px" /></p>
<ul>
<li>控制器后缀</li>
</ul>
<p><img loading="lazy" decoding="async" width="798" height="303" class="wp-image-7698" src="/wp-content/uploads/2018/06/word-image-300.png" srcset="/wp-content/uploads/2018/06/word-image-300.png 798w, /wp-content/uploads/2018/06/word-image-300-300x114.png 300w, /wp-content/uploads/2018/06/word-image-300-768x292.png 768w" sizes="(max-width: 798px) 100vw, 798px" /></p>
<ul>
<li>配置静态资源路径，把后台静态资源放到相应的目录,配置后台密码加密验salt</li>
</ul>
<p><img loading="lazy" decoding="async" width="767" height="329" class="wp-image-7699" src="/wp-content/uploads/2018/06/word-image-301.png" srcset="/wp-content/uploads/2018/06/word-image-301.png 767w, /wp-content/uploads/2018/06/word-image-301-300x129.png 300w" sizes="(max-width: 767px) 100vw, 767px" /></p>
<ul>
<li>先设置默认模块为admin、开发前台时（项目上线）设置为home</li>
</ul>
<p><img loading="lazy" decoding="async" width="785" height="161" class="wp-image-7700" src="/wp-content/uploads/2018/06/word-image-302.png" srcset="/wp-content/uploads/2018/06/word-image-302.png 785w, /wp-content/uploads/2018/06/word-image-302-300x62.png 300w, /wp-content/uploads/2018/06/word-image-302-768x158.png 768w" sizes="(max-width: 785px) 100vw, 785px" /></p>
<ul>
<li>并且开启调试模式,页面trace调试，看到错误的详细信息</li>
</ul>
<p><img loading="lazy" decoding="async" width="866" height="277" class="wp-image-7701" src="/wp-content/uploads/2018/06/word-image-303.png" srcset="/wp-content/uploads/2018/06/word-image-303.png 866w, /wp-content/uploads/2018/06/word-image-303-300x96.png 300w, /wp-content/uploads/2018/06/word-image-303-768x246.png 768w" sizes="(max-width: 866px) 100vw, 866px" /></p>
<p>开启页面trace调试，页面右下角多处一个图标。</p>
<p><img loading="lazy" decoding="async" width="153" height="49" class="wp-image-7702" src="/wp-content/uploads/2018/06/word-image-304.png" srcset="/wp-content/uploads/2018/06/word-image-304.png 153w, /wp-content/uploads/2018/06/word-image-304-150x49.png 150w" sizes="(max-width: 153px) 100vw, 153px" /></p>
<ul>
<li>开启模型获取数据返回关联数组的配置</li>
</ul>
<p><img loading="lazy" decoding="async" width="901" height="177" class="wp-image-7703" src="/wp-content/uploads/2018/06/word-image-305.png" srcset="/wp-content/uploads/2018/06/word-image-305.png 901w, /wp-content/uploads/2018/06/word-image-305-300x59.png 300w, /wp-content/uploads/2018/06/word-image-305-768x151.png 768w" sizes="(max-width: 901px) 100vw, 901px" /></p>
<ul>
<li>修改重写文件.htaccess隐藏单一入口文件访问</li>
</ul>
<p>这里需要在httpd.conf开启rewrite重写模块，和在虚拟主机中把 AllowOverride None改为 AllowOverride All，这两步在安装phpstudy的时候和配置虚拟主机时其已经帮我们设置好了。</p>
<p>只需要改修改重写文件.htaccess，前面加个问号?</p>
<h1>三、搭建后台首页</h1>
<p><img loading="lazy" decoding="async" width="844" height="270" class="wp-image-7704" src="/wp-content/uploads/2018/06/word-image-306.png" srcset="/wp-content/uploads/2018/06/word-image-306.png 844w, /wp-content/uploads/2018/06/word-image-306-300x96.png 300w, /wp-content/uploads/2018/06/word-image-306-768x246.png 768w" sizes="(max-width: 844px) 100vw, 844px" /></p>
<p>步骤1：在后台admin建立一个index控制器，分别建立top、main、left、index</p>
<p><img loading="lazy" decoding="async" width="774" height="613" class="wp-image-7705" src="/wp-content/uploads/2018/06/word-image-307.png" srcset="/wp-content/uploads/2018/06/word-image-307.png 774w, /wp-content/uploads/2018/06/word-image-307-300x238.png 300w, /wp-content/uploads/2018/06/word-image-307-768x608.png 768w" sizes="(max-width: 774px) 100vw, 774px" /></p>
<p>步骤2：复制后台指定的模板到指定的目录，并且修改每个模板的静态资源路径</p>
<p><img loading="lazy" decoding="async" width="1264" height="457" class="wp-image-7706" src="/wp-content/uploads/2018/06/word-image-308.png" srcset="/wp-content/uploads/2018/06/word-image-308.png 1264w, /wp-content/uploads/2018/06/word-image-308-300x108.png 300w, /wp-content/uploads/2018/06/word-image-308-768x278.png 768w, /wp-content/uploads/2018/06/word-image-308-1024x370.png 1024w" sizes="(max-width: 1264px) 100vw, 1264px" /></p>
<p>访问效果：</p>
<p><img loading="lazy" decoding="async" width="744" height="432" class="wp-image-7707" src="/wp-content/uploads/2018/06/word-image-309.png" srcset="/wp-content/uploads/2018/06/word-image-309.png 744w, /wp-content/uploads/2018/06/word-image-309-300x174.png 300w" sizes="(max-width: 744px) 100vw, 744px" /></p>
<h1>四、用户表的CURD操作</h1>
<h3>完成用户的添加功能</h3>
<p>步骤1：在后台创建User控制器，并建立一个add方法输出模板内容</p>
<p><img loading="lazy" decoding="async" width="794" height="286" class="wp-image-7708" src="/wp-content/uploads/2018/06/word-image-310.png" srcset="/wp-content/uploads/2018/06/word-image-310.png 794w, /wp-content/uploads/2018/06/word-image-310-300x108.png 300w, /wp-content/uploads/2018/06/word-image-310-768x277.png 768w" sizes="(max-width: 794px) 100vw, 794px" /></p>
<p>步骤2：修改add.html模板的name名称</p>
<p><img loading="lazy" decoding="async" width="1286" height="622" class="wp-image-7709" src="/wp-content/uploads/2018/06/word-image-311.png" srcset="/wp-content/uploads/2018/06/word-image-311.png 1286w, /wp-content/uploads/2018/06/word-image-311-300x145.png 300w, /wp-content/uploads/2018/06/word-image-311-768x371.png 768w, /wp-content/uploads/2018/06/word-image-311-1024x495.png 1024w" sizes="(max-width: 1286px) 100vw, 1286px" /></p>
<p>步骤3：定义当前表的验证器</p>
<p><img loading="lazy" decoding="async" width="1209" height="714" class="wp-image-7710" src="/wp-content/uploads/2018/06/word-image-312.png" srcset="/wp-content/uploads/2018/06/word-image-312.png 1209w, /wp-content/uploads/2018/06/word-image-312-300x177.png 300w, /wp-content/uploads/2018/06/word-image-312-768x454.png 768w, /wp-content/uploads/2018/06/word-image-312-1024x605.png 1024w" sizes="(max-width: 1209px) 100vw, 1209px" /></p>
<p>步骤4：在模型中定义前入库的钩子事件，完成密码字段的加密</p>
<p><img loading="lazy" decoding="async" width="1101" height="436" class="wp-image-7711" src="/wp-content/uploads/2018/06/word-image-313.png" srcset="/wp-content/uploads/2018/06/word-image-313.png 1101w, /wp-content/uploads/2018/06/word-image-313-300x119.png 300w, /wp-content/uploads/2018/06/word-image-313-768x304.png 768w, /wp-content/uploads/2018/06/word-image-313-1024x406.png 1024w" sizes="(max-width: 1101px) 100vw, 1101px" /></p>
<p>步骤5：控制器完成验证入库操作</p>
<p><img loading="lazy" decoding="async" width="1191" height="699" class="wp-image-7712" src="/wp-content/uploads/2018/06/word-image-314.png" srcset="/wp-content/uploads/2018/06/word-image-314.png 1191w, /wp-content/uploads/2018/06/word-image-314-300x176.png 300w, /wp-content/uploads/2018/06/word-image-314-768x451.png 768w, /wp-content/uploads/2018/06/word-image-314-1024x601.png 1024w" sizes="(max-width: 1191px) 100vw, 1191px" /></p>
<h3>完成用户列表功能及分页</h3>
<p>步骤1：在后台User控制器建立一个index方法，取出所有的用户数据，并分配到模板中</p>
<p><img loading="lazy" decoding="async" width="831" height="395" class="wp-image-7713" src="/wp-content/uploads/2018/06/word-image-315.png" srcset="/wp-content/uploads/2018/06/word-image-315.png 831w, /wp-content/uploads/2018/06/word-image-315-300x143.png 300w, /wp-content/uploads/2018/06/word-image-315-768x365.png 768w" sizes="(max-width: 831px) 100vw, 831px" /></p>
<p>步骤2：模板遍历数据</p>
<p><img loading="lazy" decoding="async" width="1039" height="601" class="wp-image-7714" src="/wp-content/uploads/2018/06/word-image-316.png" srcset="/wp-content/uploads/2018/06/word-image-316.png 1039w, /wp-content/uploads/2018/06/word-image-316-300x174.png 300w, /wp-content/uploads/2018/06/word-image-316-768x444.png 768w, /wp-content/uploads/2018/06/word-image-316-1024x592.png 1024w" sizes="(max-width: 1039px) 100vw, 1039px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="941" height="192" class="wp-image-7715" src="/wp-content/uploads/2018/06/word-image-317.png" srcset="/wp-content/uploads/2018/06/word-image-317.png 941w, /wp-content/uploads/2018/06/word-image-317-300x61.png 300w, /wp-content/uploads/2018/06/word-image-317-768x157.png 768w" sizes="(max-width: 941px) 100vw, 941px" /></p>
<h3>完成用户的编辑功能</h3>
<p>编辑用户的时候，密码选项需要考虑两种情况：</p>
<p>①如密码和确认密码都为空，说明用户不想修改密码，则保留原来的密码。</p>
<p>②如果两个密码有一个不为空，说明用户想修改密码，则必须要求用户两次密码一致。</p>
<p>代码如下：</p>
<p>步骤1：给编辑的设置一个链接地址，携带一个主键值</p>
<p><img loading="lazy" decoding="async" width="1260" height="305" class="wp-image-7716" src="/wp-content/uploads/2018/06/word-image-318.png" srcset="/wp-content/uploads/2018/06/word-image-318.png 1260w, /wp-content/uploads/2018/06/word-image-318-300x73.png 300w, /wp-content/uploads/2018/06/word-image-318-768x186.png 768w, /wp-content/uploads/2018/06/word-image-318-1024x248.png 1024w" sizes="(max-width: 1260px) 100vw, 1260px" /></p>
<p>步骤2：使用jquery-validate对密码字段进行验证</p>
<p><img loading="lazy" decoding="async" width="1008" height="318" class="wp-image-7717" src="/wp-content/uploads/2018/06/word-image-319.png" srcset="/wp-content/uploads/2018/06/word-image-319.png 1008w, /wp-content/uploads/2018/06/word-image-319-300x95.png 300w, /wp-content/uploads/2018/06/word-image-319-768x242.png 768w" sizes="(max-width: 1008px) 100vw, 1008px" /></p>
<p>规则如下：</p>
<p><img loading="lazy" decoding="async" width="841" height="711" class="wp-image-7718" src="/wp-content/uploads/2018/06/word-image-320.png" srcset="/wp-content/uploads/2018/06/word-image-320.png 841w, /wp-content/uploads/2018/06/word-image-320-300x254.png 300w, /wp-content/uploads/2018/06/word-image-320-768x649.png 768w" sizes="(max-width: 841px) 100vw, 841px" /> <img loading="lazy" decoding="async" width="590" height="144" class="wp-image-7719" src="/wp-content/uploads/2018/06/word-image-321.png" srcset="/wp-content/uploads/2018/06/word-image-321.png 590w, /wp-content/uploads/2018/06/word-image-321-300x73.png 300w" sizes="(max-width: 590px) 100vw, 590px" /></p>
<p>注：要修改style.css文件样式，因为有样式冲突</p>
<p><img loading="lazy" decoding="async" width="1138" height="179" class="wp-image-7720" src="/wp-content/uploads/2018/06/word-image-322.png" srcset="/wp-content/uploads/2018/06/word-image-322.png 1138w, /wp-content/uploads/2018/06/word-image-322-300x47.png 300w, /wp-content/uploads/2018/06/word-image-322-768x121.png 768w, /wp-content/uploads/2018/06/word-image-322-1024x161.png 1024w" sizes="(max-width: 1138px) 100vw, 1138px" /></p>
<p>设置upd.html模板内容回显数据：</p>
<p><img loading="lazy" decoding="async" width="1270" height="671" class="wp-image-7721" src="/wp-content/uploads/2018/06/word-image-323.png" srcset="/wp-content/uploads/2018/06/word-image-323.png 1270w, /wp-content/uploads/2018/06/word-image-323-300x159.png 300w, /wp-content/uploads/2018/06/word-image-323-768x406.png 768w, /wp-content/uploads/2018/06/word-image-323-1024x541.png 1024w" sizes="(max-width: 1270px) 100vw, 1270px" /></p>
<p>步骤3：upd方法中完成编辑的验证编辑入库</p>
<p><img loading="lazy" decoding="async" width="1160" height="520" class="wp-image-7722" src="/wp-content/uploads/2018/06/word-image-324.png" srcset="/wp-content/uploads/2018/06/word-image-324.png 1160w, /wp-content/uploads/2018/06/word-image-324-300x134.png 300w, /wp-content/uploads/2018/06/word-image-324-768x344.png 768w, /wp-content/uploads/2018/06/word-image-324-1024x459.png 1024w" sizes="(max-width: 1160px) 100vw, 1160px" /></p>
<p>同时修改编辑场景的验证器：</p>
<p><img loading="lazy" decoding="async" width="1002" height="485" class="wp-image-7723" src="/wp-content/uploads/2018/06/word-image-325.png" srcset="/wp-content/uploads/2018/06/word-image-325.png 1002w, /wp-content/uploads/2018/06/word-image-325-300x145.png 300w, /wp-content/uploads/2018/06/word-image-325-768x372.png 768w" sizes="(max-width: 1002px) 100vw, 1002px" /></p>
<h3>ajax控制用户的登录状态</h3>
<p>步骤1：先给标签加一个a标签，并且阻止默认行为，同时加一个is_active和user_id属性，目的是获取当前记录的状态值和主键值，并且绑定类名为changeActive。</p>
<p><img loading="lazy" decoding="async" width="1197" height="259" class="wp-image-7724" src="/wp-content/uploads/2018/06/word-image-326.png" srcset="/wp-content/uploads/2018/06/word-image-326.png 1197w, /wp-content/uploads/2018/06/word-image-326-300x65.png 300w, /wp-content/uploads/2018/06/word-image-326-768x166.png 768w, /wp-content/uploads/2018/06/word-image-326-1024x222.png 1024w" sizes="(max-width: 1197px) 100vw, 1197px" /></p>
<p>步骤2：给class=changeActive 绑定单击事件，发送ajax请求</p>
<p><img loading="lazy" decoding="async" width="1244" height="493" class="wp-image-7725" src="/wp-content/uploads/2018/06/word-image-327.png" srcset="/wp-content/uploads/2018/06/word-image-327.png 1244w, /wp-content/uploads/2018/06/word-image-327-300x119.png 300w, /wp-content/uploads/2018/06/word-image-327-768x304.png 768w, /wp-content/uploads/2018/06/word-image-327-1024x406.png 1024w" sizes="(max-width: 1244px) 100vw, 1244px" /></p>
<p>步骤3：在User控制器建立一个ajaxChangeActive方法，完成状态的更改</p>
<p><img loading="lazy" decoding="async" width="831" height="646" class="wp-image-7726" src="/wp-content/uploads/2018/06/word-image-328.png" srcset="/wp-content/uploads/2018/06/word-image-328.png 831w, /wp-content/uploads/2018/06/word-image-328-300x233.png 300w, /wp-content/uploads/2018/06/word-image-328-768x597.png 768w" sizes="(max-width: 831px) 100vw, 831px" /></p>
<p>注意：由于更改状态值的时候会触发编辑的前钩子，这时候没有携带密码字段前钩子会直接报错，解决办法：对前钩子有没有密码字段进行isset判断即可:</p>
<p><img loading="lazy" decoding="async" width="971" height="482" class="wp-image-7727" src="/wp-content/uploads/2018/06/word-image-329.png" srcset="/wp-content/uploads/2018/06/word-image-329.png 971w, /wp-content/uploads/2018/06/word-image-329-300x149.png 300w, /wp-content/uploads/2018/06/word-image-329-768x381.png 768w" sizes="(max-width: 971px) 100vw, 971px" /></p>
<p>提示：调试ajax的时候，务必要打开控制器network进行调试。可以打开response选项看报啥错，这样可以快速定位到错误的原因。</p>
<h1>五、完成后台用户登录|退出|防翻墙功能</h1>
<h2>完成后台登录功能</h2>
<p>步骤1：在后台建立一个Public控制器，并建立一个login方法，输出登录模板同时，同时完成登录的功能实现</p>
<p><img loading="lazy" decoding="async" width="1135" height="651" class="wp-image-7728" src="/wp-content/uploads/2018/06/word-image-330.png" srcset="/wp-content/uploads/2018/06/word-image-330.png 1135w, /wp-content/uploads/2018/06/word-image-330-300x172.png 300w, /wp-content/uploads/2018/06/word-image-330-768x441.png 768w, /wp-content/uploads/2018/06/word-image-330-1024x587.png 1024w" sizes="(max-width: 1135px) 100vw, 1135px" /></p>
<p>同时在User模型中，定义一个checkUser的方法，检测用户名和密码是否相等</p>
<p><img loading="lazy" decoding="async" width="1030" height="529" class="wp-image-7729" src="/wp-content/uploads/2018/06/word-image-331.png" srcset="/wp-content/uploads/2018/06/word-image-331.png 1030w, /wp-content/uploads/2018/06/word-image-331-300x154.png 300w, /wp-content/uploads/2018/06/word-image-331-768x394.png 768w, /wp-content/uploads/2018/06/word-image-331-1024x526.png 1024w" sizes="(max-width: 1030px) 100vw, 1030px" /></p>
<p>步骤2：修改login.html模板内容，显示验证码</p>
<p><img loading="lazy" decoding="async" width="1267" height="689" class="wp-image-7730" src="/wp-content/uploads/2018/06/word-image-332.png" srcset="/wp-content/uploads/2018/06/word-image-332.png 1267w, /wp-content/uploads/2018/06/word-image-332-300x163.png 300w, /wp-content/uploads/2018/06/word-image-332-768x418.png 768w, /wp-content/uploads/2018/06/word-image-332-1024x557.png 1024w" sizes="(max-width: 1267px) 100vw, 1267px" /> <img loading="lazy" decoding="async" width="1167" height="425" class="wp-image-7731" src="/wp-content/uploads/2018/06/word-image-333.png" srcset="/wp-content/uploads/2018/06/word-image-333.png 1167w, /wp-content/uploads/2018/06/word-image-333-300x109.png 300w, /wp-content/uploads/2018/06/word-image-333-768x280.png 768w, /wp-content/uploads/2018/06/word-image-333-1024x373.png 1024w" sizes="(max-width: 1167px) 100vw, 1167px" /></p>
<p>步骤3：在验证器中定义登录场景的验证规则</p>
<p><img loading="lazy" decoding="async" width="1264" height="690" class="wp-image-7732" src="/wp-content/uploads/2018/06/word-image-334.png" srcset="/wp-content/uploads/2018/06/word-image-334.png 1264w, /wp-content/uploads/2018/06/word-image-334-300x164.png 300w, /wp-content/uploads/2018/06/word-image-334-768x419.png 768w, /wp-content/uploads/2018/06/word-image-334-1024x559.png 1024w" sizes="(max-width: 1264px) 100vw, 1264px" /></p>
<p>登录成功，在top.html中回显用户名</p>
<p><img loading="lazy" decoding="async" width="1024" height="214" class="wp-image-7733" src="/wp-content/uploads/2018/06/word-image-335.png" srcset="/wp-content/uploads/2018/06/word-image-335.png 1024w, /wp-content/uploads/2018/06/word-image-335-300x63.png 300w, /wp-content/uploads/2018/06/word-image-335-768x161.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></p>
<h2>完成后台退出功能</h2>
<p>步骤1：在后台Public控制器建立一个logout的退出方法</p>
<p><img loading="lazy" decoding="async" width="831" height="296" class="wp-image-7734" src="/wp-content/uploads/2018/06/word-image-336.png" srcset="/wp-content/uploads/2018/06/word-image-336.png 831w, /wp-content/uploads/2018/06/word-image-336-300x107.png 300w, /wp-content/uploads/2018/06/word-image-336-768x274.png 768w" sizes="(max-width: 831px) 100vw, 831px" /></p>
<h2>防用户翻墙</h2>
<p>防翻墙思想：建立一个父控制器如：CommonController,在此控制器的构造函数中做session的判断，其他需要进行验证session的控制器就继承此公共控制器即可防止翻墙，某些控制器不需要session判断则不继承即可。（如:PublicController）</p>
<p><img loading="lazy" decoding="async" width="991" height="358" class="wp-image-7735" src="/wp-content/uploads/2018/06/word-image-337.png" srcset="/wp-content/uploads/2018/06/word-image-337.png 991w, /wp-content/uploads/2018/06/word-image-337-300x108.png 300w, /wp-content/uploads/2018/06/word-image-337-768x277.png 768w" sizes="(max-width: 991px) 100vw, 991px" /></p>
<p>其中Index 和User控制器需要继承Common，public不需要继承</p>
<p><img loading="lazy" decoding="async" width="831" height="164" class="wp-image-7736" src="/wp-content/uploads/2018/06/word-image-338.png" srcset="/wp-content/uploads/2018/06/word-image-338.png 831w, /wp-content/uploads/2018/06/word-image-338-300x59.png 300w, /wp-content/uploads/2018/06/word-image-338-768x152.png 768w" sizes="(max-width: 831px) 100vw, 831px" /> <img loading="lazy" decoding="async" width="834" height="172" class="wp-image-7737" src="/wp-content/uploads/2018/06/word-image-339.png" srcset="/wp-content/uploads/2018/06/word-image-339.png 834w, /wp-content/uploads/2018/06/word-image-339-300x62.png 300w, /wp-content/uploads/2018/06/word-image-339-768x158.png 768w" sizes="(max-width: 834px) 100vw, 834px" /></p>
<h1>六、RBAC权限控制</h1>
<h2>RBAC介绍</h2>
<p>RBAC: Role Based Access Controller ,即基于角色的访问权限控制。</p>
<p>简单的说,用户登录可以属于不同的角色，不同的角色拥有的后台访问菜单权限也不一样。</p>
<p>如：</p>
<p>如下面的每个菜单就是一个权限。</p>
<p><img loading="lazy" decoding="async" width="190" height="124" class="wp-image-7738" src="/wp-content/uploads/2018/06/word-image-340.png" /></p>
<p>后台菜单中权限一般只控制到两级权限，权限级别太深难以维护，具体要看项目需求。</p>
<p>一级权限：如：商品管理。</p>
<p>二级权限：如：商品添加、商品列表。</p>
<p>三级权限：如：商品列表中的编辑或删除操作</p>
<h2>RBAC表的表设计</h2>
<p>一般RBAC权限控制都3张表和5张表，其核心都是一样。</p>
<p>3张表：后台用户表、角色表、权限表。</p>
<p>而5张表仅把用户表和角色表、角色表和权限表其相关联的字段分别使用一个表来维护。且表多了维护起来更加繁琐。</p>
<p>这里我们采用3张表来做权限控制。</p>
<p>三张表的关系如下：</p>
<p><img loading="lazy" decoding="async" width="749" height="293" class="wp-image-7739" src="/wp-content/uploads/2018/06/word-image-341.png" srcset="/wp-content/uploads/2018/06/word-image-341.png 749w, /wp-content/uploads/2018/06/word-image-341-300x117.png 300w" sizes="(max-width: 749px) 100vw, 749px" /></p>
<p>分析：</p>
<ul>
<li>用户表通过角色字段role_id，找到与其关联的角色表role_id。</li>
<li>角色表通过所拥有的所有权限字段auth_id_list，找到与其关联的权限表的auth_id。</li>
</ul>
<p>控制权限图解：</p>
<p><img loading="lazy" decoding="async" width="1127" height="449" class="wp-image-7740" src="/wp-content/uploads/2018/06/word-image-342.png" srcset="/wp-content/uploads/2018/06/word-image-342.png 1127w, /wp-content/uploads/2018/06/word-image-342-300x120.png 300w, /wp-content/uploads/2018/06/word-image-342-768x306.png 768w, /wp-content/uploads/2018/06/word-image-342-1024x408.png 1024w" sizes="(max-width: 1127px) 100vw, 1127px" /></p>
<p>可见，一个用户对应着一个角色，一个角色可以拥有多个权限。</p>
<h1>七、RBAC功能实现</h1>
<h2>权限表的curd操作</h2>
<h3>（1）完成权限的添加</h3>
<p>步骤1：在后台建立一个Auth控制器，并建立一个add方法，输出模板内容，并完成添加权限的实现</p>
<p><img loading="lazy" decoding="async" width="1028" height="717" class="wp-image-7741" src="/wp-content/uploads/2018/06/word-image-343.png" srcset="/wp-content/uploads/2018/06/word-image-343.png 1028w, /wp-content/uploads/2018/06/word-image-343-300x209.png 300w, /wp-content/uploads/2018/06/word-image-343-768x536.png 768w, /wp-content/uploads/2018/06/word-image-343-1024x714.png 1024w" sizes="(max-width: 1028px) 100vw, 1028px" /></p>
<p>同时在Auth模型中取出权限的无限级分类数据：</p>
<p><img loading="lazy" decoding="async" width="965" height="680" class="wp-image-7742" src="/wp-content/uploads/2018/06/word-image-344.png" srcset="/wp-content/uploads/2018/06/word-image-344.png 965w, /wp-content/uploads/2018/06/word-image-344-300x211.png 300w, /wp-content/uploads/2018/06/word-image-344-768x541.png 768w" sizes="(max-width: 965px) 100vw, 965px" /></p>
<p>步骤2：设置add.html模板内容</p>
<p><img loading="lazy" decoding="async" width="1230" height="699" class="wp-image-7743" src="/wp-content/uploads/2018/06/word-image-345.png" srcset="/wp-content/uploads/2018/06/word-image-345.png 1230w, /wp-content/uploads/2018/06/word-image-345-300x170.png 300w, /wp-content/uploads/2018/06/word-image-345-768x436.png 768w, /wp-content/uploads/2018/06/word-image-345-1024x582.png 1024w" sizes="(max-width: 1230px) 100vw, 1230px" /></p>
<p>当选择顶级权限时，控制器名和方法名不可用，否则可用。因为顶级权限没有控制器名和方法名。</p>
<p><img loading="lazy" decoding="async" width="1179" height="481" class="wp-image-7744" src="/wp-content/uploads/2018/06/word-image-346.png" srcset="/wp-content/uploads/2018/06/word-image-346.png 1179w, /wp-content/uploads/2018/06/word-image-346-300x122.png 300w, /wp-content/uploads/2018/06/word-image-346-768x313.png 768w, /wp-content/uploads/2018/06/word-image-346-1024x418.png 1024w" sizes="(max-width: 1179px) 100vw, 1179px" /></p>
<p>注意：表单input设置disabled和readonly的区别</p>
<p>相同点：都不可以编辑input中的数据</p>
<p>不同点：设置disabled时，php中通过$_POST接收不到input框name的属性值</p>
<p>设置readonly时，php中通过$_POST可以收到input的name的属性值</p>
<p>步骤3：定义Auth验证器，进行验证</p>
<p><img loading="lazy" decoding="async" width="773" height="636" class="wp-image-7745" src="/wp-content/uploads/2018/06/word-image-347.png" srcset="/wp-content/uploads/2018/06/word-image-347.png 773w, /wp-content/uploads/2018/06/word-image-347-300x247.png 300w, /wp-content/uploads/2018/06/word-image-347-768x632.png 768w" sizes="(max-width: 773px) 100vw, 773px" /></p>
<p>模板效果：</p>
<p><img loading="lazy" decoding="async" width="542" height="323" class="wp-image-7746" src="/wp-content/uploads/2018/06/word-image-348.png" srcset="/wp-content/uploads/2018/06/word-image-348.png 542w, /wp-content/uploads/2018/06/word-image-348-300x180.png 300w" sizes="(max-width: 542px) 100vw, 542px" /></p>
<h3>完成权限的列表展示</h3>
<h3>完成权限的编辑</h3>
<h3>完成权限的删除</h3>
<h2>角色表的curd操作</h2>
<h3>添加角色及分配权限</h3>
<p>注：一般系统角色名为超级管理员都会拥有所有的权限，其权限字段auth_id_list可以手动设置为*。</p>
<h3>（2）角色的列表展示</h3>
<p>把一个角色所拥有的权限都查出来，这里需要利用到两个mysql函数：</p>
<p>FIND_IN_SET和group_concat(字段)</p>
<ul>
<li>FIND_IN_SET(str,strlist) :</li>
</ul>
<p>作用：查询出子串str，是否在由逗号分隔的目标字符串strlist中存在。</p>
<p>如：判断5是否在字符串1,2,3,4,5中存在：FIND_IN_SET(5,‘1,2,3,4,5’) ，存在则返回所在目标字符串strlist的所在位置，不存在则返回0。</p>
<p><img loading="lazy" decoding="async" width="643" height="83" class="wp-image-7747" src="/wp-content/uploads/2018/06/word-image-349.png" srcset="/wp-content/uploads/2018/06/word-image-349.png 643w, /wp-content/uploads/2018/06/word-image-349-300x39.png 300w" sizes="(max-width: 643px) 100vw, 643px" /> <img loading="lazy" decoding="async" width="476" height="77" class="wp-image-7748" src="/wp-content/uploads/2018/06/word-image-350.png" srcset="/wp-content/uploads/2018/06/word-image-350.png 476w, /wp-content/uploads/2018/06/word-image-350-300x49.png 300w" sizes="(max-width: 476px) 100vw, 476px" /></p>
<ul>
<li>group_concat(字段)</li>
</ul>
<p>作用：主要根据某个字段进行分组，把相同字段的值连接在一起。</p>
<p>默认连接符号是逗号 ，如果用|连接则：</p>
<p>group_concat(字段名 SEPARATOR “|”)</p>
<p>例：如下是表tp_article表中的一些数据</p>
<p><img loading="lazy" decoding="async" width="400" height="150" class="wp-image-7749" src="/wp-content/uploads/2018/06/word-image-351.png" srcset="/wp-content/uploads/2018/06/word-image-351.png 400w, /wp-content/uploads/2018/06/word-image-351-300x113.png 300w" sizes="(max-width: 400px) 100vw, 400px" /></p>
<p>根据cat_id字段进行分组，把具有相同cat_id的title字段值连接在一起。</p>
<p><img loading="lazy" decoding="async" width="766" height="159" class="wp-image-7750" src="/wp-content/uploads/2018/06/word-image-352.png" srcset="/wp-content/uploads/2018/06/word-image-352.png 766w, /wp-content/uploads/2018/06/word-image-352-300x62.png 300w" sizes="(max-width: 766px) 100vw, 766px" /></p>
<h3>（3）完成角色编辑功能</h3>
<h3>（4）完成角色删除功能</h3>
<h1>实现不同用户登录展示不同后台菜单</h1>
<h1>八、权限防翻墙</h1>
]]></content:encoded>
					
					<wfw:commentRss>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7682.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TP5 商城（二）RBAC、权限增删改查、角色增删改查、不同用户显示不同后台、权限防翻墙</title>
		<link>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7751.html</link>
					<comments>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7751.html#respond</comments>
		
		<dc:creator><![CDATA[Mr.Lee]]></dc:creator>
		<pubDate>Sat, 09 Jun 2018 00:39:13 +0000</pubDate>
				<category><![CDATA[TP5.0]]></category>
		<category><![CDATA[TP5.0商城]]></category>
		<category><![CDATA[后台框架]]></category>
		<category><![CDATA[RBAC]]></category>
		<category><![CDATA[不同用户显示不同后台]]></category>
		<category><![CDATA[权限增删改查]]></category>
		<category><![CDATA[权限防翻墙]]></category>
		<category><![CDATA[角色增删改查]]></category>
		<guid isPermaLink="false">/?p=7751</guid>

					<description><![CDATA[一、RBAC功能实现 权限表的curd操作 （1）完成权限的添加 步骤1：在后台建立一个Auth控制器，并建立 [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>一、RBAC功能实现</h1>
<h2>权限表的curd操作</h2>
<h3>（1）完成权限的添加</h3>
<p>步骤1：在后台建立一个Auth控制器，并建立一个add方法，输出模板内容，并完成添加权限的实现</p>
<p><img loading="lazy" decoding="async" width="1028" height="717" class="wp-image-7825" src="/wp-content/uploads/2018/06/word-image-424.png" srcset="/wp-content/uploads/2018/06/word-image-424.png 1028w, /wp-content/uploads/2018/06/word-image-424-300x209.png 300w, /wp-content/uploads/2018/06/word-image-424-768x536.png 768w, /wp-content/uploads/2018/06/word-image-424-1024x714.png 1024w" sizes="(max-width: 1028px) 100vw, 1028px" /></p>
<p>同时在Auth模型中取出权限的无限级分类数据：</p>
<p><img loading="lazy" decoding="async" width="965" height="680" class="wp-image-7826" src="/wp-content/uploads/2018/06/word-image-425.png" srcset="/wp-content/uploads/2018/06/word-image-425.png 965w, /wp-content/uploads/2018/06/word-image-425-300x211.png 300w, /wp-content/uploads/2018/06/word-image-425-768x541.png 768w" sizes="(max-width: 965px) 100vw, 965px" /></p>
<p>步骤2：设置add.html模板内容</p>
<p><img loading="lazy" decoding="async" width="1230" height="699" class="wp-image-7827" src="/wp-content/uploads/2018/06/word-image-426.png" srcset="/wp-content/uploads/2018/06/word-image-426.png 1230w, /wp-content/uploads/2018/06/word-image-426-300x170.png 300w, /wp-content/uploads/2018/06/word-image-426-768x436.png 768w, /wp-content/uploads/2018/06/word-image-426-1024x582.png 1024w" sizes="(max-width: 1230px) 100vw, 1230px" /></p>
<p>当选择顶级权限时，控制器名和方法名不可用，否则可用。因为顶级权限没有控制器名和方法名。</p>
<p><img loading="lazy" decoding="async" width="1179" height="481" class="wp-image-7828" src="/wp-content/uploads/2018/06/word-image-427.png" srcset="/wp-content/uploads/2018/06/word-image-427.png 1179w, /wp-content/uploads/2018/06/word-image-427-300x122.png 300w, /wp-content/uploads/2018/06/word-image-427-768x313.png 768w, /wp-content/uploads/2018/06/word-image-427-1024x418.png 1024w" sizes="(max-width: 1179px) 100vw, 1179px" /></p>
<p>注意：表单input设置disabled和readonly的区别</p>
<p>相同点：都不可以编辑input中的数据</p>
<p>不同点：设置disabled时，php中通过$_POST接收不到input框name的属性值</p>
<p>设置readonly时，php中通过$_POST可以收到input的name的属性值</p>
<p>步骤3：定义Auth验证器，进行验证</p>
<p><img loading="lazy" decoding="async" width="773" height="636" class="wp-image-7829" src="/wp-content/uploads/2018/06/word-image-428.png" srcset="/wp-content/uploads/2018/06/word-image-428.png 773w, /wp-content/uploads/2018/06/word-image-428-300x247.png 300w, /wp-content/uploads/2018/06/word-image-428-768x632.png 768w" sizes="(max-width: 773px) 100vw, 773px" /></p>
<p>模板效果：</p>
<p><img loading="lazy" decoding="async" width="542" height="323" class="wp-image-7830" src="/wp-content/uploads/2018/06/word-image-429.png" srcset="/wp-content/uploads/2018/06/word-image-429.png 542w, /wp-content/uploads/2018/06/word-image-429-300x180.png 300w" sizes="(max-width: 542px) 100vw, 542px" /></p>
<h3>完成权限的列表展示</h3>
<p>步骤1：在后台的Auth控制器中建立一个index方法，取出所有的权限数据，分配到模板中。</p>
<p><img loading="lazy" decoding="async" width="1021" height="355" class="wp-image-7832" src="/wp-content/uploads/2018/06/word-image-430.png" srcset="/wp-content/uploads/2018/06/word-image-430.png 1021w, /wp-content/uploads/2018/06/word-image-430-300x104.png 300w, /wp-content/uploads/2018/06/word-image-430-768x267.png 768w" sizes="(max-width: 1021px) 100vw, 1021px" /></p>
<p>注：需要指定getAuthsSon方法返回的结果下标值：</p>
<p><img loading="lazy" decoding="async" width="994" height="413" class="wp-image-7833" src="/wp-content/uploads/2018/06/word-image-431.png" srcset="/wp-content/uploads/2018/06/word-image-431.png 994w, /wp-content/uploads/2018/06/word-image-431-300x125.png 300w, /wp-content/uploads/2018/06/word-image-431-768x319.png 768w" sizes="(max-width: 994px) 100vw, 994px" /></p>
<p>步骤：模板中遍历数据</p>
<p><img loading="lazy" decoding="async" width="1267" height="529" class="wp-image-7834" src="/wp-content/uploads/2018/06/word-image-432.png" srcset="/wp-content/uploads/2018/06/word-image-432.png 1267w, /wp-content/uploads/2018/06/word-image-432-300x125.png 300w, /wp-content/uploads/2018/06/word-image-432-768x321.png 768w, /wp-content/uploads/2018/06/word-image-432-1024x428.png 1024w" sizes="(max-width: 1267px) 100vw, 1267px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="967" height="329" class="wp-image-7835" src="/wp-content/uploads/2018/06/word-image-433.png" srcset="/wp-content/uploads/2018/06/word-image-433.png 967w, /wp-content/uploads/2018/06/word-image-433-300x102.png 300w, /wp-content/uploads/2018/06/word-image-433-768x261.png 768w" sizes="(max-width: 967px) 100vw, 967px" /></p>
<h3>完成权限的编辑</h3>
<p>编辑一个角色注意的地方：</p>
<p>a、不能以当前分类作为父权限 b.不能以当前子孙作为父权限</p>
<p>步骤1：修改编辑的链接地址</p>
<p><img loading="lazy" decoding="async" width="1155" height="428" class="wp-image-7836" src="/wp-content/uploads/2018/06/word-image-434.png" srcset="/wp-content/uploads/2018/06/word-image-434.png 1155w, /wp-content/uploads/2018/06/word-image-434-300x111.png 300w, /wp-content/uploads/2018/06/word-image-434-768x285.png 768w, /wp-content/uploads/2018/06/word-image-434-1024x379.png 1024w" sizes="(max-width: 1155px) 100vw, 1155px" /></p>
<p>步骤2：在Auth控制器建立一个upd的完成编辑功能</p>
<p><img loading="lazy" decoding="async" width="1056" height="699" class="wp-image-7837" src="/wp-content/uploads/2018/06/word-image-435.png" srcset="/wp-content/uploads/2018/06/word-image-435.png 1056w, /wp-content/uploads/2018/06/word-image-435-300x199.png 300w, /wp-content/uploads/2018/06/word-image-435-768x508.png 768w, /wp-content/uploads/2018/06/word-image-435-1024x678.png 1024w" sizes="(max-width: 1056px) 100vw, 1056px" /></p>
<p>步骤3：模板回显数据</p>
<p><img loading="lazy" decoding="async" width="1262" height="673" class="wp-image-7838" src="/wp-content/uploads/2018/06/word-image-436.png" srcset="/wp-content/uploads/2018/06/word-image-436.png 1262w, /wp-content/uploads/2018/06/word-image-436-300x160.png 300w, /wp-content/uploads/2018/06/word-image-436-768x410.png 768w, /wp-content/uploads/2018/06/word-image-436-1024x546.png 1024w" sizes="(max-width: 1262px) 100vw, 1262px" /> <img loading="lazy" decoding="async" width="1189" height="503" class="wp-image-7839" src="/wp-content/uploads/2018/06/word-image-437.png" srcset="/wp-content/uploads/2018/06/word-image-437.png 1189w, /wp-content/uploads/2018/06/word-image-437-300x127.png 300w, /wp-content/uploads/2018/06/word-image-437-768x325.png 768w, /wp-content/uploads/2018/06/word-image-437-1024x433.png 1024w" sizes="(max-width: 1189px) 100vw, 1189px" /></p>
<p>步骤4：需要考虑编辑注意的地方</p>
<p>a、不能以当前分类作为父权限 b.不能以当前子孙作为父权限</p>
<p><img loading="lazy" decoding="async" width="671" height="258" class="wp-image-7840" src="/wp-content/uploads/2018/06/word-image-438.png" srcset="/wp-content/uploads/2018/06/word-image-438.png 671w, /wp-content/uploads/2018/06/word-image-438-300x115.png 300w" sizes="(max-width: 671px) 100vw, 671px" /></p>
<p>解决办法：通过js递归实现，把当前权限以及子孙权限给删除即可。</p>
<p><img loading="lazy" decoding="async" width="1249" height="301" class="wp-image-7841" src="/wp-content/uploads/2018/06/word-image-439.png" srcset="/wp-content/uploads/2018/06/word-image-439.png 1249w, /wp-content/uploads/2018/06/word-image-439-300x72.png 300w, /wp-content/uploads/2018/06/word-image-439-768x185.png 768w, /wp-content/uploads/2018/06/word-image-439-1024x247.png 1024w" sizes="(max-width: 1249px) 100vw, 1249px" /> <img loading="lazy" decoding="async" width="1108" height="542" class="wp-image-7842" src="/wp-content/uploads/2018/06/word-image-440.png" srcset="/wp-content/uploads/2018/06/word-image-440.png 1108w, /wp-content/uploads/2018/06/word-image-440-300x147.png 300w, /wp-content/uploads/2018/06/word-image-440-768x376.png 768w, /wp-content/uploads/2018/06/word-image-440-1024x501.png 1024w" sizes="(max-width: 1108px) 100vw, 1108px" /></p>
<h3>【作业】完成权限的删除</h3>
<p>自行完成</p>
<p><img loading="lazy" decoding="async" width="603" height="415" class="wp-image-7843" src="/wp-content/uploads/2018/06/word-image-441.png" srcset="/wp-content/uploads/2018/06/word-image-441.png 603w, /wp-content/uploads/2018/06/word-image-441-300x206.png 300w" sizes="(max-width: 603px) 100vw, 603px" /></p>
<p>未考虑子分类 直接删除全部</p>
<h2>角色表的curd操作</h2>
<p><img loading="lazy" decoding="async" width="749" height="293" class="wp-image-7844" src="/wp-content/uploads/2018/06/word-image-442.png" srcset="/wp-content/uploads/2018/06/word-image-442.png 749w, /wp-content/uploads/2018/06/word-image-442-300x117.png 300w" sizes="(max-width: 749px) 100vw, 749px" /></p>
<p>分析：</p>
<ul>
<li>用户表通过角色字段role_id，找到与其关联的角色表role_id。</li>
<li>角色表通过所拥有的所有权限字段auth_id_list，找到与其关联的权限表的auth_id。</li>
</ul>
<h3>添加角色及分配权限</h3>
<p>步骤1：在后台建立一个Role控制器，并建立一个add方法，获取所有的权限</p>
<p><img loading="lazy" decoding="async" width="1023" height="699" class="wp-image-7845" src="/wp-content/uploads/2018/06/word-image-443.png" srcset="/wp-content/uploads/2018/06/word-image-443.png 1023w, /wp-content/uploads/2018/06/word-image-443-300x205.png 300w, /wp-content/uploads/2018/06/word-image-443-768x525.png 768w" sizes="(max-width: 1023px) 100vw, 1023px" /></p>
<p>我们这里取出所有的权限需要一定技巧，两个：</p>
<p>技巧一：取出所有的权限：并且以auth_id为每个元素的下标。</p>
<p>技巧二：取出所有的权限，通过pid进行分组，把具有相同的pid划分为同一组</p>
<p>其中上面变量$auths和$children的打印结果如下：</p>
<p><img loading="lazy" decoding="async" width="337" height="285" class="wp-image-7846" src="/wp-content/uploads/2018/06/word-image-444.png" srcset="/wp-content/uploads/2018/06/word-image-444.png 337w, /wp-content/uploads/2018/06/word-image-444-300x254.png 300w" sizes="(max-width: 337px) 100vw, 337px" /></p>
<p>其中pid=0,有两个元素即auth_id为46和49。其他以此类推。</p>
<p><img loading="lazy" decoding="async" width="479" height="270" class="wp-image-7847" src="/wp-content/uploads/2018/06/word-image-445.png" srcset="/wp-content/uploads/2018/06/word-image-445.png 479w, /wp-content/uploads/2018/06/word-image-445-300x169.png 300w" sizes="(max-width: 479px) 100vw, 479px" /></p>
<p>步骤2：模板中遍历权限，这里需要参考课件的权限布局文件：</p>
<p><img loading="lazy" decoding="async" width="442" height="67" class="wp-image-7848" src="/wp-content/uploads/2018/06/word-image-446.png" srcset="/wp-content/uploads/2018/06/word-image-446.png 442w, /wp-content/uploads/2018/06/word-image-446-300x45.png 300w" sizes="(max-width: 442px) 100vw, 442px" /></p>
<p>注意：如下一级中有个二级，二级中有三级、</p>
<p><img loading="lazy" decoding="async" width="520" height="106" class="wp-image-7849" src="/wp-content/uploads/2018/06/word-image-447.png" srcset="/wp-content/uploads/2018/06/word-image-447.png 520w, /wp-content/uploads/2018/06/word-image-447-300x61.png 300w" sizes="(max-width: 520px) 100vw, 520px" /> <img loading="lazy" decoding="async" width="1298" height="691" class="wp-image-7850" src="/wp-content/uploads/2018/06/word-image-448.png" srcset="/wp-content/uploads/2018/06/word-image-448.png 1298w, /wp-content/uploads/2018/06/word-image-448-300x160.png 300w, /wp-content/uploads/2018/06/word-image-448-768x409.png 768w, /wp-content/uploads/2018/06/word-image-448-1024x545.png 1024w" sizes="(max-width: 1298px) 100vw, 1298px" /></p>
<p>结果如下：</p>
<p><img loading="lazy" decoding="async" width="680" height="312" class="wp-image-7851" src="/wp-content/uploads/2018/06/word-image-449.png" srcset="/wp-content/uploads/2018/06/word-image-449.png 680w, /wp-content/uploads/2018/06/word-image-449-300x138.png 300w" sizes="(max-width: 680px) 100vw, 680px" /></p>
<p>步骤3：进行添加权限入库</p>
<p><img loading="lazy" decoding="async" width="966" height="529" class="wp-image-7852" src="/wp-content/uploads/2018/06/word-image-450.png" srcset="/wp-content/uploads/2018/06/word-image-450.png 966w, /wp-content/uploads/2018/06/word-image-450-300x164.png 300w, /wp-content/uploads/2018/06/word-image-450-768x421.png 768w" sizes="(max-width: 966px) 100vw, 966px" /></p>
<p>同时给表角色表添加模型和验证器</p>
<p>模型：</p>
<p><img loading="lazy" decoding="async" width="842" height="401" class="wp-image-7853" src="/wp-content/uploads/2018/06/word-image-451.png" srcset="/wp-content/uploads/2018/06/word-image-451.png 842w, /wp-content/uploads/2018/06/word-image-451-300x143.png 300w, /wp-content/uploads/2018/06/word-image-451-768x366.png 768w" sizes="(max-width: 842px) 100vw, 842px" /></p>
<p>验证器：</p>
<p><img loading="lazy" decoding="async" width="707" height="519" class="wp-image-7854" src="/wp-content/uploads/2018/06/word-image-452.png" srcset="/wp-content/uploads/2018/06/word-image-452.png 707w, /wp-content/uploads/2018/06/word-image-452-300x220.png 300w" sizes="(max-width: 707px) 100vw, 707px" /></p>
<p>数据库存储的格式：</p>
<p><img loading="lazy" decoding="async" width="667" height="118" class="wp-image-7855" src="/wp-content/uploads/2018/06/word-image-453.png" srcset="/wp-content/uploads/2018/06/word-image-453.png 667w, /wp-content/uploads/2018/06/word-image-453-300x53.png 300w" sizes="(max-width: 667px) 100vw, 667px" /></p>
<p>注：一般系统角色名为超级管理员都会拥有所有的权限，其权限字段auth_id_list可以手动设置为*。</p>
<h3>（2）完成添加权限分配的特效操作</h3>
<p>role/add.html模板文件：</p>
<p><img loading="lazy" decoding="async" width="1326" height="697" class="wp-image-7856" src="/wp-content/uploads/2018/06/word-image-454.png" srcset="/wp-content/uploads/2018/06/word-image-454.png 1326w, /wp-content/uploads/2018/06/word-image-454-300x158.png 300w, /wp-content/uploads/2018/06/word-image-454-768x404.png 768w, /wp-content/uploads/2018/06/word-image-454-1024x538.png 1024w" sizes="(max-width: 1326px) 100vw, 1326px" /></p>
<p>特效代码：</p>
<p><img loading="lazy" decoding="async" width="912" height="488" class="wp-image-7857" src="/wp-content/uploads/2018/06/word-image-455.png" srcset="/wp-content/uploads/2018/06/word-image-455.png 912w, /wp-content/uploads/2018/06/word-image-455-300x161.png 300w, /wp-content/uploads/2018/06/word-image-455-768x411.png 768w" sizes="(max-width: 912px) 100vw, 912px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="703" height="336" class="wp-image-7858" src="/wp-content/uploads/2018/06/word-image-456.png" srcset="/wp-content/uploads/2018/06/word-image-456.png 703w, /wp-content/uploads/2018/06/word-image-456-300x143.png 300w" sizes="(max-width: 703px) 100vw, 703px" /></p>
<h3>（3）【重要】小结</h3>
<ol>
<li>记住，以后去公司做有关权限分配的时候，可以直接参考以下的模板布局</li>
</ol>
<p><img loading="lazy" decoding="async" width="686" height="76" class="wp-image-7859" src="/wp-content/uploads/2018/06/word-image-457.png" srcset="/wp-content/uploads/2018/06/word-image-457.png 686w, /wp-content/uploads/2018/06/word-image-457-300x33.png 300w" sizes="(max-width: 686px) 100vw, 686px" /></p>
<p>b、以后在模板中凡是需要取出含有（父子孙）层级关系的数据，可以使用下面这个技巧。</p>
<p>技巧一：取出所有的权限：并且以auth_id为每个元素的下标。</p>
<p>技巧二：取出所有的权限，通过pid进行分组，把具有相同的pid划分为同一组</p>
<p>此技巧的典型使用场景有：</p>
<ol>
<li>如遍历权限可以用到，上面代码就是。</li>
</ol>
<p><img loading="lazy" decoding="async" width="617" height="128" class="wp-image-7860" src="/wp-content/uploads/2018/06/word-image-458.png" srcset="/wp-content/uploads/2018/06/word-image-458.png 617w, /wp-content/uploads/2018/06/word-image-458-300x62.png 300w" sizes="(max-width: 617px) 100vw, 617px" /></p>
<ol>
<li>如京东商城遍历三级分类菜单</li>
</ol>
<p><img loading="lazy" decoding="async" width="839" height="53" class="wp-image-7861" src="/wp-content/uploads/2018/06/word-image-459.png" srcset="/wp-content/uploads/2018/06/word-image-459.png 839w, /wp-content/uploads/2018/06/word-image-459-300x19.png 300w, /wp-content/uploads/2018/06/word-image-459-768x49.png 768w" sizes="(max-width: 839px) 100vw, 839px" /></p>
<p>3、分类菜单的折叠</p>
<p><img loading="lazy" decoding="async" width="230" height="342" class="wp-image-7862" src="/wp-content/uploads/2018/06/word-image-460.png" srcset="/wp-content/uploads/2018/06/word-image-460.png 230w, /wp-content/uploads/2018/06/word-image-460-202x300.png 202w" sizes="(max-width: 230px) 100vw, 230px" /></p>
<h3>（4）角色的列表展示</h3>
<p>把一个角色所拥有的权限都查出来，这里需要利用到两个mysql函数：</p>
<p>FIND_IN_SET和group_concat(字段)</p>
<ul>
<li>FIND_IN_SET(str,strlist) :</li>
</ul>
<p>作用：查询出子串str，是否在由逗号分隔的目标字符串strlist中存在。</p>
<p>如：判断5是否在字符串1,2,3,4,5中存在：FIND_IN_SET(5,‘1,2,3,4,5’) ，存在则返回所在目标字符串strlist的所在位置，不存在则返回0。</p>
<p>执行函数mysql函数： select 函数名();</p>
<p><img loading="lazy" decoding="async" width="643" height="83" class="wp-image-7863" src="/wp-content/uploads/2018/06/word-image-461.png" srcset="/wp-content/uploads/2018/06/word-image-461.png 643w, /wp-content/uploads/2018/06/word-image-461-300x39.png 300w" sizes="(max-width: 643px) 100vw, 643px" /> <img loading="lazy" decoding="async" width="476" height="77" class="wp-image-7864" src="/wp-content/uploads/2018/06/word-image-462.png" srcset="/wp-content/uploads/2018/06/word-image-462.png 476w, /wp-content/uploads/2018/06/word-image-462-300x49.png 300w" sizes="(max-width: 476px) 100vw, 476px" /></p>
<ul>
<li>group_concat(字段)</li>
</ul>
<p>作用：主要根据某个字段进行分组，把相同字段的值连接在一起。</p>
<p>默认连接符号是逗号 ，如果用|连接则：</p>
<p>group_concat(字段名 SEPARATOR “|”)</p>
<p>例：如下是表tp_article表中的一些数据</p>
<p><img loading="lazy" decoding="async" width="400" height="150" class="wp-image-7865" src="/wp-content/uploads/2018/06/word-image-463.png" srcset="/wp-content/uploads/2018/06/word-image-463.png 400w, /wp-content/uploads/2018/06/word-image-463-300x113.png 300w" sizes="(max-width: 400px) 100vw, 400px" /></p>
<p>根据cat_id字段进行分组，把具有相同cat_id的title字段值连接在一起。</p>
<p><img loading="lazy" decoding="async" width="766" height="159" class="wp-image-7866" src="/wp-content/uploads/2018/06/word-image-464.png" srcset="/wp-content/uploads/2018/06/word-image-464.png 766w, /wp-content/uploads/2018/06/word-image-464-300x62.png 300w" sizes="(max-width: 766px) 100vw, 766px" /></p>
<p>查询出当前角色所拥有的全部权限拼接在一起：</p>
<p><img loading="lazy" decoding="async" width="1117" height="403" class="wp-image-7867" src="/wp-content/uploads/2018/06/word-image-465.png" srcset="/wp-content/uploads/2018/06/word-image-465.png 1117w, /wp-content/uploads/2018/06/word-image-465-300x108.png 300w, /wp-content/uploads/2018/06/word-image-465-768x277.png 768w, /wp-content/uploads/2018/06/word-image-465-1024x369.png 1024w" sizes="(max-width: 1117px) 100vw, 1117px" /></p>
<h3>完成角色编辑功能（给角色分配权限）</h3>
<p>步骤1：修改role/index.html的链接地址</p>
<p><img loading="lazy" decoding="async" width="1283" height="476" class="wp-image-7868" src="/wp-content/uploads/2018/06/word-image-466.png" srcset="/wp-content/uploads/2018/06/word-image-466.png 1283w, /wp-content/uploads/2018/06/word-image-466-300x111.png 300w, /wp-content/uploads/2018/06/word-image-466-768x285.png 768w, /wp-content/uploads/2018/06/word-image-466-1024x380.png 1024w" sizes="(max-width: 1283px) 100vw, 1283px" /></p>
<p>步骤2：在admin-RoleController-upd的方法中完成数据的回显到模板中</p>
<p>注意： 模块-控制器-方法</p>
<p><img loading="lazy" decoding="async" width="879" height="699" class="wp-image-7869" src="/wp-content/uploads/2018/06/word-image-467.png" srcset="/wp-content/uploads/2018/06/word-image-467.png 879w, /wp-content/uploads/2018/06/word-image-467-300x239.png 300w, /wp-content/uploads/2018/06/word-image-467-768x611.png 768w" sizes="(max-width: 879px) 100vw, 879px" /></p>
<p>步骤3：复制添加角色的add.html模板即可，改名为html.进行回显数据和把角色已有的权限默认选中</p>
<p><img loading="lazy" decoding="async" width="1122" height="620" class="wp-image-7870" src="/wp-content/uploads/2018/06/word-image-468.png" srcset="/wp-content/uploads/2018/06/word-image-468.png 1122w, /wp-content/uploads/2018/06/word-image-468-300x166.png 300w, /wp-content/uploads/2018/06/word-image-468-768x424.png 768w, /wp-content/uploads/2018/06/word-image-468-1024x566.png 1024w" sizes="(max-width: 1122px) 100vw, 1122px" /></p>
<p>已有权限默认选中：</p>
<p><img loading="lazy" decoding="async" width="1160" height="587" class="wp-image-7871" src="/wp-content/uploads/2018/06/word-image-469.png" srcset="/wp-content/uploads/2018/06/word-image-469.png 1160w, /wp-content/uploads/2018/06/word-image-469-300x152.png 300w, /wp-content/uploads/2018/06/word-image-469-768x389.png 768w, /wp-content/uploads/2018/06/word-image-469-1024x518.png 1024w" sizes="(max-width: 1160px) 100vw, 1160px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="661" height="295" class="wp-image-7872" src="/wp-content/uploads/2018/06/word-image-470.png" srcset="/wp-content/uploads/2018/06/word-image-470.png 661w, /wp-content/uploads/2018/06/word-image-470-300x134.png 300w" sizes="(max-width: 661px) 100vw, 661px" /></p>
<h3>（6）【作业】完成角色删除功能</h3>
<p>自行完成</p>
<p><img loading="lazy" decoding="async" width="636" height="397" class="wp-image-7873" src="/wp-content/uploads/2018/06/word-image-471.png" srcset="/wp-content/uploads/2018/06/word-image-471.png 636w, /wp-content/uploads/2018/06/word-image-471-300x187.png 300w" sizes="(max-width: 636px) 100vw, 636px" /></p>
<h3>（7）添加用户分配权限</h3>
<p>步骤1：修改admin-view-user-add.html模板内容，加一个显示角色的下拉框</p>
<h1>实现不同用户登录展示不同后台菜单</h1>
<h2>思路</h2>
<p><img loading="lazy" decoding="async" width="848" height="291" class="wp-image-7874" src="/wp-content/uploads/2018/06/word-image-472.png" srcset="/wp-content/uploads/2018/06/word-image-472.png 848w, /wp-content/uploads/2018/06/word-image-472-300x103.png 300w, /wp-content/uploads/2018/06/word-image-472-768x264.png 768w" sizes="(max-width: 848px) 100vw, 848px" /></p>
<ol>
<li>用户登录成功的时候，获取到role_id。</li>
<li>通过role_id获取角色表的auth_id_list字段</li>
<li>通过权限表auth_id 只要在auth_id_list字段存在即可，查出所拥有的权限</li>
</ol>
<p>超级管理员auth_id_list字段的值为*，代表拥有后台操作的所有权限。</p>
<h2>代码实现</h2>
<p>步骤1：在用户登录成功的模型的checkUser方法中，通过角色id把当前角色所有的权限写入到session。</p>
<p><img loading="lazy" decoding="async" width="973" height="627" class="wp-image-7875" src="/wp-content/uploads/2018/06/word-image-473.png" srcset="/wp-content/uploads/2018/06/word-image-473.png 973w, /wp-content/uploads/2018/06/word-image-473-300x193.png 300w, /wp-content/uploads/2018/06/word-image-473-768x495.png 768w" sizes="(max-width: 973px) 100vw, 973px" /></p>
<p>步骤2：定义user模型中定义writeAuthToSession方法把权限写入到session中</p>
<p>注：后台left.html模板文件中，只需要显示一级和二级的权限即可：</p>
<p>我们需要构造出一个特定数据结构的数据：</p>
<p>如下：通过每个顶级（pid=0）的元素加个一个sonsAuth下标存储其对应的子级权限</p>
<p>[</p>
<p>auth_name=&gt;‘用户管理’</p>
<p>auth_id =&gt;46</p>
<p>pid =&gt; 0</p>
<p>&#8230;&#8230;</p>
<p>sonsAuth=&gt;[</p>
<p>[auth_name=&gt;用户列表,’pid’=&gt;46]</p>
<p>[auth_name=&gt;用户添加,’pid’=&gt;46]</p>
<p>&#8230;..</p>
<p>]</p>
<p>]</p>
<p>超级管理员：</p>
<p><img loading="lazy" decoding="async" width="1265" height="387" class="wp-image-7876" src="/wp-content/uploads/2018/06/word-image-474.png" srcset="/wp-content/uploads/2018/06/word-image-474.png 1265w, /wp-content/uploads/2018/06/word-image-474-300x92.png 300w, /wp-content/uploads/2018/06/word-image-474-768x235.png 768w, /wp-content/uploads/2018/06/word-image-474-1024x313.png 1024w" sizes="(max-width: 1265px) 100vw, 1265px" /></p>
<p>非超级管理员：</p>
<p><img loading="lazy" decoding="async" width="1163" height="577" class="wp-image-7877" src="/wp-content/uploads/2018/06/word-image-475.png" srcset="/wp-content/uploads/2018/06/word-image-475.png 1163w, /wp-content/uploads/2018/06/word-image-475-300x149.png 300w, /wp-content/uploads/2018/06/word-image-475-768x381.png 768w, /wp-content/uploads/2018/06/word-image-475-1024x508.png 1024w" sizes="(max-width: 1163px) 100vw, 1163px" /></p>
<p>步骤3：在left.html取出session中的权限，遍历访问的菜单</p>
<p><img loading="lazy" decoding="async" width="1235" height="668" class="wp-image-7878" src="/wp-content/uploads/2018/06/word-image-476.png" srcset="/wp-content/uploads/2018/06/word-image-476.png 1235w, /wp-content/uploads/2018/06/word-image-476-300x162.png 300w, /wp-content/uploads/2018/06/word-image-476-768x415.png 768w, /wp-content/uploads/2018/06/word-image-476-1024x554.png 1024w" sizes="(max-width: 1235px) 100vw, 1235px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="219" height="159" class="wp-image-7879" src="/wp-content/uploads/2018/06/word-image-477.png" /></p>
<h1>权限防翻墙</h1>
<p>如下：</p>
<p><img loading="lazy" decoding="async" width="1347" height="258" class="wp-image-7880" src="/wp-content/uploads/2018/06/word-image-478.png" srcset="/wp-content/uploads/2018/06/word-image-478.png 1347w, /wp-content/uploads/2018/06/word-image-478-300x57.png 300w, /wp-content/uploads/2018/06/word-image-478-768x147.png 768w, /wp-content/uploads/2018/06/word-image-478-1024x196.png 1024w" sizes="(max-width: 1347px) 100vw, 1347px" /></p>
<p>解决办法：在common控制器中的_initialize的方法中，做防翻墙的操作。</p>
<p>1、要先获取到用户所访问的控制器名和方法名，在去做相关判断是否有权限</p>
<p><img loading="lazy" decoding="async" width="1111" height="626" class="wp-image-7881" src="/wp-content/uploads/2018/06/word-image-479.png" srcset="/wp-content/uploads/2018/06/word-image-479.png 1111w, /wp-content/uploads/2018/06/word-image-479-300x169.png 300w, /wp-content/uploads/2018/06/word-image-479-768x433.png 768w, /wp-content/uploads/2018/06/word-image-479-1024x577.png 1024w" sizes="(max-width: 1111px) 100vw, 1111px" /></p>
<ol>
<li>把用户可以访问的权限存储在session中</li>
</ol>
<p>超级管理员：</p>
<p><img loading="lazy" decoding="async" width="1240" height="517" class="wp-image-7882" src="/wp-content/uploads/2018/06/word-image-480.png" srcset="/wp-content/uploads/2018/06/word-image-480.png 1240w, /wp-content/uploads/2018/06/word-image-480-300x125.png 300w, /wp-content/uploads/2018/06/word-image-480-768x320.png 768w, /wp-content/uploads/2018/06/word-image-480-1024x427.png 1024w" sizes="(max-width: 1240px) 100vw, 1240px" /></p>
<p>非超级管理员：</p>
<p><img loading="lazy" decoding="async" width="998" height="625" class="wp-image-7883" src="/wp-content/uploads/2018/06/word-image-481.png" srcset="/wp-content/uploads/2018/06/word-image-481.png 998w, /wp-content/uploads/2018/06/word-image-481-300x188.png 300w, /wp-content/uploads/2018/06/word-image-481-768x481.png 768w" sizes="(max-width: 998px) 100vw, 998px" /></p>
<p>今天重点：</p>
<ol>
<li>一张牛逼的图</li>
<li>怎么构造满足我们要求的数组结构数据</li>
</ol>
<h1>四、商品有关的基本概念</h1>
<p>这里主要涉及到以下几个概念：</p>
<ul>
<li>商品类型：不同的网站的卖的商品是不一样的，比如化妆品网站专门卖化妆品、手机网站专门卖手机、汽车网站专门卖汽车。</li>
<li>商品属性：不同的商品类型对应的商品属性也是不一样的。</li>
</ul>
<p>比如卖汽车网站，商品(汽车)属性有轴距、变速箱、驱动方式、进气方式、排量等</p>
<p>比如卖电脑网站，商品（电脑）属性有尺寸、内存、cpu、操作系统、系统核数等</p>
<p>比如卖手机网站，商品（手机）属性有尺寸、内存、系统、颜色、网络类型、电池容量等</p>
<p>商品类型决定了商品属性</p>
<ul>
<li>商品分类</li>
</ul>
<p>一个电商网站卖的商品不一样，其商品分类也是不一样的。</p>
<p>比如：卖汽车分类有：国产（吉利、 广汽）、日产(本田、丰田)、德国（奔驰、宝马）、韩国（起亚、现代）。</p>
<p>比如：卖手机分类有: 小米、华为、三星、苹果、oppo、vivo、魅族。</p>
<ul>
<li>商品（产品+属性=商品）</li>
</ul>
<p>如：iphoneX+64G , iphoneX+256G</p>
<h3>商品类型</h3>
<p>不同的商品类型会有不同的属性</p>
<p>可以在ecshop后台中新建一个商品类型，如下：建立一个汽车商品类型</p>
<p><img loading="lazy" decoding="async" width="1344" height="238" class="wp-image-7884" src="/wp-content/uploads/2018/06/word-image-482.png" srcset="/wp-content/uploads/2018/06/word-image-482.png 1344w, /wp-content/uploads/2018/06/word-image-482-300x53.png 300w, /wp-content/uploads/2018/06/word-image-482-768x136.png 768w, /wp-content/uploads/2018/06/word-image-482-1024x181.png 1024w" sizes="(max-width: 1344px) 100vw, 1344px" /> <img loading="lazy" decoding="async" width="797" height="395" class="wp-image-7885" src="/wp-content/uploads/2018/06/word-image-483.png" srcset="/wp-content/uploads/2018/06/word-image-483.png 797w, /wp-content/uploads/2018/06/word-image-483-300x149.png 300w, /wp-content/uploads/2018/06/word-image-483-768x381.png 768w" sizes="(max-width: 797px) 100vw, 797px" /></p>
<p>属性分组：有些属性是可以归为一组的，参考京东电脑商品：</p>
<p><img loading="lazy" decoding="async" width="546" height="381" class="wp-image-7886" src="/wp-content/uploads/2018/06/word-image-484.png" srcset="/wp-content/uploads/2018/06/word-image-484.png 546w, /wp-content/uploads/2018/06/word-image-484-300x209.png 300w" sizes="(max-width: 546px) 100vw, 546px" /></p>
<h3>商品属性</h3>
<p>给商品类型添加商品属性： 商品类型&#8211;&gt;属性列表：</p>
<p><img loading="lazy" decoding="async" width="1147" height="34" class="wp-image-7887" src="/wp-content/uploads/2018/06/word-image-485.png" srcset="/wp-content/uploads/2018/06/word-image-485.png 1147w, /wp-content/uploads/2018/06/word-image-485-300x9.png 300w, /wp-content/uploads/2018/06/word-image-485-768x23.png 768w, /wp-content/uploads/2018/06/word-image-485-1024x30.png 1024w" sizes="(max-width: 1147px) 100vw, 1147px" /> <img loading="lazy" decoding="async" width="1142" height="200" class="wp-image-7888" src="/wp-content/uploads/2018/06/word-image-486.png" srcset="/wp-content/uploads/2018/06/word-image-486.png 1142w, /wp-content/uploads/2018/06/word-image-486-300x53.png 300w, /wp-content/uploads/2018/06/word-image-486-768x135.png 768w, /wp-content/uploads/2018/06/word-image-486-1024x179.png 1024w" sizes="(max-width: 1142px) 100vw, 1142px" /></p>
<p>给汽车类型商品添加进气方式的属性：</p>
<p><img loading="lazy" decoding="async" width="658" height="419" class="wp-image-7889" src="/wp-content/uploads/2018/06/word-image-487.png" srcset="/wp-content/uploads/2018/06/word-image-487.png 658w, /wp-content/uploads/2018/06/word-image-487-300x191.png 300w" sizes="(max-width: 658px) 100vw, 658px" /></p>
<p>单选属性： 指买商品的时候，可以选择一个属性，不同的属性价格不一样</p>
<p><img loading="lazy" decoding="async" width="676" height="145" class="wp-image-7890" src="/wp-content/uploads/2018/06/word-image-488.png" srcset="/wp-content/uploads/2018/06/word-image-488.png 676w, /wp-content/uploads/2018/06/word-image-488-300x64.png 300w" sizes="(max-width: 676px) 100vw, 676px" /></p>
<p>唯一属性：只能看不能选。</p>
<p><img loading="lazy" decoding="async" width="802" height="232" class="wp-image-7891" src="/wp-content/uploads/2018/06/word-image-489.png" srcset="/wp-content/uploads/2018/06/word-image-489.png 802w, /wp-content/uploads/2018/06/word-image-489-300x87.png 300w, /wp-content/uploads/2018/06/word-image-489-768x222.png 768w" sizes="(max-width: 802px) 100vw, 802px" /></p>
<p>复选属性：可以选择多个，一般买商品的附加配件都是复选的。</p>
<p><img loading="lazy" decoding="async" width="1016" height="261" class="wp-image-7892" src="/wp-content/uploads/2018/06/word-image-490.png" srcset="/wp-content/uploads/2018/06/word-image-490.png 1016w, /wp-content/uploads/2018/06/word-image-490-300x77.png 300w, /wp-content/uploads/2018/06/word-image-490-768x197.png 768w" sizes="(max-width: 1016px) 100vw, 1016px" /></p>
<p>当在后台添加一个商品的时候要选择一个商品类型，选择了一个商品类型就决定了这个商品的有哪些属性，如下是添加商品设置其商品属性：</p>
<p><img loading="lazy" decoding="async" width="921" height="440" class="wp-image-7893" src="/wp-content/uploads/2018/06/word-image-491.png" srcset="/wp-content/uploads/2018/06/word-image-491.png 921w, /wp-content/uploads/2018/06/word-image-491-300x143.png 300w, /wp-content/uploads/2018/06/word-image-491-768x367.png 768w" sizes="(max-width: 921px) 100vw, 921px" /></p>
<p>添加属性的特点：</p>
<p>唯一属性（只能看，不能选）：前面没有【+】，不可以设置价格</p>
<p>单选属性（可选择）：前面有【+】，点击+即可复制多个，不同的单选属性可设置不同的价格</p>
<p>属性值手工输入：对应的是个input框，需要自己输入。</p>
<p>属性值是列表选择： 对应的是个select下拉框，需选中一个属性值。</p>
<h3>商品分类</h3>
<p>一般一个网站决定卖什么类型商品就决定了其商品分类。</p>
<p>如卖汽车网站：分类有国产、日系、德系、韩系等</p>
<p>如卖化妆品网站：分类洗面奶、乳液、面膜、保湿、祛痘、眼霜等</p>
<p><img loading="lazy" decoding="async" width="1323" height="236" class="wp-image-7894" src="/wp-content/uploads/2018/06/word-image-492.png" srcset="/wp-content/uploads/2018/06/word-image-492.png 1323w, /wp-content/uploads/2018/06/word-image-492-300x54.png 300w, /wp-content/uploads/2018/06/word-image-492-768x137.png 768w, /wp-content/uploads/2018/06/word-image-492-1024x183.png 1024w" sizes="(max-width: 1323px) 100vw, 1323px" /></p>
<h1>五、完成商品类型的curd</h1>
<h2>商品类型介绍</h2>
<p>商品类型：不同的网站的卖的商品类型是不一样的，比如化妆品网站专卖化妆品、手机网站专卖手机、二手汽车网站专买二手汽车。</p>
<p>网站决定卖什么商品类型，也就决定了商品的商品属性</p>
<h2>商品类型的增加</h2>
<h2>商品类型的列表</h2>
<h2>商品类型的编辑</h2>
<h2>【作业】商品类型的删除</h2>
<h1>六、完成商品属性的curd</h1>
<h2>1、商品属性的认识</h2>
<p>网站决定卖什么商品类型，也就决定了商品的商品属性</p>
<p>可以参考ecshop添加属性的方式:</p>
<p><img loading="lazy" decoding="async" width="960" height="427" class="wp-image-7895" src="/wp-content/uploads/2018/06/word-image-493.png" srcset="/wp-content/uploads/2018/06/word-image-493.png 960w, /wp-content/uploads/2018/06/word-image-493-300x133.png 300w, /wp-content/uploads/2018/06/word-image-493-768x342.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p>属性这里重点两种属性：唯一属性和单选属性</p>
<p>唯一属性：只能看，不能选。</p>
<p><img loading="lazy" decoding="async" width="389" height="55" class="wp-image-7896" src="/wp-content/uploads/2018/06/word-image-494.png" srcset="/wp-content/uploads/2018/06/word-image-494.png 389w, /wp-content/uploads/2018/06/word-image-494-300x42.png 300w" sizes="(max-width: 389px) 100vw, 389px" /></p>
<p>单选属性：我们购买商品的时候，可以选择的，后面添加商品的时候，不同的单选属性价格也是不一样的，如iphone6银色和iphone黑色价格是不一样的。</p>
<p><img loading="lazy" decoding="async" width="678" height="186" class="wp-image-7897" src="/wp-content/uploads/2018/06/word-image-495.png" srcset="/wp-content/uploads/2018/06/word-image-495.png 678w, /wp-content/uploads/2018/06/word-image-495-300x82.png 300w" sizes="(max-width: 678px) 100vw, 678px" /></p>
<p>②属性的值的录入方式</p>
<p><img loading="lazy" decoding="async" width="643" height="114" class="wp-image-7898" src="/wp-content/uploads/2018/06/word-image-496.png" srcset="/wp-content/uploads/2018/06/word-image-496.png 643w, /wp-content/uploads/2018/06/word-image-496-300x53.png 300w" sizes="(max-width: 643px) 100vw, 643px" /></p>
<p>手工输入：不可以输入属性值，且可选值列表是禁用状态，只能在添加商品的时候输入属性值。</p>
<p>列表选择：在可选择列表输入一些我们指定的属性值，添加商品的时候，从中选中一个属性值即可。</p>
<p>表结构：</p>
<h2>完成商品属性的添加</h2>
<h2>完成商品属性的列表</h2>
<h2>完成商品属性的编辑</h2>
<h2>完成商品属性的删除</h2>
<h2>完成商品类型列表中属性的查看</h2>
<h1>七、完成商品分类的curd</h1>
<h2>1、分析分类表结构</h2>
<p>表字段结构如下：</p>
<h2>完成商品分类的添加</h2>
<h2>完成商品分类的列表</h2>
<h2>4、完成商品分类的编辑</h2>
<h2>5、【作业】完成商品分类的删除</h2>
]]></content:encoded>
					
					<wfw:commentRss>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7751.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TP5 商城（三）账户状态权限控制、商品类型 CURD、商品属性 CURD、商品分类 CURD</title>
		<link>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7899.html</link>
					<comments>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7899.html#respond</comments>
		
		<dc:creator><![CDATA[Mr.Lee]]></dc:creator>
		<pubDate>Sat, 09 Jun 2018 00:38:08 +0000</pubDate>
				<category><![CDATA[TP5.0]]></category>
		<category><![CDATA[TP5.0商城]]></category>
		<category><![CDATA[后台框架]]></category>
		<category><![CDATA[商品分类 CURD]]></category>
		<category><![CDATA[商品属性 CURD]]></category>
		<category><![CDATA[商品类型 CURD]]></category>
		<category><![CDATA[账户状态权限控制]]></category>
		<guid isPermaLink="false">/?p=7899</guid>

					<description><![CDATA[完善控制账户状态的权限控制 当用户点击下面列表的可用或禁用的功能的时候，ajax返回一个无权限操作。 这是因为 [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>完善控制账户状态的权限控制</h1>
<p>当用户点击下面列表的可用或禁用的功能的时候，ajax返回一个无权限操作。</p>
<p>这是因为用户没有此权限，一般只有超级管理员才会有此权限。</p>
<p>所以，我们也可以在后台添加此权限给用户进行分配：</p>
<p><img loading="lazy" decoding="async" width="558" height="375" class="wp-image-7965" src="/wp-content/uploads/2018/06/word-image-560.png" srcset="/wp-content/uploads/2018/06/word-image-560.png 558w, /wp-content/uploads/2018/06/word-image-560-300x202.png 300w" sizes="(max-width: 558px) 100vw, 558px" /></p>
<p>然后给对应的角色分配即可：</p>
<p><img loading="lazy" decoding="async" width="721" height="347" class="wp-image-7966" src="/wp-content/uploads/2018/06/word-image-561.png" srcset="/wp-content/uploads/2018/06/word-image-561.png 721w, /wp-content/uploads/2018/06/word-image-561-300x144.png 300w" sizes="(max-width: 721px) 100vw, 721px" /></p>
<p>同时当某个角色没有此权限的时候，需要在Common控制器中给提示无权限访问：</p>
<p><img loading="lazy" decoding="async" width="1286" height="694" class="wp-image-7967" src="/wp-content/uploads/2018/06/word-image-562.png" srcset="/wp-content/uploads/2018/06/word-image-562.png 1286w, /wp-content/uploads/2018/06/word-image-562-300x162.png 300w, /wp-content/uploads/2018/06/word-image-562-768x414.png 768w, /wp-content/uploads/2018/06/word-image-562-1024x553.png 1024w" sizes="(max-width: 1286px) 100vw, 1286px" /></p>
<p>在ajax中给出提示无权限：</p>
<p><img loading="lazy" decoding="async" width="1210" height="427" class="wp-image-7968" src="/wp-content/uploads/2018/06/word-image-563.png" srcset="/wp-content/uploads/2018/06/word-image-563.png 1210w, /wp-content/uploads/2018/06/word-image-563-300x106.png 300w, /wp-content/uploads/2018/06/word-image-563-768x271.png 768w, /wp-content/uploads/2018/06/word-image-563-1024x361.png 1024w" sizes="(max-width: 1210px) 100vw, 1210px" /></p>
<h1>一、商品有关的基本概念</h1>
<p>这里主要涉及到以下几个概念：</p>
<ul>
<li>商品类型：不同的网站的卖的商品是不一样的，比如化妆品网站专门卖化妆品、手机网站专门卖手机、汽车网站专门卖汽车。</li>
<li>商品属性：不同的商品类型对应的商品属性也是不一样的。</li>
</ul>
<p>比如卖汽车网站，商品(汽车)属性有轴距、变速箱、驱动方式、进气方式、排量等</p>
<p>比如卖电脑网站，商品（电脑）属性有尺寸、内存、cpu、操作系统、系统核数等</p>
<p>比如卖手机网站，商品（手机）属性有尺寸、内存、系统、颜色、网络类型、电池容量等</p>
<p>商品类型决定了商品属性，商品属性依据商品类型走的。</p>
<ul>
<li>商品分类</li>
</ul>
<p>一个电商网站卖的商品不一样，其商品分类也是不一样的。</p>
<p>比如：卖汽车分类有：国产（吉利、 广汽）、日产(本田、丰田)、德国（奔驰、宝马）、韩国（起亚、现代）。</p>
<p>比如：卖手机分类有: 小米、华为、三星、苹果、oppo、vivo、魅族。</p>
<p>比如：卖化妆品有: 补水、祛痘、气垫、BB霜、口红、&#8230;.</p>
<ul>
<li>商品（产品+属性=商品）</li>
<li>商品（产品+属性=商品）</li>
</ul>
<p>如：iphoneX+64G(7888) , iphoneX+256G(9888)</p>
<h2>1、商品类型</h2>
<p>不同的商品类型会有不同的属性</p>
<p>可以在ecshop后台中新建一个商品类型，如下：建立一个手机商品类型</p>
<p><img loading="lazy" decoding="async" width="1344" height="238" class="wp-image-7969" src="/wp-content/uploads/2018/06/word-image-564.png" srcset="/wp-content/uploads/2018/06/word-image-564.png 1344w, /wp-content/uploads/2018/06/word-image-564-300x53.png 300w, /wp-content/uploads/2018/06/word-image-564-768x136.png 768w, /wp-content/uploads/2018/06/word-image-564-1024x181.png 1024w" sizes="(max-width: 1344px) 100vw, 1344px" /></p>
<h2>2、商品属性</h2>
<p>给商品类型添加商品属性： 商品类型&#8211;&gt;属性列表：</p>
<p><img loading="lazy" decoding="async" width="1147" height="34" class="wp-image-7970" src="/wp-content/uploads/2018/06/word-image-565.png" srcset="/wp-content/uploads/2018/06/word-image-565.png 1147w, /wp-content/uploads/2018/06/word-image-565-300x9.png 300w, /wp-content/uploads/2018/06/word-image-565-768x23.png 768w, /wp-content/uploads/2018/06/word-image-565-1024x30.png 1024w" sizes="(max-width: 1147px) 100vw, 1147px" /> <img loading="lazy" decoding="async" width="1159" height="102" class="wp-image-7972" src="/wp-content/uploads/2018/06/word-image-566.png" srcset="/wp-content/uploads/2018/06/word-image-566.png 1159w, /wp-content/uploads/2018/06/word-image-566-300x26.png 300w, /wp-content/uploads/2018/06/word-image-566-768x68.png 768w, /wp-content/uploads/2018/06/word-image-566-1024x90.png 1024w" sizes="(max-width: 1159px) 100vw, 1159px" /></p>
<p>给手机类型商品添加内存的属性：</p>
<p><img loading="lazy" decoding="async" width="665" height="370" class="wp-image-7973" src="/wp-content/uploads/2018/06/word-image-567.png" srcset="/wp-content/uploads/2018/06/word-image-567.png 665w, /wp-content/uploads/2018/06/word-image-567-300x167.png 300w" sizes="(max-width: 665px) 100vw, 665px" /></p>
<p>添加商品属性列表如下：</p>
<p><img loading="lazy" decoding="async" width="955" height="200" class="wp-image-7974" src="/wp-content/uploads/2018/06/word-image-568.png" srcset="/wp-content/uploads/2018/06/word-image-568.png 955w, /wp-content/uploads/2018/06/word-image-568-300x63.png 300w, /wp-content/uploads/2018/06/word-image-568-768x161.png 768w" sizes="(max-width: 955px) 100vw, 955px" /></p>
<p>属性解释：</p>
<p>单选属性： 指买商品的时候，可以选择一个属性，不同的属性价格不一样</p>
<p><img loading="lazy" decoding="async" width="676" height="145" class="wp-image-7975" src="/wp-content/uploads/2018/06/word-image-569.png" srcset="/wp-content/uploads/2018/06/word-image-569.png 676w, /wp-content/uploads/2018/06/word-image-569-300x64.png 300w" sizes="(max-width: 676px) 100vw, 676px" /></p>
<p>唯一属性：只能看不能选。</p>
<p><img loading="lazy" decoding="async" width="802" height="232" class="wp-image-7976" src="/wp-content/uploads/2018/06/word-image-570.png" srcset="/wp-content/uploads/2018/06/word-image-570.png 802w, /wp-content/uploads/2018/06/word-image-570-300x87.png 300w, /wp-content/uploads/2018/06/word-image-570-768x222.png 768w" sizes="(max-width: 802px) 100vw, 802px" /></p>
<p>复选属性：可以选择多个，一般买商品的附加配件都是复选的。</p>
<p><img loading="lazy" decoding="async" width="1016" height="261" class="wp-image-7977" src="/wp-content/uploads/2018/06/word-image-571.png" srcset="/wp-content/uploads/2018/06/word-image-571.png 1016w, /wp-content/uploads/2018/06/word-image-571-300x77.png 300w, /wp-content/uploads/2018/06/word-image-571-768x197.png 768w" sizes="(max-width: 1016px) 100vw, 1016px" /></p>
<h2>3、属性类型和属性录入方式的组合</h2>
<p>当在后台添加一个商品的时候要选择一个商品类型，选择了一个商品类型就决定了这个商品的有哪些属性，如下是添加商品设置其商品属性：</p>
<p><img loading="lazy" decoding="async" width="359" height="255" class="wp-image-7978" src="/wp-content/uploads/2018/06/word-image-572.png" srcset="/wp-content/uploads/2018/06/word-image-572.png 359w, /wp-content/uploads/2018/06/word-image-572-300x213.png 300w" sizes="(max-width: 359px) 100vw, 359px" /></p>
<p>给商品添加属性：</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" width="794" height="225" class="wp-image-7979" src="/wp-content/uploads/2018/06/word-image-573.png" srcset="/wp-content/uploads/2018/06/word-image-573.png 794w, /wp-content/uploads/2018/06/word-image-573-300x85.png 300w, /wp-content/uploads/2018/06/word-image-573-768x218.png 768w" sizes="(max-width: 794px) 100vw, 794px" /></p>
<p>特点如下：</p>
<p>唯一属性（只能看，不能选）：前面没有【+】，不可以设置价格</p>
<p>单选属性（可选择）：前面有【+】，点击+即可复制多个，不同的单选属性可设置不同的价格</p>
<p>属性值手工输入：对应的是个input框，需要自己输入。</p>
<p>属性值是列表选择： 对应的是个select下拉框，需选中一个属性值。</p>
<h2>4、商品分类</h2>
<p>一般一个网站决定卖什么类型商品就决定了其商品分类。</p>
<p>如卖汽车网站：分类有国产、日系、德系、韩系等</p>
<p>如卖化妆品网站：分类洗面奶、乳液、面膜、保湿、祛痘、眼霜等</p>
<p><img loading="lazy" decoding="async" width="1323" height="236" class="wp-image-7980" src="/wp-content/uploads/2018/06/word-image-574.png" srcset="/wp-content/uploads/2018/06/word-image-574.png 1323w, /wp-content/uploads/2018/06/word-image-574-300x54.png 300w, /wp-content/uploads/2018/06/word-image-574-768x137.png 768w, /wp-content/uploads/2018/06/word-image-574-1024x183.png 1024w" sizes="(max-width: 1323px) 100vw, 1323px" /></p>
<h1>二、完成商品类型的curd</h1>
<h2>商品类型介绍</h2>
<p>商品类型：不同的网站的卖的商品类型是不一样的，比如化妆品网站专卖化妆品、手机网站专卖手机、二手汽车网站专买二手汽车。</p>
<p>网站决定卖什么商品类型，也就决定了商品的商品属性</p>
<h2>商品类型的增加</h2>
<p>商品类型表如下:</p>
<p><img loading="lazy" decoding="async" width="986" height="155" class="wp-image-7981" src="/wp-content/uploads/2018/06/word-image-575.png" srcset="/wp-content/uploads/2018/06/word-image-575.png 986w, /wp-content/uploads/2018/06/word-image-575-300x47.png 300w, /wp-content/uploads/2018/06/word-image-575-768x121.png 768w" sizes="(max-width: 986px) 100vw, 986px" /></p>
<p>1：在admin-TypeController-add中，完成添加商品类型完成</p>
<p><img loading="lazy" decoding="async" width="1038" height="519" class="wp-image-7982" src="/wp-content/uploads/2018/06/word-image-576.png" srcset="/wp-content/uploads/2018/06/word-image-576.png 1038w, /wp-content/uploads/2018/06/word-image-576-300x150.png 300w, /wp-content/uploads/2018/06/word-image-576-768x384.png 768w, /wp-content/uploads/2018/06/word-image-576-1024x512.png 1024w" sizes="(max-width: 1038px) 100vw, 1038px" /></p>
<ol>
<li>在add模板中设置表单name名称</li>
</ol>
<p><img loading="lazy" decoding="async" width="1263" height="589" class="wp-image-7983" src="/wp-content/uploads/2018/06/word-image-577.png" srcset="/wp-content/uploads/2018/06/word-image-577.png 1263w, /wp-content/uploads/2018/06/word-image-577-300x140.png 300w, /wp-content/uploads/2018/06/word-image-577-768x358.png 768w, /wp-content/uploads/2018/06/word-image-577-1024x478.png 1024w" sizes="(max-width: 1263px) 100vw, 1263px" /></p>
<p>3、同时建立一个Type的验证器和Type模型</p>
<p>验证器：</p>
<p><img loading="lazy" decoding="async" width="888" height="523" class="wp-image-7984" src="/wp-content/uploads/2018/06/word-image-578.png" srcset="/wp-content/uploads/2018/06/word-image-578.png 888w, /wp-content/uploads/2018/06/word-image-578-300x177.png 300w, /wp-content/uploads/2018/06/word-image-578-768x452.png 768w" sizes="(max-width: 888px) 100vw, 888px" /></p>
<p>模型：</p>
<p><img loading="lazy" decoding="async" width="796" height="268" class="wp-image-7985" src="/wp-content/uploads/2018/06/word-image-579.png" srcset="/wp-content/uploads/2018/06/word-image-579.png 796w, /wp-content/uploads/2018/06/word-image-579-300x101.png 300w, /wp-content/uploads/2018/06/word-image-579-768x259.png 768w" sizes="(max-width: 796px) 100vw, 796px" /></p>
<h2>商品类型的列表</h2>
<ol>
<li>在admin-Type-index方法中取出所有的商品类型分配到模板中</li>
</ol>
<p><img loading="lazy" decoding="async" width="746" height="314" class="wp-image-7986" src="/wp-content/uploads/2018/06/word-image-580.png" srcset="/wp-content/uploads/2018/06/word-image-580.png 746w, /wp-content/uploads/2018/06/word-image-580-300x126.png 300w" sizes="(max-width: 746px) 100vw, 746px" /></p>
<ol>
<li>index.html模板中遍历数据</li>
</ol>
<p><img loading="lazy" decoding="async" width="1263" height="493" class="wp-image-7987" src="/wp-content/uploads/2018/06/word-image-581.png" srcset="/wp-content/uploads/2018/06/word-image-581.png 1263w, /wp-content/uploads/2018/06/word-image-581-300x117.png 300w, /wp-content/uploads/2018/06/word-image-581-768x300.png 768w, /wp-content/uploads/2018/06/word-image-581-1024x400.png 1024w" sizes="(max-width: 1263px) 100vw, 1263px" /></p>
<h2>商品类型的编辑</h2>
<ol>
<li>修改index.html的编辑的链接地址</li>
</ol>
<p><img loading="lazy" decoding="async" width="1201" height="404" class="wp-image-7988" src="/wp-content/uploads/2018/06/word-image-582.png" srcset="/wp-content/uploads/2018/06/word-image-582.png 1201w, /wp-content/uploads/2018/06/word-image-582-300x101.png 300w, /wp-content/uploads/2018/06/word-image-582-768x258.png 768w, /wp-content/uploads/2018/06/word-image-582-1024x344.png 1024w" sizes="(max-width: 1201px) 100vw, 1201px" /></p>
<p>2、在admin-type-upd方法中完取出当前商品类型的数据回显到模板中，并完成编辑入库的实现</p>
<p><img loading="lazy" decoding="async" width="1070" height="509" class="wp-image-7989" src="/wp-content/uploads/2018/06/word-image-583.png" srcset="/wp-content/uploads/2018/06/word-image-583.png 1070w, /wp-content/uploads/2018/06/word-image-583-300x143.png 300w, /wp-content/uploads/2018/06/word-image-583-768x365.png 768w, /wp-content/uploads/2018/06/word-image-583-1024x487.png 1024w" sizes="(max-width: 1070px) 100vw, 1070px" /></p>
<p>3、模板upd.html回显内容</p>
<p><img loading="lazy" decoding="async" width="1271" height="587" class="wp-image-7990" src="/wp-content/uploads/2018/06/word-image-584.png" srcset="/wp-content/uploads/2018/06/word-image-584.png 1271w, /wp-content/uploads/2018/06/word-image-584-300x139.png 300w, /wp-content/uploads/2018/06/word-image-584-768x355.png 768w, /wp-content/uploads/2018/06/word-image-584-1024x473.png 1024w" sizes="(max-width: 1271px) 100vw, 1271px" /></p>
<h2>商品类型的删除</h2>
<ol>
<li>修改index.html的删除的链接地址</li>
</ol>
<p><img loading="lazy" decoding="async" width="1238" height="385" class="wp-image-7991" src="/wp-content/uploads/2018/06/word-image-585.png" srcset="/wp-content/uploads/2018/06/word-image-585.png 1238w, /wp-content/uploads/2018/06/word-image-585-300x93.png 300w, /wp-content/uploads/2018/06/word-image-585-768x239.png 768w, /wp-content/uploads/2018/06/word-image-585-1024x318.png 1024w" sizes="(max-width: 1238px) 100vw, 1238px" /></p>
<ol>
<li>在admin-type-del方法中完成删除</li>
</ol>
<p><img loading="lazy" decoding="async" width="953" height="345" class="wp-image-7992" src="/wp-content/uploads/2018/06/word-image-586.png" srcset="/wp-content/uploads/2018/06/word-image-586.png 953w, /wp-content/uploads/2018/06/word-image-586-300x109.png 300w, /wp-content/uploads/2018/06/word-image-586-768x278.png 768w" sizes="(max-width: 953px) 100vw, 953px" /></p>
<h1>三、完成商品属性的curd</h1>
<h2>1、商品属性的认识</h2>
<p>网站决定卖什么商品类型，也就决定了商品的商品属性</p>
<p>可以参考ecshop添加属性的方式:</p>
<p><img loading="lazy" decoding="async" width="960" height="427" class="wp-image-7993" src="/wp-content/uploads/2018/06/word-image-587.png" srcset="/wp-content/uploads/2018/06/word-image-587.png 960w, /wp-content/uploads/2018/06/word-image-587-300x133.png 300w, /wp-content/uploads/2018/06/word-image-587-768x342.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p>属性这里重点两种属性：唯一属性和单选属性</p>
<p>唯一属性：只能看，不能选。</p>
<p><img loading="lazy" decoding="async" width="389" height="55" class="wp-image-7994" src="/wp-content/uploads/2018/06/word-image-588.png" srcset="/wp-content/uploads/2018/06/word-image-588.png 389w, /wp-content/uploads/2018/06/word-image-588-300x42.png 300w" sizes="(max-width: 389px) 100vw, 389px" /></p>
<p>单选属性：我们购买商品的时候，可以选择的，后面添加商品的时候，不同的单选属性价格也是不一样的，如iphone6银色和iphone黑色价格是不一样的。</p>
<p><img loading="lazy" decoding="async" width="678" height="186" class="wp-image-7995" src="/wp-content/uploads/2018/06/word-image-589.png" srcset="/wp-content/uploads/2018/06/word-image-589.png 678w, /wp-content/uploads/2018/06/word-image-589-300x82.png 300w" sizes="(max-width: 678px) 100vw, 678px" /></p>
<p>②属性的值的录入方式</p>
<p><img loading="lazy" decoding="async" width="643" height="114" class="wp-image-7996" src="/wp-content/uploads/2018/06/word-image-590.png" srcset="/wp-content/uploads/2018/06/word-image-590.png 643w, /wp-content/uploads/2018/06/word-image-590-300x53.png 300w" sizes="(max-width: 643px) 100vw, 643px" /></p>
<p>手工输入：不可以输入属性值，且可选值列表是禁用状态，只能在添加商品的时候输入属性值。</p>
<p>列表选择：在可选择列表输入一些我们指定的属性值，添加商品的时候，从中选中一个属性值即可。</p>
<p>表结构：</p>
<p><img loading="lazy" decoding="async" width="916" height="162" class="wp-image-7997" src="/wp-content/uploads/2018/06/word-image-591.png" srcset="/wp-content/uploads/2018/06/word-image-591.png 916w, /wp-content/uploads/2018/06/word-image-591-300x53.png 300w, /wp-content/uploads/2018/06/word-image-591-768x136.png 768w" sizes="(max-width: 916px) 100vw, 916px" /></p>
<h2>完成商品属性的添加</h2>
<ol>
<li>在admin-attribute-add方法中完成添加属性的完成</li>
</ol>
<p><img loading="lazy" decoding="async" width="1161" height="711" class="wp-image-7998" src="/wp-content/uploads/2018/06/word-image-592.png" srcset="/wp-content/uploads/2018/06/word-image-592.png 1161w, /wp-content/uploads/2018/06/word-image-592-300x184.png 300w, /wp-content/uploads/2018/06/word-image-592-768x470.png 768w, /wp-content/uploads/2018/06/word-image-592-1024x627.png 1024w" sizes="(max-width: 1161px) 100vw, 1161px" /></p>
<p>Attribute验证器定义验证场景验证：</p>
<p><img loading="lazy" decoding="async" width="1110" height="598" class="wp-image-7999" src="/wp-content/uploads/2018/06/word-image-593.png" srcset="/wp-content/uploads/2018/06/word-image-593.png 1110w, /wp-content/uploads/2018/06/word-image-593-300x162.png 300w, /wp-content/uploads/2018/06/word-image-593-768x414.png 768w, /wp-content/uploads/2018/06/word-image-593-1024x552.png 1024w" sizes="(max-width: 1110px) 100vw, 1110px" /></p>
<p>Attribue模型如下：</p>
<p><img loading="lazy" decoding="async" width="756" height="393" class="wp-image-8000" src="/wp-content/uploads/2018/06/word-image-594.png" srcset="/wp-content/uploads/2018/06/word-image-594.png 756w, /wp-content/uploads/2018/06/word-image-594-300x156.png 300w" sizes="(max-width: 756px) 100vw, 756px" /></p>
<ol>
<li>在add.html模板中设置表单name属性值</li>
</ol>
<p><img loading="lazy" decoding="async" width="1219" height="683" class="wp-image-8001" src="/wp-content/uploads/2018/06/word-image-595.png" srcset="/wp-content/uploads/2018/06/word-image-595.png 1219w, /wp-content/uploads/2018/06/word-image-595-300x168.png 300w, /wp-content/uploads/2018/06/word-image-595-768x430.png 768w, /wp-content/uploads/2018/06/word-image-595-1024x574.png 1024w" sizes="(max-width: 1219px) 100vw, 1219px" /> <img loading="lazy" decoding="async" width="653" height="125" class="wp-image-8002" src="/wp-content/uploads/2018/06/word-image-596.png" srcset="/wp-content/uploads/2018/06/word-image-596.png 653w, /wp-content/uploads/2018/06/word-image-596-300x57.png 300w" sizes="(max-width: 653px) 100vw, 653px" /></p>
<p>注意：当选择手工输入的时候，可选择列表是禁用disabled,若是列表选择，变为可用</p>
<p>代码如下：</p>
<p><img loading="lazy" decoding="async" width="1002" height="373" class="wp-image-8003" src="/wp-content/uploads/2018/06/word-image-597.png" srcset="/wp-content/uploads/2018/06/word-image-597.png 1002w, /wp-content/uploads/2018/06/word-image-597-300x112.png 300w, /wp-content/uploads/2018/06/word-image-597-768x286.png 768w" sizes="(max-width: 1002px) 100vw, 1002px" /></p>
<h2>完成属性的列表</h2>
<ol>
<li>在admin-attribue-index方法中取出所有的属性数据，分配到模板中</li>
</ol>
<p><img loading="lazy" decoding="async" width="1026" height="476" class="wp-image-8004" src="/wp-content/uploads/2018/06/word-image-598.png" srcset="/wp-content/uploads/2018/06/word-image-598.png 1026w, /wp-content/uploads/2018/06/word-image-598-300x139.png 300w, /wp-content/uploads/2018/06/word-image-598-768x356.png 768w, /wp-content/uploads/2018/06/word-image-598-1024x475.png 1024w" sizes="(max-width: 1026px) 100vw, 1026px" /></p>
<ol>
<li>模板中遍历权限数据</li>
</ol>
<p>联表方式：</p>
<p><img loading="lazy" decoding="async" width="984" height="518" class="wp-image-8005" src="/wp-content/uploads/2018/06/word-image-599.png" srcset="/wp-content/uploads/2018/06/word-image-599.png 984w, /wp-content/uploads/2018/06/word-image-599-300x158.png 300w, /wp-content/uploads/2018/06/word-image-599-768x404.png 768w" sizes="(max-width: 984px) 100vw, 984px" /></p>
<p>不联表方式：</p>
<p><img loading="lazy" decoding="async" width="1224" height="344" class="wp-image-8006" src="/wp-content/uploads/2018/06/word-image-600.png" srcset="/wp-content/uploads/2018/06/word-image-600.png 1224w, /wp-content/uploads/2018/06/word-image-600-300x84.png 300w, /wp-content/uploads/2018/06/word-image-600-768x216.png 768w, /wp-content/uploads/2018/06/word-image-600-1024x288.png 1024w" sizes="(max-width: 1224px) 100vw, 1224px" /></p>
<h2>完成属性的编辑</h2>
<p>1、修改index.html的编辑的链接地址</p>
<p><img loading="lazy" decoding="async" width="1272" height="394" class="wp-image-8007" src="/wp-content/uploads/2018/06/word-image-601.png" srcset="/wp-content/uploads/2018/06/word-image-601.png 1272w, /wp-content/uploads/2018/06/word-image-601-300x93.png 300w, /wp-content/uploads/2018/06/word-image-601-768x238.png 768w, /wp-content/uploads/2018/06/word-image-601-1024x317.png 1024w" sizes="(max-width: 1272px) 100vw, 1272px" /></p>
<ol>
<li>在admin-attribute-upd方法中取出数据回显到模板中，并完成编辑的入库实现</li>
</ol>
<p><img loading="lazy" decoding="async" width="1065" height="702" class="wp-image-8008" src="/wp-content/uploads/2018/06/word-image-602.png" srcset="/wp-content/uploads/2018/06/word-image-602.png 1065w, /wp-content/uploads/2018/06/word-image-602-300x198.png 300w, /wp-content/uploads/2018/06/word-image-602-768x506.png 768w, /wp-content/uploads/2018/06/word-image-602-1024x675.png 1024w" sizes="(max-width: 1065px) 100vw, 1065px" /></p>
<p>3、模板中显示数据</p>
<p><img loading="lazy" decoding="async" width="1206" height="708" class="wp-image-8009" src="/wp-content/uploads/2018/06/word-image-603.png" srcset="/wp-content/uploads/2018/06/word-image-603.png 1206w, /wp-content/uploads/2018/06/word-image-603-300x176.png 300w, /wp-content/uploads/2018/06/word-image-603-768x451.png 768w, /wp-content/uploads/2018/06/word-image-603-1024x601.png 1024w" sizes="(max-width: 1206px) 100vw, 1206px" /></p>
<p>让单选框两种方式默认选中：</p>
<p>方式一：</p>
<p><img loading="lazy" decoding="async" width="991" height="305" class="wp-image-8010" src="/wp-content/uploads/2018/06/word-image-604.png" srcset="/wp-content/uploads/2018/06/word-image-604.png 991w, /wp-content/uploads/2018/06/word-image-604-300x92.png 300w, /wp-content/uploads/2018/06/word-image-604-768x236.png 768w" sizes="(max-width: 991px) 100vw, 991px" /></p>
<p>方式二：通过Jq实现，推荐写法</p>
<p><img loading="lazy" decoding="async" width="1156" height="618" class="wp-image-8011" src="/wp-content/uploads/2018/06/word-image-605.png" srcset="/wp-content/uploads/2018/06/word-image-605.png 1156w, /wp-content/uploads/2018/06/word-image-605-300x160.png 300w, /wp-content/uploads/2018/06/word-image-605-768x411.png 768w, /wp-content/uploads/2018/06/word-image-605-1024x547.png 1024w" sizes="(max-width: 1156px) 100vw, 1156px" /></p>
<h2>ajax完成商品属性的删除</h2>
<ol>
<li>给删除链接地址，绑定class和attr_id自定义属性，并且阻止默认行为</li>
</ol>
<p><img loading="lazy" decoding="async" width="1250" height="355" class="wp-image-8012" src="/wp-content/uploads/2018/06/word-image-606.png" srcset="/wp-content/uploads/2018/06/word-image-606.png 1250w, /wp-content/uploads/2018/06/word-image-606-300x85.png 300w, /wp-content/uploads/2018/06/word-image-606-768x218.png 768w, /wp-content/uploads/2018/06/word-image-606-1024x291.png 1024w" sizes="(max-width: 1250px) 100vw, 1250px" /></p>
<ol>
<li>给class=delAttr绑定单击事件，使用ajax进行删除</li>
</ol>
<p><img loading="lazy" decoding="async" width="1173" height="468" class="wp-image-8013" src="/wp-content/uploads/2018/06/word-image-607.png" srcset="/wp-content/uploads/2018/06/word-image-607.png 1173w, /wp-content/uploads/2018/06/word-image-607-300x120.png 300w, /wp-content/uploads/2018/06/word-image-607-768x306.png 768w, /wp-content/uploads/2018/06/word-image-607-1024x409.png 1024w" sizes="(max-width: 1173px) 100vw, 1173px" /></p>
<ol>
<li>在admin-attribute-ajaxDel方法中完成删除的实现</li>
</ol>
<h1>四、完成商品分类的curd</h1>
<h2>1、分析分类表结构</h2>
<p>表字段结构如下：</p>
<p><img loading="lazy" decoding="async" width="760" height="153" class="wp-image-8014" src="/wp-content/uploads/2018/06/word-image-608.png" srcset="/wp-content/uploads/2018/06/word-image-608.png 760w, /wp-content/uploads/2018/06/word-image-608-300x60.png 300w" sizes="(max-width: 760px) 100vw, 760px" /></p>
<h2>完成商品分类的添加</h2>
<p>找当前分类的祖先分类：传递当前分类的pid ,谁的cat_id等于我的pid就找到我的祖先。</p>
<p>找当前分类的子孙分类：传递当前分类的cat_id ,谁的pid等于我的cat_id就找到我的子孙</p>
<ol>
<li>在admin-category-add方法中完成添加分类的完成</li>
</ol>
<p><img loading="lazy" decoding="async" width="949" height="536" class="wp-image-8015" src="/wp-content/uploads/2018/06/word-image-609.png" srcset="/wp-content/uploads/2018/06/word-image-609.png 949w, /wp-content/uploads/2018/06/word-image-609-300x169.png 300w, /wp-content/uploads/2018/06/word-image-609-768x434.png 768w" sizes="(max-width: 949px) 100vw, 949px" /></p>
<p>验证器：</p>
<p><img loading="lazy" decoding="async" width="730" height="546" class="wp-image-8016" src="/wp-content/uploads/2018/06/word-image-610.png" srcset="/wp-content/uploads/2018/06/word-image-610.png 730w, /wp-content/uploads/2018/06/word-image-610-300x224.png 300w" sizes="(max-width: 730px) 100vw, 730px" /></p>
<p>模型：</p>
<p><img loading="lazy" decoding="async" width="1109" height="639" class="wp-image-8017" src="/wp-content/uploads/2018/06/word-image-611.png" srcset="/wp-content/uploads/2018/06/word-image-611.png 1109w, /wp-content/uploads/2018/06/word-image-611-300x173.png 300w, /wp-content/uploads/2018/06/word-image-611-768x443.png 768w, /wp-content/uploads/2018/06/word-image-611-1024x590.png 1024w" sizes="(max-width: 1109px) 100vw, 1109px" /></p>
<p>2、在add.html模板中设置表单name属性值</p>
<p><img loading="lazy" decoding="async" width="1196" height="591" class="wp-image-8018" src="/wp-content/uploads/2018/06/word-image-612.png" srcset="/wp-content/uploads/2018/06/word-image-612.png 1196w, /wp-content/uploads/2018/06/word-image-612-300x148.png 300w, /wp-content/uploads/2018/06/word-image-612-768x380.png 768w, /wp-content/uploads/2018/06/word-image-612-1024x506.png 1024w" sizes="(max-width: 1196px) 100vw, 1196px" /></p>
<h2>完成商品分类的列表</h2>
<ol>
<li>在admin-category-index方法中取出所有的分类数据，分配到模板中</li>
</ol>
<p><img loading="lazy" decoding="async" width="785" height="352" class="wp-image-8019" src="/wp-content/uploads/2018/06/word-image-613.png" srcset="/wp-content/uploads/2018/06/word-image-613.png 785w, /wp-content/uploads/2018/06/word-image-613-300x135.png 300w, /wp-content/uploads/2018/06/word-image-613-768x344.png 768w" sizes="(max-width: 785px) 100vw, 785px" /></p>
<p>同时为了不用联表，把分类的无限级分类的以cat_id作为下标</p>
<p><img loading="lazy" decoding="async" width="1126" height="457" class="wp-image-8020" src="/wp-content/uploads/2018/06/word-image-614.png" srcset="/wp-content/uploads/2018/06/word-image-614.png 1126w, /wp-content/uploads/2018/06/word-image-614-300x122.png 300w, /wp-content/uploads/2018/06/word-image-614-768x312.png 768w, /wp-content/uploads/2018/06/word-image-614-1024x416.png 1024w" sizes="(max-width: 1126px) 100vw, 1126px" /></p>
<p>2、模板index.html中遍历分类数据</p>
<p><img loading="lazy" decoding="async" width="1279" height="572" class="wp-image-8021" src="/wp-content/uploads/2018/06/word-image-615.png" srcset="/wp-content/uploads/2018/06/word-image-615.png 1279w, /wp-content/uploads/2018/06/word-image-615-300x134.png 300w, /wp-content/uploads/2018/06/word-image-615-768x343.png 768w, /wp-content/uploads/2018/06/word-image-615-1024x458.png 1024w" sizes="(max-width: 1279px) 100vw, 1279px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="1156" height="241" class="wp-image-8022" src="/wp-content/uploads/2018/06/word-image-616.png" srcset="/wp-content/uploads/2018/06/word-image-616.png 1156w, /wp-content/uploads/2018/06/word-image-616-300x63.png 300w, /wp-content/uploads/2018/06/word-image-616-768x160.png 768w, /wp-content/uploads/2018/06/word-image-616-1024x213.png 1024w" sizes="(max-width: 1156px) 100vw, 1156px" /></p>
<h2>完成商品分类的编辑</h2>
<ol>
<li>修改index.html的编辑的链接地址</li>
</ol>
<p><img loading="lazy" decoding="async" width="1258" height="353" class="wp-image-8023" src="/wp-content/uploads/2018/06/word-image-617.png" srcset="/wp-content/uploads/2018/06/word-image-617.png 1258w, /wp-content/uploads/2018/06/word-image-617-300x84.png 300w, /wp-content/uploads/2018/06/word-image-617-768x216.png 768w, /wp-content/uploads/2018/06/word-image-617-1024x287.png 1024w" sizes="(max-width: 1258px) 100vw, 1258px" /></p>
<p>2、在admin-category-upd方法中完取出当前分类的数据回显到模板中，并完成编辑入库的实现</p>
<p><img loading="lazy" decoding="async" width="1000" height="644" class="wp-image-8024" src="/wp-content/uploads/2018/06/word-image-618.png" srcset="/wp-content/uploads/2018/06/word-image-618.png 1000w, /wp-content/uploads/2018/06/word-image-618-300x193.png 300w, /wp-content/uploads/2018/06/word-image-618-768x495.png 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></p>
<h2>5、【作业】完成商品分类的删除</h2>
<p>自行完成</p>
<p>CategoryController:</p>
<p><img loading="lazy" decoding="async" width="577" height="326" class="wp-image-8025" src="/wp-content/uploads/2018/06/word-image-619.png" srcset="/wp-content/uploads/2018/06/word-image-619.png 577w, /wp-content/uploads/2018/06/word-image-619-300x169.png 300w" sizes="(max-width: 577px) 100vw, 577px" /></p>
<p>Html:</p>
<p><img loading="lazy" decoding="async" width="883" height="122" class="wp-image-8026" src="/wp-content/uploads/2018/06/word-image-620.png" srcset="/wp-content/uploads/2018/06/word-image-620.png 883w, /wp-content/uploads/2018/06/word-image-620-300x41.png 300w, /wp-content/uploads/2018/06/word-image-620-768x106.png 768w" sizes="(max-width: 883px) 100vw, 883px" /> <img loading="lazy" decoding="async" width="734" height="403" class="wp-image-8027" src="/wp-content/uploads/2018/06/word-image-621.png" srcset="/wp-content/uploads/2018/06/word-image-621.png 734w, /wp-content/uploads/2018/06/word-image-621-300x165.png 300w" sizes="(max-width: 734px) 100vw, 734px" /></p>
<h1>六、完成商品类型列表中属性的查看</h1>
<h1>七、完成商品的添加</h1>
<h2>商品的认识</h2>
<p>商品=产品+商品属性，即同一个产品，但是商品属性不同，就不是同一个商品。</p>
<p>如：iphone6s黑色 和iphone6s银色</p>
<h2>商品添加所需的数据表</h2>
<p>当在后台添加一个商品的时候，商品相关数据需要入库到以下两个表：</p>
<p>商品表sh_goods和商品属性表sh_goods_attr</p>
<p><img loading="lazy" decoding="async" width="159" height="40" class="wp-image-8028" src="/wp-content/uploads/2018/06/word-image-622.png" /></p>
<p>商品的基本信息数据存储在sh_goods表中，商品属性数据存储在sh_goods_attr中</p>
<p>商品表sh_goods表结构：</p>
<p>商品属性表sh_goods_attr表结构：</p>
<h2>完成商品基本信息的入库</h2>
<h3>（1）展示添加商品模板</h3>
<h3>基本信息入库操作</h3>
<h2>4、添加商品的多图片上传</h2>
<h3>（1）思路分析</h3>
<p>实现思路：可以参考ecshop开源商城：</p>
<p><img loading="lazy" decoding="async" width="985" height="188" class="wp-image-8029" src="/wp-content/uploads/2018/06/word-image-623.png" srcset="/wp-content/uploads/2018/06/word-image-623.png 985w, /wp-content/uploads/2018/06/word-image-623-300x57.png 300w, /wp-content/uploads/2018/06/word-image-623-768x147.png 768w" sizes="(max-width: 985px) 100vw, 985px" /></p>
<p>①构建布局：</p>
<p>每个文件上传域名其实可以看做是一个li标签，其中包含a标签和input上传文件域</p>
<p>如下结构：</p>
<p>&lt;li&gt; &lt;a href=’javascript:;’ &gt;[+]&lt;/a&gt;&lt;input type=’file’/&gt; &lt;/li&gt;</p>
<p>&lt;li&gt; &lt;a href=’javascript:;’ &gt;[-]&lt;/a&gt;&lt;input type=’file’/&gt; &lt;/li&gt;</p>
<p>②怎么实现图片前的[+][-]加减功能？</p>
<p>思路：</p>
<ol>
<li>给li中的a标签绑定单击事件，获取当前单击元素的内容</li>
<li>判断内容，含两种情况[+]、[-]</li>
</ol>
<p>若是[+]: 则获取当前元素的父元素（即li），克隆一份，在把内部的a标签的[+]变成[-]。</p>
<p>若是[-]: 则获取当前元素的父元素（即li），并移除。</p>
<h3>多图片上传加减特效</h3>
<h3>实现多图片的上传</h3>
<h3>（4）生成多图片的缩略图</h3>
<p>生成缩略图的步骤：</p>
<ul>
<li>Image打开源图片 $image = \Think\Image::open(源图片);</li>
<li>进行缩放处理 $image -&gt; thumb(宽度，高度，类型)</li>
<li>把缩放好的图片保存到服务器上 $image -&gt; save(小图路径名);</li>
</ul>
<h1>八、完成商品的属性添加</h1>
<h2>1、分析商品动态属性的生成</h2>
<p>添加一个商品，其商品属性可能有多个。</p>
<p>即商品表sh_goods的一条记录对应商品属性表sh_goods_attr的多条记录，属于一对多关系。</p>
<p>问题：怎么给商品设置商品属性？</p>
<p>这里可以参考ecshop的方案，当添加商品的,必须先选择一个商品类型，在通过ajax动态获取商品类型的属性，再给商品设置这些属性值。</p>
<p>如在ecshop后台添加商品的时候，选择手机类型，动态生成的属性框如下：</p>
<p><img loading="lazy" decoding="async" width="1084" height="312" class="wp-image-8030" src="/wp-content/uploads/2018/06/word-image-624.png" srcset="/wp-content/uploads/2018/06/word-image-624.png 1084w, /wp-content/uploads/2018/06/word-image-624-300x86.png 300w, /wp-content/uploads/2018/06/word-image-624-768x221.png 768w, /wp-content/uploads/2018/06/word-image-624-1024x295.png 1024w" sizes="(max-width: 1084px) 100vw, 1084px" /></p>
<p>从上面添加商品属性可以看出，动态生成商品属性的时候，共有四种组合情况。</p>
<p>其实就是属性类型和属性值录入方式的互相组合：</p>
<p>①唯一属性+手工输入</p>
<p>②唯一属性+列表选择</p>
<p>③单选属性+手工输入</p>
<p>④单选属性+列表选择</p>
<p>其实可以把上面每个动态生成的属性信息看作是被包含在一个li标签中。</p>
<p>分析四种组合情况生成动态属性的特点如下：</p>
<p>元素从左到右分析：</p>
<ul>
<li>单选属性属性名称前有个[+]或[-]号，可以进行加减，而唯一属性则没有</li>
<li>属性名称</li>
<li>属性值录入方式为手工输入，则对应属性值的输入方式的是一个输入框(&lt;input type=’text’/&gt;)，而属性值录入方式为列表选择的时候则对应属性值的输入方式的是一个select下拉框。</li>
<li>单选属性可以输入价格，而唯一属性则没有</li>
</ul>
<h2>完成商品的动态属性生成</h2>
<h2>完成商品动态属性的入库</h2>
<p>分析：</p>
<p>把单选属性值和单选属性价格通过属性attr_id归为同一组，方便后续获取对应属性的价格和值。</p>
<p>单选属性值： name=goodsAttrValue[attr_id][]</p>
<p>单选属性值价格： name=goodsAttrValue[attr_id][]</p>
<p>因为单选属性用户可以点击[+]号会生成多个，所以多个单选属性值和价格name的值后面都必须加上中括号[]。</p>
<p>由于唯一属性只能选择一个值，所以name后不需要加[]</p>
<h1>九、商品列表展示</h1>
<h1>十、使用ajax+layer弹出层查看商品详情</h1>
]]></content:encoded>
					
					<wfw:commentRss>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/7899.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TP5 商城（四）商品属性、商品添加、图片上传、商品列表、ajax+layer 展示商品详情</title>
		<link>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/8031.html</link>
					<comments>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/8031.html#respond</comments>
		
		<dc:creator><![CDATA[Mr.Lee]]></dc:creator>
		<pubDate>Sat, 09 Jun 2018 00:37:00 +0000</pubDate>
				<category><![CDATA[TP5.0]]></category>
		<category><![CDATA[TP5.0商城]]></category>
		<category><![CDATA[后台框架]]></category>
		<category><![CDATA[ajax+layer 展示商品详情]]></category>
		<category><![CDATA[商品列表]]></category>
		<category><![CDATA[商品属性]]></category>
		<category><![CDATA[商品添加]]></category>
		<category><![CDATA[图片上传]]></category>
		<guid isPermaLink="false">/?p=8031</guid>

					<description><![CDATA[一、查看商品类型属性 不同的商品类型其属性也是不一样的。 在admin-view-type-index.htm [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>一、查看商品类型属性</h1>
<p>不同的商品类型其属性也是不一样的。</p>
<ol>
<li>在admin-view-type-index.html修改链接地址</li>
</ol>
<p><img loading="lazy" decoding="async" width="1241" height="484" class="wp-image-8093" src="/wp-content/uploads/2018/06/word-image-684.png" srcset="/wp-content/uploads/2018/06/word-image-684.png 1241w, /wp-content/uploads/2018/06/word-image-684-300x117.png 300w, /wp-content/uploads/2018/06/word-image-684-768x300.png 768w, /wp-content/uploads/2018/06/word-image-684-1024x399.png 1024w" sizes="(max-width: 1241px) 100vw, 1241px" /></p>
<ol>
<li>在admin-typeController-getAttr方法中，取出当前分类所有的属性展示在模板中</li>
</ol>
<p><img loading="lazy" decoding="async" width="987" height="385" class="wp-image-8094" src="/wp-content/uploads/2018/06/word-image-685.png" srcset="/wp-content/uploads/2018/06/word-image-685.png 987w, /wp-content/uploads/2018/06/word-image-685-300x117.png 300w, /wp-content/uploads/2018/06/word-image-685-768x300.png 768w" sizes="(max-width: 987px) 100vw, 987px" /></p>
<ol>
<li>模板中遍历数据</li>
</ol>
<p><img loading="lazy" decoding="async" width="1257" height="500" class="wp-image-8095" src="/wp-content/uploads/2018/06/word-image-686.png" srcset="/wp-content/uploads/2018/06/word-image-686.png 1257w, /wp-content/uploads/2018/06/word-image-686-300x119.png 300w, /wp-content/uploads/2018/06/word-image-686-768x305.png 768w, /wp-content/uploads/2018/06/word-image-686-1024x407.png 1024w" sizes="(max-width: 1257px) 100vw, 1257px" /></p>
<h1>二、去除编辑属性时属性值的多个空格</h1>
<p>修改admin/view/attribute/upd.html模板</p>
<p><img loading="lazy" decoding="async" width="1003" height="339" class="wp-image-8096" src="/wp-content/uploads/2018/06/word-image-687.png" srcset="/wp-content/uploads/2018/06/word-image-687.png 1003w, /wp-content/uploads/2018/06/word-image-687-300x101.png 300w, /wp-content/uploads/2018/06/word-image-687-768x260.png 768w" sizes="(max-width: 1003px) 100vw, 1003px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="574" height="120" class="wp-image-8097" src="/wp-content/uploads/2018/06/word-image-688.png" srcset="/wp-content/uploads/2018/06/word-image-688.png 574w, /wp-content/uploads/2018/06/word-image-688-300x63.png 300w" sizes="(max-width: 574px) 100vw, 574px" /></p>
<h1>三、完成商品的添加</h1>
<h2>商品的认识</h2>
<p>商品=产品+商品属性，即同一个产品，但是商品属性不同，就不是同一个商品，且价格也不同。</p>
<p>如：iphone6s黑色 和iphone6s银色</p>
<h2>商品添加所需的数据表</h2>
<p>当在后台添加一个商品的时候，商品相关数据需要入库到以下两个表：</p>
<p>商品表sh_goods和商品属性表sh_goods_attr</p>
<p><img loading="lazy" decoding="async" width="159" height="40" class="wp-image-8098" src="/wp-content/uploads/2018/06/word-image-689.png" /></p>
<p>商品的基本信息数据存储在sh_goods表中，商品属性数据存储在sh_goods_attr中</p>
<p>商品表sh_goods表结构：</p>
<p><img loading="lazy" decoding="async" width="967" height="381" class="wp-image-8099" src="/wp-content/uploads/2018/06/word-image-690.png" srcset="/wp-content/uploads/2018/06/word-image-690.png 967w, /wp-content/uploads/2018/06/word-image-690-300x118.png 300w, /wp-content/uploads/2018/06/word-image-690-768x303.png 768w" sizes="(max-width: 967px) 100vw, 967px" /></p>
<p>注：给我们的商品表添加一个goods_middle字段，存储图片的生成的中图的路径</p>
<p><img loading="lazy" decoding="async" width="731" height="200" class="wp-image-8100" src="/wp-content/uploads/2018/06/word-image-691.png" srcset="/wp-content/uploads/2018/06/word-image-691.png 731w, /wp-content/uploads/2018/06/word-image-691-300x82.png 300w" sizes="(max-width: 731px) 100vw, 731px" /></p>
<p>商品属性表sh_goods_attr表结构：</p>
<p><img loading="lazy" decoding="async" width="935" height="267" class="wp-image-8102" src="/wp-content/uploads/2018/06/word-image-692.png" srcset="/wp-content/uploads/2018/06/word-image-692.png 935w, /wp-content/uploads/2018/06/word-image-692-300x86.png 300w, /wp-content/uploads/2018/06/word-image-692-768x219.png 768w" sizes="(max-width: 935px) 100vw, 935px" /></p>
<h2>完成商品基本信息的入库</h2>
<p>基本信息：商品名称、商品价格、库存、详情、是否热卖&#8230;..</p>
<h3>展示添加商品模板</h3>
<ol>
<li>在admin-GoodsController-add方法中，输出添加商品的模板</li>
</ol>
<p><img loading="lazy" decoding="async" width="889" height="348" class="wp-image-8103" src="/wp-content/uploads/2018/06/word-image-693.png" srcset="/wp-content/uploads/2018/06/word-image-693.png 889w, /wp-content/uploads/2018/06/word-image-693-300x117.png 300w, /wp-content/uploads/2018/06/word-image-693-768x301.png 768w" sizes="(max-width: 889px) 100vw, 889px" /></p>
<ol>
<li>把后台的添加商品的模板复制到admin/view/goods/目录下面，并且修改静态资源路径</li>
</ol>
<p><img loading="lazy" decoding="async" width="762" height="305" class="wp-image-8104" src="/wp-content/uploads/2018/06/word-image-694.png" srcset="/wp-content/uploads/2018/06/word-image-694.png 762w, /wp-content/uploads/2018/06/word-image-694-300x120.png 300w" sizes="(max-width: 762px) 100vw, 762px" /></p>
<p>模板是四个选项卡构成：</p>
<p><img loading="lazy" decoding="async" width="1252" height="541" class="wp-image-8105" src="/wp-content/uploads/2018/06/word-image-695.png" srcset="/wp-content/uploads/2018/06/word-image-695.png 1252w, /wp-content/uploads/2018/06/word-image-695-300x130.png 300w, /wp-content/uploads/2018/06/word-image-695-768x332.png 768w, /wp-content/uploads/2018/06/word-image-695-1024x442.png 1024w" sizes="(max-width: 1252px) 100vw, 1252px" /></p>
<p>先修改第一个和第四选项卡的name名称：</p>
<p>第一个选项卡：</p>
<p><img loading="lazy" decoding="async" width="1217" height="599" class="wp-image-8106" src="/wp-content/uploads/2018/06/word-image-696.png" srcset="/wp-content/uploads/2018/06/word-image-696.png 1217w, /wp-content/uploads/2018/06/word-image-696-300x148.png 300w, /wp-content/uploads/2018/06/word-image-696-768x378.png 768w, /wp-content/uploads/2018/06/word-image-696-1024x504.png 1024w" sizes="(max-width: 1217px) 100vw, 1217px" /> <img loading="lazy" decoding="async" width="1118" height="625" class="wp-image-8107" src="/wp-content/uploads/2018/06/word-image-697.png" srcset="/wp-content/uploads/2018/06/word-image-697.png 1118w, /wp-content/uploads/2018/06/word-image-697-300x168.png 300w, /wp-content/uploads/2018/06/word-image-697-768x429.png 768w, /wp-content/uploads/2018/06/word-image-697-1024x572.png 1024w" sizes="(max-width: 1118px) 100vw, 1118px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="526" height="488" class="wp-image-8108" src="/wp-content/uploads/2018/06/word-image-698.png" srcset="/wp-content/uploads/2018/06/word-image-698.png 526w, /wp-content/uploads/2018/06/word-image-698-300x278.png 300w" sizes="(max-width: 526px) 100vw, 526px" /></p>
<p>第四个选项卡内容：</p>
<p><img loading="lazy" decoding="async" width="880" height="418" class="wp-image-8109" src="/wp-content/uploads/2018/06/word-image-699.png" srcset="/wp-content/uploads/2018/06/word-image-699.png 880w, /wp-content/uploads/2018/06/word-image-699-300x143.png 300w, /wp-content/uploads/2018/06/word-image-699-768x365.png 768w" sizes="(max-width: 880px) 100vw, 880px" /></p>
<h3>基本信息入库操作</h3>
<ol>
<li>定义添加商品的验证器Goods</li>
</ol>
<p><img loading="lazy" decoding="async" width="1145" height="592" class="wp-image-8110" src="/wp-content/uploads/2018/06/word-image-700.png" srcset="/wp-content/uploads/2018/06/word-image-700.png 1145w, /wp-content/uploads/2018/06/word-image-700-300x155.png 300w, /wp-content/uploads/2018/06/word-image-700-768x397.png 768w, /wp-content/uploads/2018/06/word-image-700-1024x529.png 1024w" sizes="(max-width: 1145px) 100vw, 1145px" /></p>
<ol>
<li>在admin-GoodsController-add 方法中完成商品的入库操作</li>
</ol>
<p><img loading="lazy" decoding="async" width="949" height="620" class="wp-image-8111" src="/wp-content/uploads/2018/06/word-image-701.png" srcset="/wp-content/uploads/2018/06/word-image-701.png 949w, /wp-content/uploads/2018/06/word-image-701-300x196.png 300w, /wp-content/uploads/2018/06/word-image-701-768x502.png 768w" sizes="(max-width: 949px) 100vw, 949px" /></p>
<ol>
<li>使用ueditor 完成商品的详情</li>
</ol>
<p>引入三个核心js文件：</p>
<p><img loading="lazy" decoding="async" width="1257" height="383" class="wp-image-8112" src="/wp-content/uploads/2018/06/word-image-702.png" srcset="/wp-content/uploads/2018/06/word-image-702.png 1257w, /wp-content/uploads/2018/06/word-image-702-300x91.png 300w, /wp-content/uploads/2018/06/word-image-702-768x234.png 768w, /wp-content/uploads/2018/06/word-image-702-1024x312.png 1024w" sizes="(max-width: 1257px) 100vw, 1257px" /></p>
<p>设置textarea的id,初始化编辑器：</p>
<p><img loading="lazy" decoding="async" width="1236" height="504" class="wp-image-8113" src="/wp-content/uploads/2018/06/word-image-703.png" srcset="/wp-content/uploads/2018/06/word-image-703.png 1236w, /wp-content/uploads/2018/06/word-image-703-300x122.png 300w, /wp-content/uploads/2018/06/word-image-703-768x313.png 768w, /wp-content/uploads/2018/06/word-image-703-1024x418.png 1024w" sizes="(max-width: 1236px) 100vw, 1236px" /></p>
<h2>添加商品的多图片上传</h2>
<p><img loading="lazy" decoding="async" width="901" height="51" class="wp-image-8114" src="/wp-content/uploads/2018/06/word-image-704.png" srcset="/wp-content/uploads/2018/06/word-image-704.png 901w, /wp-content/uploads/2018/06/word-image-704-300x17.png 300w, /wp-content/uploads/2018/06/word-image-704-768x43.png 768w" sizes="(max-width: 901px) 100vw, 901px" /></p>
<p>建议原图上传800*800 ，生成两种缩略图</p>
<p>中图缩略图：350*350 比例为2</p>
<p>小图：50*50 生成缩略图的类型为2位等比例补白</p>
<ol>
<li>上传文件的form两个要求：post提交 和enctype = multipart/form-data</li>
</ol>
<p><img loading="lazy" decoding="async" width="826" height="169" class="wp-image-8115" src="/wp-content/uploads/2018/06/word-image-705.png" srcset="/wp-content/uploads/2018/06/word-image-705.png 826w, /wp-content/uploads/2018/06/word-image-705-300x61.png 300w, /wp-content/uploads/2018/06/word-image-705-768x157.png 768w" sizes="(max-width: 826px) 100vw, 826px" /></p>
<ol>
<li>设置文件上传的name属性，因为是多图上传，所以呢name后需要加[]。</li>
</ol>
<p><img loading="lazy" decoding="async" width="957" height="229" class="wp-image-8116" src="/wp-content/uploads/2018/06/word-image-706.png" srcset="/wp-content/uploads/2018/06/word-image-706.png 957w, /wp-content/uploads/2018/06/word-image-706-300x72.png 300w, /wp-content/uploads/2018/06/word-image-706-768x184.png 768w" sizes="(max-width: 957px) 100vw, 957px" /></p>
<h3>（1）思路分析</h3>
<p>实现思路：可以参考ecshop开源商城：</p>
<p><img loading="lazy" decoding="async" width="985" height="188" class="wp-image-8117" src="/wp-content/uploads/2018/06/word-image-707.png" srcset="/wp-content/uploads/2018/06/word-image-707.png 985w, /wp-content/uploads/2018/06/word-image-707-300x57.png 300w, /wp-content/uploads/2018/06/word-image-707-768x147.png 768w" sizes="(max-width: 985px) 100vw, 985px" /></p>
<p>①构建布局：</p>
<p>每个文件上传域名其实可以看做是一个li标签，其中包含a标签和input上传文件域</p>
<p>如下结构：</p>
<p>&lt;li&gt; &lt;a href=’javascript:;’ &gt;[+]&lt;/a&gt;&lt;input type=’file’/&gt; &lt;/li&gt;</p>
<p>&lt;li&gt; &lt;a href=’javascript:;’ &gt;[-]&lt;/a&gt;&lt;input type=’file’/&gt; &lt;/li&gt;</p>
<p>②怎么实现图片前的[+][-]加减功能？</p>
<p>思路：</p>
<ol>
<li>给li中的a标签绑定单击事件，获取当前单击元素的内容</li>
<li>判断内容，含两种情况[+]、[-]</li>
</ol>
<p>若是[+]: 则获取当前元素的父元素（即li），克隆一份，在把内部的a标签的[+]变成[-]。</p>
<p>若是[-]: 则获取当前元素的父元素（即li），并移除。</p>
<h3>多图片上传加减特效</h3>
<p>1、修改第三个选项卡的内容，设置标签。以及绑定单击事件</p>
<p><img loading="lazy" decoding="async" width="1244" height="382" class="wp-image-8118" src="/wp-content/uploads/2018/06/word-image-708.png" srcset="/wp-content/uploads/2018/06/word-image-708.png 1244w, /wp-content/uploads/2018/06/word-image-708-300x92.png 300w, /wp-content/uploads/2018/06/word-image-708-768x236.png 768w, /wp-content/uploads/2018/06/word-image-708-1024x314.png 1024w" sizes="(max-width: 1244px) 100vw, 1244px" /></p>
<ol>
<li>实现上面的单击事件克隆图片</li>
</ol>
<p>通过看思路实现代码：</p>
<p>思路：</p>
<p>a、给li中的a标签绑定单击事件，获取当前单击元素的内容</p>
<p>b、判断内容，含两种情况[+]、[-]</p>
<p>若是[+]: 则获取当前元素的父元素（即li），克隆一份，在把内部的a标签的[+]变成[-]。</p>
<p>若是[-]: 则获取当前元素的父元素（即li），并移除。</p>
<p><img loading="lazy" decoding="async" width="795" height="408" class="wp-image-8119" src="/wp-content/uploads/2018/06/word-image-709.png" srcset="/wp-content/uploads/2018/06/word-image-709.png 795w, /wp-content/uploads/2018/06/word-image-709-300x154.png 300w, /wp-content/uploads/2018/06/word-image-709-768x394.png 768w" sizes="(max-width: 795px) 100vw, 795px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="512" height="225" class="wp-image-8120" src="/wp-content/uploads/2018/06/word-image-710.png" srcset="/wp-content/uploads/2018/06/word-image-710.png 512w, /wp-content/uploads/2018/06/word-image-710-300x132.png 300w" sizes="(max-width: 512px) 100vw, 512px" /></p>
<h3>实现多图片的上传</h3>
<ol>
<li>在Goods模型中定义一个方法，判断进行图片的原图上传，并返回上传成功的文件路径</li>
</ol>
<p><img loading="lazy" decoding="async" width="971" height="580" class="wp-image-8121" src="/wp-content/uploads/2018/06/word-image-711.png" srcset="/wp-content/uploads/2018/06/word-image-711.png 971w, /wp-content/uploads/2018/06/word-image-711-300x180.png 300w, /wp-content/uploads/2018/06/word-image-711-768x459.png 768w" sizes="(max-width: 971px) 100vw, 971px" /></p>
<ol>
<li>add方法中进行调用上面的方法，把图片的路径转化为json格式存储到表对应字段中</li>
</ol>
<p><img loading="lazy" decoding="async" width="1127" height="599" class="wp-image-8122" src="/wp-content/uploads/2018/06/word-image-712.png" srcset="/wp-content/uploads/2018/06/word-image-712.png 1127w, /wp-content/uploads/2018/06/word-image-712-300x159.png 300w, /wp-content/uploads/2018/06/word-image-712-768x408.png 768w, /wp-content/uploads/2018/06/word-image-712-1024x544.png 1024w" sizes="(max-width: 1127px) 100vw, 1127px" /></p>
<h3>（4）生成多图片的缩略图</h3>
<p>生成缩略图的步骤：</p>
<ul>
<li>Image打开源图片 $image = \Think\Image::open(源图片);</li>
<li>进行缩放处理 $image -&gt; thumb(宽度，高度，类型)</li>
<li>把缩放好的图片保存到服务器上 $image -&gt; save(小图路径名);</li>
</ul>
<ol>
<li>在goods模型中定义处理原图缩放的方法</li>
</ol>
<p><img loading="lazy" decoding="async" width="1040" height="699" class="wp-image-8123" src="/wp-content/uploads/2018/06/word-image-713.png" srcset="/wp-content/uploads/2018/06/word-image-713.png 1040w, /wp-content/uploads/2018/06/word-image-713-300x202.png 300w, /wp-content/uploads/2018/06/word-image-713-768x516.png 768w, /wp-content/uploads/2018/06/word-image-713-1024x688.png 1024w" sizes="(max-width: 1040px) 100vw, 1040px" /></p>
<ol>
<li>add方法中若原图上传成功，则调用上面的方法进行缩略图处理</li>
</ol>
<p><img loading="lazy" decoding="async" width="1215" height="705" class="wp-image-8124" src="/wp-content/uploads/2018/06/word-image-714.png" srcset="/wp-content/uploads/2018/06/word-image-714.png 1215w, /wp-content/uploads/2018/06/word-image-714-300x174.png 300w, /wp-content/uploads/2018/06/word-image-714-768x446.png 768w, /wp-content/uploads/2018/06/word-image-714-1024x594.png 1024w" sizes="(max-width: 1215px) 100vw, 1215px" /></p>
<p>最终生成的各图片名：</p>
<p><img loading="lazy" decoding="async" width="358" height="440" class="wp-image-8125" src="/wp-content/uploads/2018/06/word-image-715.png" srcset="/wp-content/uploads/2018/06/word-image-715.png 358w, /wp-content/uploads/2018/06/word-image-715-244x300.png 244w" sizes="(max-width: 358px) 100vw, 358px" /></p>
<h1>三、[难点-重点]完成商品的属性添加</h1>
<h2>1、分析商品动态属性的生成</h2>
<p>添加一个商品，其商品属性可能有多个。</p>
<p>即商品表sh_goods的一条记录对应商品属性表sh_goods_attr的多条记录，属于一对多关系。</p>
<p>问题：怎么给商品设置商品属性？</p>
<p>这里可以参考ecshop的方案，当添加商品的,必须先选择一个商品类型，在通过ajax动态获取商品类型的属性，再给商品设置这些属性值。</p>
<p>如在ecshop后台添加商品的时候，选择手机类型，动态生成的属性框如下：</p>
<p><img loading="lazy" decoding="async" width="1084" height="312" class="wp-image-8126" src="/wp-content/uploads/2018/06/word-image-716.png" srcset="/wp-content/uploads/2018/06/word-image-716.png 1084w, /wp-content/uploads/2018/06/word-image-716-300x86.png 300w, /wp-content/uploads/2018/06/word-image-716-768x221.png 768w, /wp-content/uploads/2018/06/word-image-716-1024x295.png 1024w" sizes="(max-width: 1084px) 100vw, 1084px" /></p>
<p>从上面添加商品属性可以看出，动态生成商品属性的时候，共有4种组合情况。</p>
<p>其实就是属性类型和属性值录入方式的互相组合：</p>
<p>①唯一属性+手工输入</p>
<p>②唯一属性+列表选择</p>
<p>③单选属性+手工输入</p>
<p>④单选属性+列表选择</p>
<p>其实可以把上面每个动态生成的属性信息看作是被包含在一个li标签中。</p>
<p>分析四种组合情况生成动态属性的特点如下：元素从左到右分析：</p>
<p><img loading="lazy" decoding="async" width="1084" height="312" class="wp-image-8127" src="/wp-content/uploads/2018/06/word-image-717.png" srcset="/wp-content/uploads/2018/06/word-image-717.png 1084w, /wp-content/uploads/2018/06/word-image-717-300x86.png 300w, /wp-content/uploads/2018/06/word-image-717-768x221.png 768w, /wp-content/uploads/2018/06/word-image-717-1024x295.png 1024w" sizes="(max-width: 1084px) 100vw, 1084px" /> <img loading="lazy" decoding="async" width="857" height="274" class="wp-image-8128" src="/wp-content/uploads/2018/06/word-image-718.png" srcset="/wp-content/uploads/2018/06/word-image-718.png 857w, /wp-content/uploads/2018/06/word-image-718-300x96.png 300w, /wp-content/uploads/2018/06/word-image-718-768x246.png 768w" sizes="(max-width: 857px) 100vw, 857px" /></p>
<ul>
<li>单选属性属性名称前有个[+]或[-]号，可以进行加减，而唯一属性则没有</li>
<li>属性名称</li>
<li>属性值录入方式为手工输入，则对应属性值的输入方式的是一个输入框(&lt;input type=’text’/&gt;)，而属性值录入方式为列表选择的时候则对应属性值的输入方式的是一个select下拉框。</li>
<li>单选属性可以输入价格，而唯一属性则没有</li>
</ul>
<h2>完成商品的动态属性生成</h2>
<ol>
<li>在商品添加的add方法中取出所有的商品类型</li>
</ol>
<p><img loading="lazy" decoding="async" width="919" height="281" class="wp-image-8129" src="/wp-content/uploads/2018/06/word-image-719.png" srcset="/wp-content/uploads/2018/06/word-image-719.png 919w, /wp-content/uploads/2018/06/word-image-719-300x92.png 300w, /wp-content/uploads/2018/06/word-image-719-768x235.png 768w" sizes="(max-width: 919px) 100vw, 919px" /></p>
<ol>
<li>模板中遍历数据在第二个选项卡</li>
</ol>
<p><img loading="lazy" decoding="async" width="1084" height="348" class="wp-image-8130" src="/wp-content/uploads/2018/06/word-image-720.png" srcset="/wp-content/uploads/2018/06/word-image-720.png 1084w, /wp-content/uploads/2018/06/word-image-720-300x96.png 300w, /wp-content/uploads/2018/06/word-image-720-768x247.png 768w, /wp-content/uploads/2018/06/word-image-720-1024x329.png 1024w" sizes="(max-width: 1084px) 100vw, 1084px" /></p>
<p>3、设置一个存储动态生成属性的容器</p>
<p><img loading="lazy" decoding="async" width="914" height="337" class="wp-image-8131" src="/wp-content/uploads/2018/06/word-image-721.png" srcset="/wp-content/uploads/2018/06/word-image-721.png 914w, /wp-content/uploads/2018/06/word-image-721-300x111.png 300w, /wp-content/uploads/2018/06/word-image-721-768x283.png 768w" sizes="(max-width: 914px) 100vw, 914px" /></p>
<ol>
<li>绑定onchange事件给select框</li>
</ol>
<p><img loading="lazy" decoding="async" width="1157" height="338" class="wp-image-8132" src="/wp-content/uploads/2018/06/word-image-722.png" srcset="/wp-content/uploads/2018/06/word-image-722.png 1157w, /wp-content/uploads/2018/06/word-image-722-300x88.png 300w, /wp-content/uploads/2018/06/word-image-722-768x224.png 768w, /wp-content/uploads/2018/06/word-image-722-1024x299.png 1024w" sizes="(max-width: 1157px) 100vw, 1157px" /></p>
<ol>
<li>在admin-GoodsController-ajaxGetTypeAttr方法，获取对应类型的属性，并以json格式输出</li>
</ol>
<p><img loading="lazy" decoding="async" width="944" height="379" class="wp-image-8133" src="/wp-content/uploads/2018/06/word-image-723.png" srcset="/wp-content/uploads/2018/06/word-image-723.png 944w, /wp-content/uploads/2018/06/word-image-723-300x120.png 300w, /wp-content/uploads/2018/06/word-image-723-768x308.png 768w" sizes="(max-width: 944px) 100vw, 944px" /></p>
<ol>
<li>根据ajax返回的属性数据，动态构建属性框</li>
</ol>
<p><img loading="lazy" decoding="async" width="972" height="527" class="wp-image-8134" src="/wp-content/uploads/2018/06/word-image-724.png" srcset="/wp-content/uploads/2018/06/word-image-724.png 972w, /wp-content/uploads/2018/06/word-image-724-300x163.png 300w, /wp-content/uploads/2018/06/word-image-724-768x416.png 768w" sizes="(max-width: 972px) 100vw, 972px" /> <img loading="lazy" decoding="async" width="1093" height="581" class="wp-image-8135" src="/wp-content/uploads/2018/06/word-image-725.png" srcset="/wp-content/uploads/2018/06/word-image-725.png 1093w, /wp-content/uploads/2018/06/word-image-725-300x159.png 300w, /wp-content/uploads/2018/06/word-image-725-768x408.png 768w, /wp-content/uploads/2018/06/word-image-725-1024x544.png 1024w" sizes="(max-width: 1093px) 100vw, 1093px" /></p>
<p>注：上面代码173行有错误：把判断attr_input_type改为attr_type</p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="623" height="423" class="wp-image-8136" src="/wp-content/uploads/2018/06/word-image-726.png" srcset="/wp-content/uploads/2018/06/word-image-726.png 623w, /wp-content/uploads/2018/06/word-image-726-300x204.png 300w" sizes="(max-width: 623px) 100vw, 623px" /></p>
<ol>
<li>完成单选属性的[+]功能</li>
</ol>
<p><img loading="lazy" decoding="async" width="992" height="331" class="wp-image-8137" src="/wp-content/uploads/2018/06/word-image-727.png" srcset="/wp-content/uploads/2018/06/word-image-727.png 992w, /wp-content/uploads/2018/06/word-image-727-300x100.png 300w, /wp-content/uploads/2018/06/word-image-727-768x256.png 768w" sizes="(max-width: 992px) 100vw, 992px" /></p>
<p>说明，逻辑和之前相册的是完全一致</p>
<p><img loading="lazy" decoding="async" width="802" height="283" class="wp-image-8138" src="/wp-content/uploads/2018/06/word-image-728.png" srcset="/wp-content/uploads/2018/06/word-image-728.png 802w, /wp-content/uploads/2018/06/word-image-728-300x106.png 300w, /wp-content/uploads/2018/06/word-image-728-768x271.png 768w" sizes="(max-width: 802px) 100vw, 802px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="626" height="288" class="wp-image-8139" src="/wp-content/uploads/2018/06/word-image-729.png" srcset="/wp-content/uploads/2018/06/word-image-729.png 626w, /wp-content/uploads/2018/06/word-image-729-300x138.png 300w" sizes="(max-width: 626px) 100vw, 626px" /></p>
<h2>完成商品动态属性的入库</h2>
<p>分析：</p>
<p>在表单中把单选属性值和单选属性价格通过属性attr_id归为同一组，方便后续获取对应属性的值和价格。</p>
<p>单选属性值： name=goodsAttrValue[attr_id][]</p>
<p>单选属性值价格： name=goodsAttrValue[attr_id][]</p>
<p>因为单选属性用户可以点击[+]号会生成多个，所以多个单选属性值和价格name的值后面都必须加上中括号[]。</p>
<p>由于唯一属性只能选择一个值，所以name后不需要加[]</p>
<p>我们最终需要构造类似于下面的数组，存储商品属性值和商品属性价格：</p>
<p><img loading="lazy" decoding="async" width="393" height="372" class="wp-image-8140" src="/wp-content/uploads/2018/06/word-image-730.png" srcset="/wp-content/uploads/2018/06/word-image-730.png 393w, /wp-content/uploads/2018/06/word-image-730-300x284.png 300w" sizes="(max-width: 393px) 100vw, 393px" /></p>
<p>在动态生成的属性框元素中设置name属性：</p>
<p><img loading="lazy" decoding="async" width="1224" height="674" class="wp-image-8141" src="/wp-content/uploads/2018/06/word-image-731.png" srcset="/wp-content/uploads/2018/06/word-image-731.png 1224w, /wp-content/uploads/2018/06/word-image-731-300x165.png 300w, /wp-content/uploads/2018/06/word-image-731-768x423.png 768w, /wp-content/uploads/2018/06/word-image-731-1024x564.png 1024w" sizes="(max-width: 1224px) 100vw, 1224px" /></p>
<p>在admin-GoodsController-add方法中打印提交过来的$postData数据如下：</p>
<p><img loading="lazy" decoding="async" width="675" height="657" class="wp-image-8142" src="/wp-content/uploads/2018/06/word-image-732.png" srcset="/wp-content/uploads/2018/06/word-image-732.png 675w, /wp-content/uploads/2018/06/word-image-732-300x292.png 300w" sizes="(max-width: 675px) 100vw, 675px" /></p>
<p>由于商品属性表（sh_goods_attr）数据需要得到入库成功的商品主键goods_id,所以我们可以在商品模型Goods的入库后钩子after_insert中完成完成商品属性表数据的入库。</p>
<p><img loading="lazy" decoding="async" width="876" height="498" class="wp-image-8143" src="/wp-content/uploads/2018/06/word-image-733.png" srcset="/wp-content/uploads/2018/06/word-image-733.png 876w, /wp-content/uploads/2018/06/word-image-733-300x171.png 300w, /wp-content/uploads/2018/06/word-image-733-768x437.png 768w" sizes="(max-width: 876px) 100vw, 876px" /> <img loading="lazy" decoding="async" width="769" height="611" class="wp-image-8144" src="/wp-content/uploads/2018/06/word-image-734.png" srcset="/wp-content/uploads/2018/06/word-image-734.png 769w, /wp-content/uploads/2018/06/word-image-734-300x238.png 300w, /wp-content/uploads/2018/06/word-image-734-768x610.png 768w" sizes="(max-width: 769px) 100vw, 769px" /></p>
<h1>商品列表展示</h1>
<ol>
<li>在admin-GoodsController-index方法中取出商品数据进行分配到模板</li>
</ol>
<p><img loading="lazy" decoding="async" width="805" height="296" class="wp-image-8145" src="/wp-content/uploads/2018/06/word-image-735.png" srcset="/wp-content/uploads/2018/06/word-image-735.png 805w, /wp-content/uploads/2018/06/word-image-735-300x110.png 300w, /wp-content/uploads/2018/06/word-image-735-768x282.png 768w" sizes="(max-width: 805px) 100vw, 805px" /></p>
<ol>
<li>模板中遍历数据</li>
</ol>
<p><img loading="lazy" decoding="async" width="1259" height="464" class="wp-image-8146" src="/wp-content/uploads/2018/06/word-image-736.png" srcset="/wp-content/uploads/2018/06/word-image-736.png 1259w, /wp-content/uploads/2018/06/word-image-736-300x111.png 300w, /wp-content/uploads/2018/06/word-image-736-768x283.png 768w, /wp-content/uploads/2018/06/word-image-736-1024x377.png 1024w" sizes="(max-width: 1259px) 100vw, 1259px" /></p>
<h1>使用ajax+layer弹出层查看商品详情</h1>
<ol>
<li>给admin-view-goods-index.html模板内容设置查看商品详情的标签属性</li>
</ol>
<p><img loading="lazy" decoding="async" width="1287" height="364" class="wp-image-8147" src="/wp-content/uploads/2018/06/word-image-737.png" srcset="/wp-content/uploads/2018/06/word-image-737.png 1287w, /wp-content/uploads/2018/06/word-image-737-300x85.png 300w, /wp-content/uploads/2018/06/word-image-737-768x217.png 768w, /wp-content/uploads/2018/06/word-image-737-1024x290.png 1024w" sizes="(max-width: 1287px) 100vw, 1287px" /></p>
<ol>
<li>给上面的class=showContent绑定单击事件，发送ajax请求</li>
</ol>
<p><img loading="lazy" decoding="async" width="1139" height="500" class="wp-image-8148" src="/wp-content/uploads/2018/06/word-image-738.png" srcset="/wp-content/uploads/2018/06/word-image-738.png 1139w, /wp-content/uploads/2018/06/word-image-738-300x132.png 300w, /wp-content/uploads/2018/06/word-image-738-768x337.png 768w, /wp-content/uploads/2018/06/word-image-738-1024x450.png 1024w" sizes="(max-width: 1139px) 100vw, 1139px" /></p>
<p>同时引入layer弹出层插件的核心js文件layer.js:</p>
<p><img loading="lazy" decoding="async" width="1109" height="286" class="wp-image-8149" src="/wp-content/uploads/2018/06/word-image-739.png" srcset="/wp-content/uploads/2018/06/word-image-739.png 1109w, /wp-content/uploads/2018/06/word-image-739-300x77.png 300w, /wp-content/uploads/2018/06/word-image-739-768x198.png 768w, /wp-content/uploads/2018/06/word-image-739-1024x264.png 1024w" sizes="(max-width: 1109px) 100vw, 1109px" /></p>
<p>3、在admin-GoodsController-ajaxGetContent获取商品的数据，返回json数据</p>
<p><img loading="lazy" decoding="async" width="1051" height="469" class="wp-image-8150" src="/wp-content/uploads/2018/06/word-image-740.png" srcset="/wp-content/uploads/2018/06/word-image-740.png 1051w, /wp-content/uploads/2018/06/word-image-740-300x134.png 300w, /wp-content/uploads/2018/06/word-image-740-768x343.png 768w, /wp-content/uploads/2018/06/word-image-740-1024x457.png 1024w" sizes="(max-width: 1051px) 100vw, 1051px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="1005" height="472" class="wp-image-8151" src="/wp-content/uploads/2018/06/word-image-741.png" srcset="/wp-content/uploads/2018/06/word-image-741.png 1005w, /wp-content/uploads/2018/06/word-image-741-300x141.png 300w, /wp-content/uploads/2018/06/word-image-741-768x361.png 768w" sizes="(max-width: 1005px) 100vw, 1005px" /></p>
<p>作业：使用ajax修改商品的是否热卖等状态，类似于ecshop如下：</p>
<p><img loading="lazy" decoding="async" width="1229" height="181" class="wp-image-8152" src="/wp-content/uploads/2018/06/word-image-742.png" srcset="/wp-content/uploads/2018/06/word-image-742.png 1229w, /wp-content/uploads/2018/06/word-image-742-300x44.png 300w, /wp-content/uploads/2018/06/word-image-742-768x113.png 768w, /wp-content/uploads/2018/06/word-image-742-1024x151.png 1024w" sizes="(max-width: 1229px) 100vw, 1229px" /></p>
]]></content:encoded>
					
					<wfw:commentRss>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/8031.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TP5 商城（五）商城前台首页、首页导航栏、首页分类筛选、首页推荐位、前台会员注册、短信验证、前台会员登录与验证码、前台退出功能、邮箱找回密码</title>
		<link>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/8157.html</link>
					<comments>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/8157.html#respond</comments>
		
		<dc:creator><![CDATA[Mr.Lee]]></dc:creator>
		<pubDate>Sat, 09 Jun 2018 00:36:50 +0000</pubDate>
				<category><![CDATA[TP5.0]]></category>
		<category><![CDATA[TP5.0商城]]></category>
		<category><![CDATA[后台框架]]></category>
		<category><![CDATA[前台会员注册]]></category>
		<category><![CDATA[前台会员登录与验证码]]></category>
		<category><![CDATA[前台退出功能]]></category>
		<category><![CDATA[商城前台首页]]></category>
		<category><![CDATA[短信验证]]></category>
		<category><![CDATA[邮箱找回密码]]></category>
		<category><![CDATA[首页分类筛选]]></category>
		<category><![CDATA[首页导航栏]]></category>
		<category><![CDATA[首页推荐位]]></category>
		<guid isPermaLink="false">/?p=8157</guid>

					<description><![CDATA[商城实战第五天 搭建商城前台首页 把商城前台资源文件复制到/home下面 在home-indexControl [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>商城实战第五天</h1>
<h1>搭建商城前台首页</h1>
<ol>
<li>把商城前台资源文件复制到/home下面</li>
</ol>
<p><img loading="lazy" decoding="async" width="817" height="247" class="wp-image-8158" src="/wp-content/uploads/2018/06/word-image-743.png" srcset="/wp-content/uploads/2018/06/word-image-743.png 817w, /wp-content/uploads/2018/06/word-image-743-300x91.png 300w, /wp-content/uploads/2018/06/word-image-743-768x232.png 768w" sizes="(max-width: 817px) 100vw, 817px" /></p>
<ol>
<li>在home-indexController-index方法中，输出模板</li>
</ol>
<p><img loading="lazy" decoding="async" width="779" height="311" class="wp-image-8159" src="/wp-content/uploads/2018/06/word-image-744.png" srcset="/wp-content/uploads/2018/06/word-image-744.png 779w, /wp-content/uploads/2018/06/word-image-744-300x120.png 300w, /wp-content/uploads/2018/06/word-image-744-768x307.png 768w" sizes="(max-width: 779px) 100vw, 779px" /></p>
<ol>
<li>复制前台的index.html模板到/home/view/index/目录下，并修改进行静态资源目录</li>
</ol>
<p><img loading="lazy" decoding="async" width="739" height="383" class="wp-image-8160" src="/wp-content/uploads/2018/06/word-image-745.png" srcset="/wp-content/uploads/2018/06/word-image-745.png 739w, /wp-content/uploads/2018/06/word-image-745-300x155.png 300w" sizes="(max-width: 739px) 100vw, 739px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="957" height="296" class="wp-image-8161" src="/wp-content/uploads/2018/06/word-image-746.png" srcset="/wp-content/uploads/2018/06/word-image-746.png 957w, /wp-content/uploads/2018/06/word-image-746-300x93.png 300w, /wp-content/uploads/2018/06/word-image-746-768x238.png 768w" sizes="(max-width: 957px) 100vw, 957px" /></p>
<p>注：开发前台先把默认访问的模块改为Home，修改config.php配置</p>
<p><img loading="lazy" decoding="async" width="666" height="180" class="wp-image-8162" src="/wp-content/uploads/2018/06/word-image-747.png" srcset="/wp-content/uploads/2018/06/word-image-747.png 666w, /wp-content/uploads/2018/06/word-image-747-300x81.png 300w" sizes="(max-width: 666px) 100vw, 666px" /></p>
<h1>url访问模块报错（for Bidden）的解决</h1>
<p>如访问 <a href="/goto/htjc" rel="nofollow">http://域名/模块名/这样会报错。</a> 这是因为直接访问到 /public/home/目录，此目录下面没有默认的访问页index.html，解决办法：把前后台资源目录放在/public/static/下面，并且修改config.php配置文件中的前后台资源目录：</p>
<p><img loading="lazy" decoding="async" width="224" height="262" class="wp-image-8163" src="/wp-content/uploads/2018/06/word-image-748.png" /> <img loading="lazy" decoding="async" width="520" height="178" class="wp-image-8164" src="/wp-content/uploads/2018/06/word-image-749.png" srcset="/wp-content/uploads/2018/06/word-image-749.png 520w, /wp-content/uploads/2018/06/word-image-749-300x103.png 300w" sizes="(max-width: 520px) 100vw, 520px" /></p>
<h1>二、实现前台首页相关功能</h1>
<h2>完成首页的导航栏</h2>
<p><img loading="lazy" decoding="async" width="1046" height="158" class="wp-image-8165" src="/wp-content/uploads/2018/06/word-image-750.png" srcset="/wp-content/uploads/2018/06/word-image-750.png 1046w, /wp-content/uploads/2018/06/word-image-750-300x45.png 300w, /wp-content/uploads/2018/06/word-image-750-768x116.png 768w, /wp-content/uploads/2018/06/word-image-750-1024x155.png 1024w" sizes="(max-width: 1046px) 100vw, 1046px" /></p>
<p>因为导航栏的栏目比较多，我们只取出顶级栏目（即pid=0），并且is_show=1,加上limit限制取出的条数即可</p>
<p>代码如下：</p>
<p>1、在home-IndexController-index方法中取出对应导航栏分类数据。</p>
<p><img loading="lazy" decoding="async" width="1043" height="388" class="wp-image-8166" src="/wp-content/uploads/2018/06/word-image-751.png" srcset="/wp-content/uploads/2018/06/word-image-751.png 1043w, /wp-content/uploads/2018/06/word-image-751-300x112.png 300w, /wp-content/uploads/2018/06/word-image-751-768x286.png 768w, /wp-content/uploads/2018/06/word-image-751-1024x381.png 1024w" sizes="(max-width: 1043px) 100vw, 1043px" /></p>
<ol>
<li>在home-view-index-index.html模板中遍历数据</li>
</ol>
<p><img loading="lazy" decoding="async" width="1162" height="420" class="wp-image-8167" src="/wp-content/uploads/2018/06/word-image-752.png" srcset="/wp-content/uploads/2018/06/word-image-752.png 1162w, /wp-content/uploads/2018/06/word-image-752-300x108.png 300w, /wp-content/uploads/2018/06/word-image-752-768x278.png 768w, /wp-content/uploads/2018/06/word-image-752-1024x370.png 1024w" sizes="(max-width: 1162px) 100vw, 1162px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="535" height="57" class="wp-image-8168" src="/wp-content/uploads/2018/06/word-image-753.png" srcset="/wp-content/uploads/2018/06/word-image-753.png 535w, /wp-content/uploads/2018/06/word-image-753-300x32.png 300w" sizes="(max-width: 535px) 100vw, 535px" /></p>
<h2>2、完成首页的分类筛选</h2>
<p><img loading="lazy" decoding="async" width="740" height="254" class="wp-image-8169" src="/wp-content/uploads/2018/06/word-image-754.png" srcset="/wp-content/uploads/2018/06/word-image-754.png 740w, /wp-content/uploads/2018/06/word-image-754-300x103.png 300w" sizes="(max-width: 740px) 100vw, 740px" /></p>
<p>上面的三级分类的做法和角色分配权限技巧是一样。</p>
<ol>
<li>取出所有的分类数据，以主键cat_id作为select返回结果的下标</li>
<li>根据pid进行分组，把具有相同pid的值归为同一个组，方便模板中循环。</li>
</ol>
<p>代码如下：</p>
<p>1、按照上面两个技巧进行组装数据，分配到模板中</p>
<p><img loading="lazy" decoding="async" width="1014" height="623" class="wp-image-8170" src="/wp-content/uploads/2018/06/word-image-755.png" srcset="/wp-content/uploads/2018/06/word-image-755.png 1014w, /wp-content/uploads/2018/06/word-image-755-300x184.png 300w, /wp-content/uploads/2018/06/word-image-755-768x472.png 768w" sizes="(max-width: 1014px) 100vw, 1014px" /></p>
<p>其中$cats和$children变量数据如下：</p>
<p><img loading="lazy" decoding="async" width="774" height="432" class="wp-image-8171" src="/wp-content/uploads/2018/06/word-image-756.png" srcset="/wp-content/uploads/2018/06/word-image-756.png 774w, /wp-content/uploads/2018/06/word-image-756-300x167.png 300w, /wp-content/uploads/2018/06/word-image-756-768x429.png 768w" sizes="(max-width: 774px) 100vw, 774px" /></p>
<ol>
<li>在模板中遍历</li>
</ol>
<p><img loading="lazy" decoding="async" width="1236" height="677" class="wp-image-8172" src="/wp-content/uploads/2018/06/word-image-757.png" srcset="/wp-content/uploads/2018/06/word-image-757.png 1236w, /wp-content/uploads/2018/06/word-image-757-300x164.png 300w, /wp-content/uploads/2018/06/word-image-757-768x421.png 768w, /wp-content/uploads/2018/06/word-image-757-1024x561.png 1024w" sizes="(max-width: 1236px) 100vw, 1236px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="727" height="121" class="wp-image-8173" src="/wp-content/uploads/2018/06/word-image-758.png" srcset="/wp-content/uploads/2018/06/word-image-758.png 727w, /wp-content/uploads/2018/06/word-image-758-300x50.png 300w" sizes="(max-width: 727px) 100vw, 727px" /></p>
<h2>3、首页的推荐位</h2>
<p><img loading="lazy" decoding="async" width="915" height="275" class="wp-image-8174" src="/wp-content/uploads/2018/06/word-image-759.png" srcset="/wp-content/uploads/2018/06/word-image-759.png 915w, /wp-content/uploads/2018/06/word-image-759-300x90.png 300w, /wp-content/uploads/2018/06/word-image-759-768x231.png 768w" sizes="(max-width: 915px) 100vw, 915px" /></p>
<p>一共五个推荐位：</p>
<p>上面的五个推荐位商品的都应该在正常的商品列表中（即不在回收站中），且为上架商品。</p>
<p>即字段is_delete = 0 and is_sale = 1。</p>
<p>五个推荐位：</p>
<p>疯狂抢购：按照自己商城一些特点取商品，如可以取出价格最低的几个。</p>
<p>热卖：即is_hot = 1</p>
<p>推荐：即is_best = 1</p>
<p>新品：即is_new = 1</p>
<p>猜你喜欢：随机取出几个商品,利用mysql的 rand()的随机函数，使用模型的方法order( ‘rand()’ )实现</p>
<p>代码如下：</p>
<ol>
<li>在home-Goods模型中定义一个获取指定类型商品的getTypeGoods方法</li>
</ol>
<p><img loading="lazy" decoding="async" width="1275" height="700" class="wp-image-8175" src="/wp-content/uploads/2018/06/word-image-760.png" srcset="/wp-content/uploads/2018/06/word-image-760.png 1275w, /wp-content/uploads/2018/06/word-image-760-300x165.png 300w, /wp-content/uploads/2018/06/word-image-760-768x422.png 768w, /wp-content/uploads/2018/06/word-image-760-1024x562.png 1024w" sizes="(max-width: 1275px) 100vw, 1275px" /></p>
<ol>
<li>在admin-indexController-index方法中获取对应类型的数据</li>
</ol>
<p><img loading="lazy" decoding="async" width="914" height="652" class="wp-image-8176" src="/wp-content/uploads/2018/06/word-image-761.png" srcset="/wp-content/uploads/2018/06/word-image-761.png 914w, /wp-content/uploads/2018/06/word-image-761-300x214.png 300w, /wp-content/uploads/2018/06/word-image-761-768x548.png 768w" sizes="(max-width: 914px) 100vw, 914px" /></p>
<ol>
<li>模板中遍历数据</li>
</ol>
<p><img loading="lazy" decoding="async" width="1256" height="696" class="wp-image-8177" src="/wp-content/uploads/2018/06/word-image-762.png" srcset="/wp-content/uploads/2018/06/word-image-762.png 1256w, /wp-content/uploads/2018/06/word-image-762-300x166.png 300w, /wp-content/uploads/2018/06/word-image-762-768x426.png 768w, /wp-content/uploads/2018/06/word-image-762-1024x567.png 1024w" sizes="(max-width: 1256px) 100vw, 1256px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="874" height="249" class="wp-image-8178" src="/wp-content/uploads/2018/06/word-image-763.png" srcset="/wp-content/uploads/2018/06/word-image-763.png 874w, /wp-content/uploads/2018/06/word-image-763-300x85.png 300w, /wp-content/uploads/2018/06/word-image-763-768x219.png 768w" sizes="(max-width: 874px) 100vw, 874px" /></p>
<h1>三、完成前台会员的注册功能</h1>
<h2>1、相关的会员表分析</h2>
<p><img loading="lazy" decoding="async" width="971" height="284" class="wp-image-8179" src="/wp-content/uploads/2018/06/word-image-764.png" srcset="/wp-content/uploads/2018/06/word-image-764.png 971w, /wp-content/uploads/2018/06/word-image-764-300x88.png 300w, /wp-content/uploads/2018/06/word-image-764-768x225.png 768w" sizes="(max-width: 971px) 100vw, 971px" /></p>
<p>其中openid字段，是用于后面实现qq第三方登录用的。</p>
<h2>代码实现</h2>
<ol>
<li>定义member验证器和member模型</li>
</ol>
<p>member验证器：</p>
<p><img loading="lazy" decoding="async" width="911" height="632" class="wp-image-8180" src="/wp-content/uploads/2018/06/word-image-765.png" srcset="/wp-content/uploads/2018/06/word-image-765.png 911w, /wp-content/uploads/2018/06/word-image-765-300x208.png 300w, /wp-content/uploads/2018/06/word-image-765-768x533.png 768w" sizes="(max-width: 911px) 100vw, 911px" /></p>
<p>member模型：</p>
<p><img loading="lazy" decoding="async" width="995" height="419" class="wp-image-8181" src="/wp-content/uploads/2018/06/word-image-766.png" srcset="/wp-content/uploads/2018/06/word-image-766.png 995w, /wp-content/uploads/2018/06/word-image-766-300x126.png 300w, /wp-content/uploads/2018/06/word-image-766-768x323.png 768w" sizes="(max-width: 995px) 100vw, 995px" /></p>
<ol>
<li>设置注册模板register.html的表单name字段名称</li>
</ol>
<p><img loading="lazy" decoding="async" width="1161" height="709" class="wp-image-8182" src="/wp-content/uploads/2018/06/word-image-767.png" srcset="/wp-content/uploads/2018/06/word-image-767.png 1161w, /wp-content/uploads/2018/06/word-image-767-300x183.png 300w, /wp-content/uploads/2018/06/word-image-767-768x469.png 768w, /wp-content/uploads/2018/06/word-image-767-1024x625.png 1024w" sizes="(max-width: 1161px) 100vw, 1161px" /></p>
<p>3、在home-publicController-register方法中完成注册的实现</p>
<p><img loading="lazy" decoding="async" width="976" height="626" class="wp-image-8183" src="/wp-content/uploads/2018/06/word-image-768.png" srcset="/wp-content/uploads/2018/06/word-image-768.png 976w, /wp-content/uploads/2018/06/word-image-768-300x192.png 300w, /wp-content/uploads/2018/06/word-image-768-768x493.png 768w" sizes="(max-width: 976px) 100vw, 976px" /></p>
<h1>四、使用短信验证完成注册</h1>
<h2>1、短信验证技术介绍</h2>
<p><strong>应用场景：</strong></p>
<p>主要用于用户注册、身份确认、重要资料修改的短信认证以及生成订单成功短信的通知等。</p>
<p><img loading="lazy" decoding="async" width="732" height="208" class="wp-image-8184" src="/wp-content/uploads/2018/06/word-image-769.png" srcset="/wp-content/uploads/2018/06/word-image-769.png 732w, /wp-content/uploads/2018/06/word-image-769-300x85.png 300w" sizes="(max-width: 732px) 100vw, 732px" /></p>
<p>如百度利用手机号登录：</p>
<p><img loading="lazy" decoding="async" width="349" height="248" class="wp-image-8185" src="/wp-content/uploads/2018/06/word-image-770.png" srcset="/wp-content/uploads/2018/06/word-image-770.png 349w, /wp-content/uploads/2018/06/word-image-770-300x213.png 300w" sizes="(max-width: 349px) 100vw, 349px" /></p>
<p>如新浪手机邮箱注册验证</p>
<p><a href="/goto/ozwd" rel="nofollow">https://mail.sina.com.cn/register/regmail.php</a></p>
<p><img loading="lazy" decoding="async" width="502" height="434" class="wp-image-8186" src="/wp-content/uploads/2018/06/word-image-771.png" srcset="/wp-content/uploads/2018/06/word-image-771.png 502w, /wp-content/uploads/2018/06/word-image-771-300x259.png 300w" sizes="(max-width: 502px) 100vw, 502px" /></p>
<h2>2、发送短信的实现</h2>
<p>网站应用中的短信发送一般要借助第三方提供商提供的API接口来发送短信。而且大部分是要收费的，内容方面的规范检验也越来越严格，常常都需要按照事先审核过的短信模板来发送内容，否则无法发送成功。</p>
<p>目前国内有很多这方面的短信提供商，只不过收费标准和稳定性都不一样。所以我们优先选择能免费体验的平台 ，比如容联云通讯（官方网址是：<a href="/goto/4d4z" rel="nofollow">http://www.yuntongxun.com/</a>）。</p>
<p>还有接口网：<a href="/goto/thuu" rel="nofollow">http://www.106jiekou.com/</a> ，</p>
<p>如下是容联云通讯（<a href="/goto/4d4z" rel="nofollow">http://www.yuntongxun.com/</a> ）的界面</p>
<p><img loading="lazy" decoding="async" width="1273" height="154" class="wp-image-8187" src="/wp-content/uploads/2018/06/word-image-772.png" srcset="/wp-content/uploads/2018/06/word-image-772.png 1273w, /wp-content/uploads/2018/06/word-image-772-300x36.png 300w, /wp-content/uploads/2018/06/word-image-772-768x93.png 768w, /wp-content/uploads/2018/06/word-image-772-1024x124.png 1024w" sizes="(max-width: 1273px) 100vw, 1273px" /></p>
<h2>3、容联运通讯的使用</h2>
<h3>（1）注册账号</h3>
<p>地址：<a href="/goto/30gu" rel="nofollow">http://www.yuntongxun.com/user/reg/init</a></p>
<p><img loading="lazy" decoding="async" width="637" height="571" class="wp-image-8188" src="/wp-content/uploads/2018/06/word-image-773.png" srcset="/wp-content/uploads/2018/06/word-image-773.png 637w, /wp-content/uploads/2018/06/word-image-773-300x269.png 300w" sizes="(max-width: 637px) 100vw, 637px" /></p>
<p>2、注册成功登录后进入控制中心</p>
<p><img loading="lazy" decoding="async" width="1330" height="544" class="wp-image-8189" src="/wp-content/uploads/2018/06/word-image-774.png" srcset="/wp-content/uploads/2018/06/word-image-774.png 1330w, /wp-content/uploads/2018/06/word-image-774-300x123.png 300w, /wp-content/uploads/2018/06/word-image-774-768x314.png 768w, /wp-content/uploads/2018/06/word-image-774-1024x419.png 1024w" sizes="(max-width: 1330px) 100vw, 1330px" /></p>
<p>3、设置发送短信的测试手机号</p>
<p><img loading="lazy" decoding="async" width="1023" height="487" class="wp-image-8190" src="/wp-content/uploads/2018/06/word-image-775.png" srcset="/wp-content/uploads/2018/06/word-image-775.png 1023w, /wp-content/uploads/2018/06/word-image-775-300x143.png 300w, /wp-content/uploads/2018/06/word-image-775-768x366.png 768w" sizes="(max-width: 1023px) 100vw, 1023px" /></p>
<p>注意：只有填写测试的手机号才可以发送短信，通过身份证认证之后无限制。</p>
<h3>（2）查看开发文档和下载demo代码</h3>
<p>1、开发文档：</p>
<p><img loading="lazy" decoding="async" width="1089" height="422" class="wp-image-8191" src="/wp-content/uploads/2018/06/word-image-776.png" srcset="/wp-content/uploads/2018/06/word-image-776.png 1089w, /wp-content/uploads/2018/06/word-image-776-300x116.png 300w, /wp-content/uploads/2018/06/word-image-776-768x298.png 768w, /wp-content/uploads/2018/06/word-image-776-1024x397.png 1024w" sizes="(max-width: 1089px) 100vw, 1089px" /></p>
<p>2、进入demo示例，查看使如何使用</p>
<p><img loading="lazy" decoding="async" width="1061" height="525" class="wp-image-8192" src="/wp-content/uploads/2018/06/word-image-777.png" srcset="/wp-content/uploads/2018/06/word-image-777.png 1061w, /wp-content/uploads/2018/06/word-image-777-300x148.png 300w, /wp-content/uploads/2018/06/word-image-777-768x380.png 768w, /wp-content/uploads/2018/06/word-image-777-1024x507.png 1024w" sizes="(max-width: 1061px) 100vw, 1061px" /></p>
<p>下载后的DEMO文件：</p>
<p><img loading="lazy" decoding="async" width="549" height="179" class="wp-image-8193" src="/wp-content/uploads/2018/06/word-image-778.png" srcset="/wp-content/uploads/2018/06/word-image-778.png 549w, /wp-content/uploads/2018/06/word-image-778-300x98.png 300w" sizes="(max-width: 549px) 100vw, 549px" /></p>
<p>注：发送短信要开启PHP的curl模块，在php配置文件php.ini中开启</p>
<p><img loading="lazy" decoding="async" width="770" height="70" class="wp-image-8194" src="/wp-content/uploads/2018/06/word-image-779.png" srcset="/wp-content/uploads/2018/06/word-image-779.png 770w, /wp-content/uploads/2018/06/word-image-779-300x27.png 300w, /wp-content/uploads/2018/06/word-image-779-768x70.png 768w" sizes="(max-width: 770px) 100vw, 770px" /></p>
<h3>（3）短信发送案例</h3>
<p>参考以下示例：</p>
<p><img loading="lazy" decoding="async" width="510" height="54" class="wp-image-8195" src="/wp-content/uploads/2018/06/word-image-780.png" srcset="/wp-content/uploads/2018/06/word-image-780.png 510w, /wp-content/uploads/2018/06/word-image-780-300x32.png 300w" sizes="(max-width: 510px) 100vw, 510px" /></p>
<h1>使用短信验证完成注册</h1>
<ol>
<li>上面演示代码放在虚拟主机中测试如果可以正常发送短信则把对应的文件夹sendSMS复制到我们[项目目录]/extend/目录下面：</li>
</ol>
<p><img loading="lazy" decoding="async" width="784" height="268" class="wp-image-8196" src="/wp-content/uploads/2018/06/word-image-781.png" srcset="/wp-content/uploads/2018/06/word-image-781.png 784w, /wp-content/uploads/2018/06/word-image-781-300x103.png 300w, /wp-content/uploads/2018/06/word-image-781-768x263.png 768w" sizes="(max-width: 784px) 100vw, 784px" /></p>
<p>只需要上面一个文件即可发送短信。</p>
<ol>
<li>封装一个发送短信的方法，封装在common.php</li>
</ol>
<p><img loading="lazy" decoding="async" width="1134" height="716" class="wp-image-8197" src="/wp-content/uploads/2018/06/word-image-782.png" srcset="/wp-content/uploads/2018/06/word-image-782.png 1134w, /wp-content/uploads/2018/06/word-image-782-300x189.png 300w, /wp-content/uploads/2018/06/word-image-782-768x485.png 768w, /wp-content/uploads/2018/06/word-image-782-1024x647.png 1024w" sizes="(max-width: 1134px) 100vw, 1134px" /></p>
<p>测试下是否可以发送短信：</p>
<p><img loading="lazy" decoding="async" width="864" height="263" class="wp-image-8198" src="/wp-content/uploads/2018/06/word-image-783.png" srcset="/wp-content/uploads/2018/06/word-image-783.png 864w, /wp-content/uploads/2018/06/word-image-783-300x91.png 300w, /wp-content/uploads/2018/06/word-image-783-768x234.png 768w" sizes="(max-width: 864px) 100vw, 864px" /></p>
<p>成功和失败返回如下数据：</p>
<p><img loading="lazy" decoding="async" width="744" height="284" class="wp-image-8199" src="/wp-content/uploads/2018/06/word-image-784.png" srcset="/wp-content/uploads/2018/06/word-image-784.png 744w, /wp-content/uploads/2018/06/word-image-784-300x115.png 300w" sizes="(max-width: 744px) 100vw, 744px" /></p>
<ol>
<li>在register.html注册的页面，设置发送短信的html布局</li>
</ol>
<p><img loading="lazy" decoding="async" width="1216" height="475" class="wp-image-8200" src="/wp-content/uploads/2018/06/word-image-785.png" srcset="/wp-content/uploads/2018/06/word-image-785.png 1216w, /wp-content/uploads/2018/06/word-image-785-300x117.png 300w, /wp-content/uploads/2018/06/word-image-785-768x300.png 768w, /wp-content/uploads/2018/06/word-image-785-1024x400.png 1024w" sizes="(max-width: 1216px) 100vw, 1216px" /></p>
<ol>
<li>给id=sendSms绑定单击事件，发送ajax请求，进行短信的发送</li>
</ol>
<p><img loading="lazy" decoding="async" width="1048" height="493" class="wp-image-8201" src="/wp-content/uploads/2018/06/word-image-786.png" srcset="/wp-content/uploads/2018/06/word-image-786.png 1048w, /wp-content/uploads/2018/06/word-image-786-300x141.png 300w, /wp-content/uploads/2018/06/word-image-786-768x361.png 768w, /wp-content/uploads/2018/06/word-image-786-1024x482.png 1024w" sizes="(max-width: 1048px) 100vw, 1048px" /></p>
<ol>
<li>在home-publicController-sendSms定义发送短信的方法</li>
</ol>
<p>先在config.php中加入一个短信盐：用于加密</p>
<p><img loading="lazy" decoding="async" width="664" height="217" class="wp-image-8202" src="/wp-content/uploads/2018/06/word-image-787.png" srcset="/wp-content/uploads/2018/06/word-image-787.png 664w, /wp-content/uploads/2018/06/word-image-787-300x98.png 300w" sizes="(max-width: 664px) 100vw, 664px" /></p>
<p>进行发送短信：</p>
<p><img loading="lazy" decoding="async" width="1231" height="459" class="wp-image-8203" src="/wp-content/uploads/2018/06/word-image-788.png" srcset="/wp-content/uploads/2018/06/word-image-788.png 1231w, /wp-content/uploads/2018/06/word-image-788-300x112.png 300w, /wp-content/uploads/2018/06/word-image-788-768x286.png 768w, /wp-content/uploads/2018/06/word-image-788-1024x382.png 1024w" sizes="(max-width: 1231px) 100vw, 1231px" /></p>
<p>同时定义一个验证:</p>
<p><img loading="lazy" decoding="async" width="998" height="697" class="wp-image-8204" src="/wp-content/uploads/2018/06/word-image-789.png" srcset="/wp-content/uploads/2018/06/word-image-789.png 998w, /wp-content/uploads/2018/06/word-image-789-300x210.png 300w, /wp-content/uploads/2018/06/word-image-789-768x536.png 768w" sizes="(max-width: 998px) 100vw, 998px" /></p>
<p>6、发送短信的倒计时特效:</p>
<p><img loading="lazy" decoding="async" width="1040" height="283" class="wp-image-8205" src="/wp-content/uploads/2018/06/word-image-790.png" srcset="/wp-content/uploads/2018/06/word-image-790.png 1040w, /wp-content/uploads/2018/06/word-image-790-300x82.png 300w, /wp-content/uploads/2018/06/word-image-790-768x209.png 768w, /wp-content/uploads/2018/06/word-image-790-1024x279.png 1024w" sizes="(max-width: 1040px) 100vw, 1040px" /></p>
<p>countDown倒计时方法代码如下：</p>
<p><img loading="lazy" decoding="async" width="972" height="491" class="wp-image-8206" src="/wp-content/uploads/2018/06/word-image-791.png" srcset="/wp-content/uploads/2018/06/word-image-791.png 972w, /wp-content/uploads/2018/06/word-image-791-300x152.png 300w, /wp-content/uploads/2018/06/word-image-791-768x388.png 768w" sizes="(max-width: 972px) 100vw, 972px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="512" height="112" class="wp-image-8207" src="/wp-content/uploads/2018/06/word-image-792.png" srcset="/wp-content/uploads/2018/06/word-image-792.png 512w, /wp-content/uploads/2018/06/word-image-792-300x66.png 300w" sizes="(max-width: 512px) 100vw, 512px" /></p>
<ol>
<li>同时点击注册按钮的时候，需要判断手机号短信验证码是否输入正确</li>
</ol>
<p><img loading="lazy" decoding="async" width="1084" height="559" class="wp-image-8208" src="/wp-content/uploads/2018/06/word-image-793.png" srcset="/wp-content/uploads/2018/06/word-image-793.png 1084w, /wp-content/uploads/2018/06/word-image-793-300x155.png 300w, /wp-content/uploads/2018/06/word-image-793-768x396.png 768w, /wp-content/uploads/2018/06/word-image-793-1024x528.png 1024w" sizes="(max-width: 1084px) 100vw, 1084px" /></p>
<h1>六、完成前台会员的登录和验证码功能</h1>
<p>1、先在member验证器中定义一个login的验证场景</p>
<p><img loading="lazy" decoding="async" width="992" height="674" class="wp-image-8209" src="/wp-content/uploads/2018/06/word-image-794.png" srcset="/wp-content/uploads/2018/06/word-image-794.png 992w, /wp-content/uploads/2018/06/word-image-794-300x204.png 300w, /wp-content/uploads/2018/06/word-image-794-768x522.png 768w" sizes="(max-width: 992px) 100vw, 992px" /></p>
<ol>
<li>在Member模型中定义一个checkUser方法，判断用户名和密码是否正确</li>
</ol>
<p><img loading="lazy" decoding="async" width="894" height="399" class="wp-image-8210" src="/wp-content/uploads/2018/06/word-image-795.png" srcset="/wp-content/uploads/2018/06/word-image-795.png 894w, /wp-content/uploads/2018/06/word-image-795-300x134.png 300w, /wp-content/uploads/2018/06/word-image-795-768x343.png 768w" sizes="(max-width: 894px) 100vw, 894px" /></p>
<ol>
<li>在登录模板login.html设置表单的name名称</li>
</ol>
<p><img loading="lazy" decoding="async" width="1142" height="618" class="wp-image-8211" src="/wp-content/uploads/2018/06/word-image-796.png" srcset="/wp-content/uploads/2018/06/word-image-796.png 1142w, /wp-content/uploads/2018/06/word-image-796-300x162.png 300w, /wp-content/uploads/2018/06/word-image-796-768x416.png 768w, /wp-content/uploads/2018/06/word-image-796-1024x554.png 1024w" sizes="(max-width: 1142px) 100vw, 1142px" /></p>
<p>同时单击换一张更换验证码：</p>
<p><img loading="lazy" decoding="async" width="995" height="152" class="wp-image-8212" src="/wp-content/uploads/2018/06/word-image-797.png" srcset="/wp-content/uploads/2018/06/word-image-797.png 995w, /wp-content/uploads/2018/06/word-image-797-300x46.png 300w, /wp-content/uploads/2018/06/word-image-797-768x117.png 768w" sizes="(max-width: 995px) 100vw, 995px" /></p>
<p>注：上面生成验证码的时候，带了参数为2，在验证器验证的时候，记得带上对应的标识2.</p>
<p><img loading="lazy" decoding="async" width="339" height="41" class="wp-image-8213" src="/wp-content/uploads/2018/06/word-image-798.png" srcset="/wp-content/uploads/2018/06/word-image-798.png 339w, /wp-content/uploads/2018/06/word-image-798-300x36.png 300w" sizes="(max-width: 339px) 100vw, 339px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="556" height="205" class="wp-image-8214" src="/wp-content/uploads/2018/06/word-image-799.png" srcset="/wp-content/uploads/2018/06/word-image-799.png 556w, /wp-content/uploads/2018/06/word-image-799-300x111.png 300w" sizes="(max-width: 556px) 100vw, 556px" /></p>
<p>4、在home-publicController-login方法中完成登录模板的展示和登录的逻辑实现</p>
<p><img loading="lazy" decoding="async" width="1103" height="501" class="wp-image-8215" src="/wp-content/uploads/2018/06/word-image-800.png" srcset="/wp-content/uploads/2018/06/word-image-800.png 1103w, /wp-content/uploads/2018/06/word-image-800-300x136.png 300w, /wp-content/uploads/2018/06/word-image-800-768x349.png 768w, /wp-content/uploads/2018/06/word-image-800-1024x465.png 1024w" sizes="(max-width: 1103px) 100vw, 1103px" /></p>
<h1>七、退出功能，显示用户是否登录</h1>
<p>判断用户是否登录思想：</p>
<p><img loading="lazy" decoding="async" width="474" height="50" class="wp-image-8216" src="/wp-content/uploads/2018/06/word-image-801.png" srcset="/wp-content/uploads/2018/06/word-image-801.png 474w, /wp-content/uploads/2018/06/word-image-801-300x32.png 300w" sizes="(max-width: 474px) 100vw, 474px" /></p>
<p>当用户登录，显示退出的按钮</p>
<p>当用户未登录，显示登录和注册的按钮</p>
<p>做法：可以通过session进行判断</p>
<p>修改home-view-index-index.html模板内容：</p>
<p><img loading="lazy" decoding="async" width="1245" height="423" class="wp-image-8217" src="/wp-content/uploads/2018/06/word-image-802.png" srcset="/wp-content/uploads/2018/06/word-image-802.png 1245w, /wp-content/uploads/2018/06/word-image-802-300x102.png 300w, /wp-content/uploads/2018/06/word-image-802-768x261.png 768w, /wp-content/uploads/2018/06/word-image-802-1024x348.png 1024w" sizes="(max-width: 1245px) 100vw, 1245px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="273" height="61" class="wp-image-8218" src="/wp-content/uploads/2018/06/word-image-803.png" /></p>
<p>同时在home-publicController-logout方法中完成退出功能的实现</p>
<p><img loading="lazy" decoding="async" width="784" height="369" class="wp-image-8219" src="/wp-content/uploads/2018/06/word-image-804.png" srcset="/wp-content/uploads/2018/06/word-image-804.png 784w, /wp-content/uploads/2018/06/word-image-804-300x141.png 300w, /wp-content/uploads/2018/06/word-image-804-768x361.png 768w" sizes="(max-width: 784px) 100vw, 784px" /></p>
<h1>八、邮件技术实现密码找回</h1>
<h2>1、邮件发送概述</h2>
<h3>（1）邮件发送的原理</h3>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" width="993" height="380" class="wp-image-8220" src="/wp-content/uploads/2018/06/word-image-805.png" srcset="/wp-content/uploads/2018/06/word-image-805.png 993w, /wp-content/uploads/2018/06/word-image-805-300x115.png 300w, /wp-content/uploads/2018/06/word-image-805-768x294.png 768w" sizes="(max-width: 993px) 100vw, 993px" /></p>
<p>解释：</p>
<p>POP3：全名为“Post Office Protocol &#8211; Version 3”，即“邮局协议版本3”。是TCP/IP协议族中的一员，由RFC1939 定义。本协议主要用于支持使用客户端远程管理在服务器上的电子邮件，提供了SSL加密。</p>
<p>简单一句话，POP服务器是用来收信的。</p>
<h3>（2）SMTP协议（Simple Mail Transfer Protocol）</h3>
<p><a id="post-8157-_Toc449198636"></a> SMTP（Simple Mail Transfer Protocol）：</p>
<p>即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则，由它来控制信件的中转方式。</p>
<p>SMTP协议属于TCP/IP协议族，它帮助每台计算机在发送或中转信件时找到下一个目的地。</p>
<p>通过SMTP协议所指定的服务器,就可以把E－mail寄到收信人的服务器上了，整个过程只要几分钟。SMTP服务器则是遵循SMTP协议的发送邮件服务器，用来发送或中转发出的电子邮件。</p>
<p>简单的说：　SMTP则是负责邮件服务器与邮件服务器之间的寄信的通讯协定（类似于http协议）</p>
<h2>2、如何实现邮件的发送</h2>
<p>（1）需要有邮件发送的第三方程序包，比如可以使用开源免费的PHPMailer</p>
<p><img loading="lazy" decoding="async" width="236" height="25" class="wp-image-8221" src="/wp-content/uploads/2018/06/word-image-806.png" /></p>
<p>（2）需要邮件服务器</p>
<p>利用互联网上的第三方免费邮件服务器，例如 163， qq等，有些大公司会自己搭建邮件服务器。</p>
<p>（3）需要在免费的邮件服务器里面（可以去注册163的），注册一个邮箱，进入邮箱后，要开通smtp服务。</p>
<p>以163为例，先注册一个邮箱账号。</p>
<p><img loading="lazy" decoding="async" width="691" height="616" class="wp-image-8222" src="/wp-content/uploads/2018/06/word-image-807.png" srcset="/wp-content/uploads/2018/06/word-image-807.png 691w, /wp-content/uploads/2018/06/word-image-807-300x267.png 300w" sizes="(max-width: 691px) 100vw, 691px" /></p>
<p>注册成功然后登录进入用户设置</p>
<p><img loading="lazy" decoding="async" width="950" height="304" class="wp-image-8223" src="/wp-content/uploads/2018/06/word-image-808.png" srcset="/wp-content/uploads/2018/06/word-image-808.png 950w, /wp-content/uploads/2018/06/word-image-808-300x96.png 300w, /wp-content/uploads/2018/06/word-image-808-768x246.png 768w" sizes="(max-width: 950px) 100vw, 950px" /></p>
<p>开通smtp服务</p>
<p><img loading="lazy" decoding="async" width="1107" height="644" class="wp-image-8224" src="/wp-content/uploads/2018/06/word-image-809.png" srcset="/wp-content/uploads/2018/06/word-image-809.png 1107w, /wp-content/uploads/2018/06/word-image-809-300x175.png 300w, /wp-content/uploads/2018/06/word-image-809-768x447.png 768w, /wp-content/uploads/2018/06/word-image-809-1024x596.png 1024w" sizes="(max-width: 1107px) 100vw, 1107px" /></p>
<p>设置客户端授权密码</p>
<p><img loading="lazy" decoding="async" width="987" height="529" class="wp-image-8225" src="/wp-content/uploads/2018/06/word-image-810.png" srcset="/wp-content/uploads/2018/06/word-image-810.png 987w, /wp-content/uploads/2018/06/word-image-810-300x161.png 300w, /wp-content/uploads/2018/06/word-image-810-768x412.png 768w" sizes="(max-width: 987px) 100vw, 987px" /></p>
<p>（4） php.ini配置文件中需要启用sockets扩展。</p>
<p><img loading="lazy" decoding="async" width="475" height="229" class="wp-image-8226" src="/wp-content/uploads/2018/06/word-image-811.png" srcset="/wp-content/uploads/2018/06/word-image-811.png 475w, /wp-content/uploads/2018/06/word-image-811-300x145.png 300w" sizes="(max-width: 475px) 100vw, 475px" /></p>
<p>记得重启apache服务器</p>
<h2>3、邮件发送案例</h2>
<p>参考以下示例：</p>
<p><img loading="lazy" decoding="async" width="264" height="48" class="wp-image-8227" src="/wp-content/uploads/2018/06/word-image-812.png" /></p>
<h2>集成到项目中实现忘记密码功能</h2>
<ol>
<li>把上面测试通过的发送邮件的sendEmail复制到[应用目录]/extend目录中</li>
</ol>
<p><img loading="lazy" decoding="async" width="509" height="208" class="wp-image-8228" src="/wp-content/uploads/2018/06/word-image-813.png" srcset="/wp-content/uploads/2018/06/word-image-813.png 509w, /wp-content/uploads/2018/06/word-image-813-300x123.png 300w" sizes="(max-width: 509px) 100vw, 509px" /></p>
<p>注：测试的时候，记得修改demo.php中的基本配置。</p>
<ol>
<li>在common.php文件中封装一个发送邮件的方法sendEmail</li>
</ol>
<p><img loading="lazy" decoding="async" width="1042" height="714" class="wp-image-8229" src="/wp-content/uploads/2018/06/word-image-814.png" srcset="/wp-content/uploads/2018/06/word-image-814.png 1042w, /wp-content/uploads/2018/06/word-image-814-300x206.png 300w, /wp-content/uploads/2018/06/word-image-814-768x526.png 768w, /wp-content/uploads/2018/06/word-image-814-1024x702.png 1024w" sizes="(max-width: 1042px) 100vw, 1042px" /></p>
<ol>
<li>记得测试一下是否ok</li>
</ol>
<p><img loading="lazy" decoding="async" width="1077" height="265" class="wp-image-8230" src="/wp-content/uploads/2018/06/word-image-815.png" srcset="/wp-content/uploads/2018/06/word-image-815.png 1077w, /wp-content/uploads/2018/06/word-image-815-300x74.png 300w, /wp-content/uploads/2018/06/word-image-815-768x189.png 768w, /wp-content/uploads/2018/06/word-image-815-1024x252.png 1024w" sizes="(max-width: 1077px) 100vw, 1077px" /></p>
<h2>实现登录的忘记密码功能</h2>
<p>找回密码的基本流程图解：</p>
<p><img loading="lazy" decoding="async" width="460" height="660" class="wp-image-8231" src="/wp-content/uploads/2018/06/word-image-816.png" srcset="/wp-content/uploads/2018/06/word-image-816.png 460w, /wp-content/uploads/2018/06/word-image-816-209x300.png 209w" sizes="(max-width: 460px) 100vw, 460px" /></p>
<ol>
<li>修改登录页面的忘记密码的链接地址</li>
</ol>
<p><img loading="lazy" decoding="async" width="1135" height="294" class="wp-image-8232" src="/wp-content/uploads/2018/06/word-image-817.png" srcset="/wp-content/uploads/2018/06/word-image-817.png 1135w, /wp-content/uploads/2018/06/word-image-817-300x78.png 300w, /wp-content/uploads/2018/06/word-image-817-768x199.png 768w, /wp-content/uploads/2018/06/word-image-817-1024x265.png 1024w" sizes="(max-width: 1135px) 100vw, 1135px" /></p>
<ol>
<li>在home-publicController-findpassword方法，展示一个输入注册时候的邮箱的模板显示。</li>
</ol>
<p>注:模板可以直接复制登录的login.html模板即可，稍做修改</p>
<p><img loading="lazy" decoding="async" width="1271" height="399" class="wp-image-8233" src="/wp-content/uploads/2018/06/word-image-818.png" srcset="/wp-content/uploads/2018/06/word-image-818.png 1271w, /wp-content/uploads/2018/06/word-image-818-300x94.png 300w, /wp-content/uploads/2018/06/word-image-818-768x241.png 768w, /wp-content/uploads/2018/06/word-image-818-1024x321.png 1024w" sizes="(max-width: 1271px) 100vw, 1271px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="471" height="161" class="wp-image-8234" src="/wp-content/uploads/2018/06/word-image-819.png" srcset="/wp-content/uploads/2018/06/word-image-819.png 471w, /wp-content/uploads/2018/06/word-image-819-300x103.png 300w" sizes="(max-width: 471px) 100vw, 471px" /></p>
<ol>
<li>给上面的按钮绑定单击事件，进行发送ajax，触发发送邮件。</li>
</ol>
<p><img loading="lazy" decoding="async" width="1032" height="380" class="wp-image-8235" src="/wp-content/uploads/2018/06/word-image-820.png" srcset="/wp-content/uploads/2018/06/word-image-820.png 1032w, /wp-content/uploads/2018/06/word-image-820-300x110.png 300w, /wp-content/uploads/2018/06/word-image-820-768x283.png 768w, /wp-content/uploads/2018/06/word-image-820-1024x377.png 1024w" sizes="(max-width: 1032px) 100vw, 1032px" /></p>
<ol>
<li>在home模块的PublicController控制器中的findPassword方法中判断是否是ajax请求，接收重置的邮箱，进行一些发送邮件前的判断</li>
</ol>
<p><img loading="lazy" decoding="async" width="1000" height="504" class="wp-image-8236" src="/wp-content/uploads/2018/06/word-image-821.png" srcset="/wp-content/uploads/2018/06/word-image-821.png 1000w, /wp-content/uploads/2018/06/word-image-821-300x151.png 300w, /wp-content/uploads/2018/06/word-image-821-768x387.png 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></p>
<ol>
<li>当输入的邮箱在系统中存在的时候，就进行发送邮件。</li>
</ol>
<p>明天讲！！</p>
<h2>6、验证邮件地址的合法性</h2>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/8157.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TP5 商城（六）邮件找回密码、QQ 互联、QQ 登录、分类列表页的面包屑导航、分类列表页左侧分类菜单</title>
		<link>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/8241.html</link>
					<comments>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/8241.html#respond</comments>
		
		<dc:creator><![CDATA[Mr.Lee]]></dc:creator>
		<pubDate>Fri, 08 Jun 2018 00:35:46 +0000</pubDate>
				<category><![CDATA[TP5.0]]></category>
		<category><![CDATA[TP5.0商城]]></category>
		<category><![CDATA[后台框架]]></category>
		<category><![CDATA[QQ 互联]]></category>
		<category><![CDATA[QQ 登录]]></category>
		<category><![CDATA[分类列表页左侧分类菜单]]></category>
		<category><![CDATA[分类列表页的面包屑导航]]></category>
		<category><![CDATA[邮件找回密码]]></category>
		<guid isPermaLink="false">/?p=8241</guid>

					<description><![CDATA[商城第六天 一、邮件技术实现密码找回 1、邮件发送概述 （1）邮件发送的原理 &#160; 解释： POP3： [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>商城第六天</h1>
<h1>一、邮件技术实现密码找回</h1>
<h2>1、邮件发送概述</h2>
<h3>（1）邮件发送的原理</h3>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" width="993" height="380" class="wp-image-8242" src="/wp-content/uploads/2018/06/word-image-822.png" srcset="/wp-content/uploads/2018/06/word-image-822.png 993w, /wp-content/uploads/2018/06/word-image-822-300x115.png 300w, /wp-content/uploads/2018/06/word-image-822-768x294.png 768w" sizes="(max-width: 993px) 100vw, 993px" /></p>
<p>解释：</p>
<p>POP3：全名为“Post Office Protocol &#8211; Version 3”，即“邮局协议版本3”。是TCP/IP协议族中的一员，由RFC1939 定义。本协议主要用于支持使用客户端远程管理在服务器上的电子邮件，提供了SSL加密。</p>
<p>简单一句话，POP服务器是用来收信的。</p>
<h3>（2）SMTP协议（Simple Mail Transfer Protocol）</h3>
<p><a id="post-8241-_Toc449198636"></a> SMTP（Simple Mail Transfer Protocol）：</p>
<p>即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则，由它来控制信件的中转方式。</p>
<p>SMTP协议属于TCP/IP协议族，它帮助每台计算机在发送或中转信件时找到下一个目的地。</p>
<p>通过SMTP协议所指定的服务器,就可以把E－mail寄到收信人的服务器上了，整个过程只要几分钟。SMTP服务器则是遵循SMTP协议的发送邮件服务器，用来发送或中转发出的电子邮件。</p>
<p>简单的说：　SMTP则是负责邮件服务器与邮件服务器之间的寄信的通讯协定（类似于http协议）</p>
<h2>2、如何实现邮件的发送</h2>
<p>（1）需要有邮件发送的第三方程序包，比如可以使用开源免费的PHPMailer</p>
<p><img loading="lazy" decoding="async" width="236" height="25" class="wp-image-8243" src="/wp-content/uploads/2018/06/word-image-823.png" /></p>
<p>（2）需要邮件服务器</p>
<p>利用互联网上的第三方免费邮件服务器，例如 163， qq等，有些大公司会自己搭建邮件服务器。</p>
<p>（3）需要在免费的邮件服务器里面（可以去注册163的），注册一个邮箱，进入邮箱后，要开通smtp服务。</p>
<p>以163为例，先注册一个邮箱账号。</p>
<p><img loading="lazy" decoding="async" width="691" height="616" class="wp-image-8244" src="/wp-content/uploads/2018/06/word-image-824.png" srcset="/wp-content/uploads/2018/06/word-image-824.png 691w, /wp-content/uploads/2018/06/word-image-824-300x267.png 300w" sizes="(max-width: 691px) 100vw, 691px" /></p>
<p>注册成功然后登录进入用户设置</p>
<p><img loading="lazy" decoding="async" width="950" height="304" class="wp-image-8245" src="/wp-content/uploads/2018/06/word-image-825.png" srcset="/wp-content/uploads/2018/06/word-image-825.png 950w, /wp-content/uploads/2018/06/word-image-825-300x96.png 300w, /wp-content/uploads/2018/06/word-image-825-768x246.png 768w" sizes="(max-width: 950px) 100vw, 950px" /></p>
<p>开通smtp服务</p>
<p><img loading="lazy" decoding="async" width="1107" height="644" class="wp-image-8246" src="/wp-content/uploads/2018/06/word-image-826.png" srcset="/wp-content/uploads/2018/06/word-image-826.png 1107w, /wp-content/uploads/2018/06/word-image-826-300x175.png 300w, /wp-content/uploads/2018/06/word-image-826-768x447.png 768w, /wp-content/uploads/2018/06/word-image-826-1024x596.png 1024w" sizes="(max-width: 1107px) 100vw, 1107px" /></p>
<p>设置客户端授权密码</p>
<p><img loading="lazy" decoding="async" width="987" height="529" class="wp-image-8247" src="/wp-content/uploads/2018/06/word-image-827.png" srcset="/wp-content/uploads/2018/06/word-image-827.png 987w, /wp-content/uploads/2018/06/word-image-827-300x161.png 300w, /wp-content/uploads/2018/06/word-image-827-768x412.png 768w" sizes="(max-width: 987px) 100vw, 987px" /></p>
<p>（4） php.ini配置文件中需要启用sockets扩展。</p>
<p><img loading="lazy" decoding="async" width="475" height="229" class="wp-image-8248" src="/wp-content/uploads/2018/06/word-image-828.png" srcset="/wp-content/uploads/2018/06/word-image-828.png 475w, /wp-content/uploads/2018/06/word-image-828-300x145.png 300w" sizes="(max-width: 475px) 100vw, 475px" /></p>
<p>记得重启apache服务器</p>
<h2>3、邮件发送案例</h2>
<p>参考以下示例：</p>
<p><img loading="lazy" decoding="async" width="264" height="48" class="wp-image-8249" src="/wp-content/uploads/2018/06/word-image-829.png" /></p>
<h2>集成到项目中实现忘记密码功能</h2>
<ol>
<li>把上面测试通过的发送邮件的sendEmail复制到[应用目录]/extend目录中</li>
</ol>
<p><img loading="lazy" decoding="async" width="509" height="208" class="wp-image-8250" src="/wp-content/uploads/2018/06/word-image-830.png" srcset="/wp-content/uploads/2018/06/word-image-830.png 509w, /wp-content/uploads/2018/06/word-image-830-300x123.png 300w" sizes="(max-width: 509px) 100vw, 509px" /></p>
<p>注：测试的时候，记得修改demo.php中的基本配置。</p>
<ol>
<li>在common.php文件中封装一个发送邮件的方法sendEmail</li>
</ol>
<p><img loading="lazy" decoding="async" width="1042" height="714" class="wp-image-8251" src="/wp-content/uploads/2018/06/word-image-831.png" srcset="/wp-content/uploads/2018/06/word-image-831.png 1042w, /wp-content/uploads/2018/06/word-image-831-300x206.png 300w, /wp-content/uploads/2018/06/word-image-831-768x526.png 768w, /wp-content/uploads/2018/06/word-image-831-1024x702.png 1024w" sizes="(max-width: 1042px) 100vw, 1042px" /></p>
<ol>
<li>记得测试一下是否ok</li>
</ol>
<p><img loading="lazy" decoding="async" width="1077" height="265" class="wp-image-8252" src="/wp-content/uploads/2018/06/word-image-832.png" srcset="/wp-content/uploads/2018/06/word-image-832.png 1077w, /wp-content/uploads/2018/06/word-image-832-300x74.png 300w, /wp-content/uploads/2018/06/word-image-832-768x189.png 768w, /wp-content/uploads/2018/06/word-image-832-1024x252.png 1024w" sizes="(max-width: 1077px) 100vw, 1077px" /></p>
<h2>实现登录的忘记密码功能</h2>
<p>找回密码的基本流程图解：</p>
<p><img loading="lazy" decoding="async" width="460" height="660" class="wp-image-8253" src="/wp-content/uploads/2018/06/word-image-833.png" srcset="/wp-content/uploads/2018/06/word-image-833.png 460w, /wp-content/uploads/2018/06/word-image-833-209x300.png 209w" sizes="(max-width: 460px) 100vw, 460px" /></p>
<ol>
<li>修改登录页面的忘记密码的链接地址</li>
</ol>
<p><img loading="lazy" decoding="async" width="1135" height="294" class="wp-image-8254" src="/wp-content/uploads/2018/06/word-image-834.png" srcset="/wp-content/uploads/2018/06/word-image-834.png 1135w, /wp-content/uploads/2018/06/word-image-834-300x78.png 300w, /wp-content/uploads/2018/06/word-image-834-768x199.png 768w, /wp-content/uploads/2018/06/word-image-834-1024x265.png 1024w" sizes="(max-width: 1135px) 100vw, 1135px" /></p>
<ol>
<li>在home-publicController-findpassword方法，展示一个输入注册时候的邮箱的模板显示。</li>
</ol>
<p>注:模板可以直接复制登录的login.html模板即可，稍做修改</p>
<p><img loading="lazy" decoding="async" width="1271" height="399" class="wp-image-8255" src="/wp-content/uploads/2018/06/word-image-835.png" srcset="/wp-content/uploads/2018/06/word-image-835.png 1271w, /wp-content/uploads/2018/06/word-image-835-300x94.png 300w, /wp-content/uploads/2018/06/word-image-835-768x241.png 768w, /wp-content/uploads/2018/06/word-image-835-1024x321.png 1024w" sizes="(max-width: 1271px) 100vw, 1271px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="471" height="161" class="wp-image-8256" src="/wp-content/uploads/2018/06/word-image-836.png" srcset="/wp-content/uploads/2018/06/word-image-836.png 471w, /wp-content/uploads/2018/06/word-image-836-300x103.png 300w" sizes="(max-width: 471px) 100vw, 471px" /></p>
<ol>
<li>给上面的按钮绑定单击事件，进行发送ajax，触发发送邮件。</li>
</ol>
<p><img loading="lazy" decoding="async" width="1032" height="380" class="wp-image-8257" src="/wp-content/uploads/2018/06/word-image-837.png" srcset="/wp-content/uploads/2018/06/word-image-837.png 1032w, /wp-content/uploads/2018/06/word-image-837-300x110.png 300w, /wp-content/uploads/2018/06/word-image-837-768x283.png 768w, /wp-content/uploads/2018/06/word-image-837-1024x377.png 1024w" sizes="(max-width: 1032px) 100vw, 1032px" /></p>
<ol>
<li>在home模块的PublicController控制器中的findPassword方法中判断是否是ajax请求，接收重置的邮箱，进行一些发送邮件前的判断</li>
</ol>
<p><img loading="lazy" decoding="async" width="1000" height="504" class="wp-image-8258" src="/wp-content/uploads/2018/06/word-image-838.png" srcset="/wp-content/uploads/2018/06/word-image-838.png 1000w, /wp-content/uploads/2018/06/word-image-838-300x151.png 300w, /wp-content/uploads/2018/06/word-image-838-768x387.png 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></p>
<ol>
<li>当输入的邮箱在系统中存在的时候，就进行发送邮件。</li>
</ol>
<p>需要把修改密码的链接地址构造起来一个a标签，发送给邮箱的用户：</p>
<p>类似于： php15商城&#8211; &lt;a href=”http://域名/修改密码的新地址”&gt;点我找回密码&lt;/a&gt;</p>
<p>获取当前网站的请求协议和域名：</p>
<p><img loading="lazy" decoding="async" width="409" height="82" class="wp-image-8259" src="/wp-content/uploads/2018/06/word-image-839.png" srcset="/wp-content/uploads/2018/06/word-image-839.png 409w, /wp-content/uploads/2018/06/word-image-839-300x60.png 300w" sizes="(max-width: 409px) 100vw, 409px" /> <img loading="lazy" decoding="async" width="1233" height="688" class="wp-image-8260" src="/wp-content/uploads/2018/06/word-image-840.png" srcset="/wp-content/uploads/2018/06/word-image-840.png 1233w, /wp-content/uploads/2018/06/word-image-840-300x167.png 300w, /wp-content/uploads/2018/06/word-image-840-768x429.png 768w, /wp-content/uploads/2018/06/word-image-840-1024x571.png 1024w" sizes="(max-width: 1233px) 100vw, 1233px" /></p>
<p>发送成功或失败，在html静态页面给出对应的提示：</p>
<p><img loading="lazy" decoding="async" width="1043" height="460" class="wp-image-8261" src="/wp-content/uploads/2018/06/word-image-841.png" srcset="/wp-content/uploads/2018/06/word-image-841.png 1043w, /wp-content/uploads/2018/06/word-image-841-300x132.png 300w, /wp-content/uploads/2018/06/word-image-841-768x339.png 768w, /wp-content/uploads/2018/06/word-image-841-1024x452.png 1024w" sizes="(max-width: 1043px) 100vw, 1043px" /></p>
<p>注：上面提示layer.msg需要引入layer弹出层插件</p>
<p>邮件收到的地址如下：</p>
<p><img loading="lazy" decoding="async" width="618" height="210" class="wp-image-8262" src="/wp-content/uploads/2018/06/word-image-842.png" srcset="/wp-content/uploads/2018/06/word-image-842.png 618w, /wp-content/uploads/2018/06/word-image-842-300x102.png 300w" sizes="(max-width: 618px) 100vw, 618px" /></p>
<ol>
<li>建立一个修改密码的方法updpassword。</li>
</ol>
<p><img loading="lazy" decoding="async" width="920" height="300" class="wp-image-8263" src="/wp-content/uploads/2018/06/word-image-843.png" srcset="/wp-content/uploads/2018/06/word-image-843.png 920w, /wp-content/uploads/2018/06/word-image-843-300x98.png 300w, /wp-content/uploads/2018/06/word-image-843-768x250.png 768w" sizes="(max-width: 920px) 100vw, 920px" /></p>
<p>模板内容如下：</p>
<p><img loading="lazy" decoding="async" width="1281" height="595" class="wp-image-8264" src="/wp-content/uploads/2018/06/word-image-844.png" srcset="/wp-content/uploads/2018/06/word-image-844.png 1281w, /wp-content/uploads/2018/06/word-image-844-300x139.png 300w, /wp-content/uploads/2018/06/word-image-844-768x357.png 768w, /wp-content/uploads/2018/06/word-image-844-1024x476.png 1024w" sizes="(max-width: 1281px) 100vw, 1281px" /> <img loading="lazy" decoding="async" width="520" height="246" class="wp-image-8265" src="/wp-content/uploads/2018/06/word-image-845.png" srcset="/wp-content/uploads/2018/06/word-image-845.png 520w, /wp-content/uploads/2018/06/word-image-845-300x142.png 300w" sizes="(max-width: 520px) 100vw, 520px" /></p>
<ol>
<li>给上面的id=updPassword绑定单击事件，发送ajax请求，修改密码</li>
</ol>
<p><img loading="lazy" decoding="async" width="1069" height="597" class="wp-image-8266" src="/wp-content/uploads/2018/06/word-image-846.png" srcset="/wp-content/uploads/2018/06/word-image-846.png 1069w, /wp-content/uploads/2018/06/word-image-846-300x168.png 300w, /wp-content/uploads/2018/06/word-image-846-768x429.png 768w, /wp-content/uploads/2018/06/word-image-846-1024x572.png 1024w" sizes="(max-width: 1069px) 100vw, 1069px" /></p>
<p>注：上面模板也要引入layer弹出层插件</p>
<ol>
<li>在updpassword中判断是否是ajax请求，完成修改用户的密码</li>
</ol>
<p><img loading="lazy" decoding="async" width="1047" height="604" class="wp-image-8267" src="/wp-content/uploads/2018/06/word-image-847.png" srcset="/wp-content/uploads/2018/06/word-image-847.png 1047w, /wp-content/uploads/2018/06/word-image-847-300x173.png 300w, /wp-content/uploads/2018/06/word-image-847-768x443.png 768w, /wp-content/uploads/2018/06/word-image-847-1024x591.png 1024w" sizes="(max-width: 1047px) 100vw, 1047px" /></p>
<p>同时在Memer模型的编辑的前钩子中完成密码的加密：</p>
<p><img loading="lazy" decoding="async" width="1001" height="416" class="wp-image-8268" src="/wp-content/uploads/2018/06/word-image-848.png" srcset="/wp-content/uploads/2018/06/word-image-848.png 1001w, /wp-content/uploads/2018/06/word-image-848-300x125.png 300w, /wp-content/uploads/2018/06/word-image-848-768x319.png 768w" sizes="(max-width: 1001px) 100vw, 1001px" /></p>
<h2>验证邮件地址的合法性</h2>
<ol>
<li>因为用户可以篡改邮件的链接地址，如把id=1的用户改为id=3的用于，这样就把其他用户的密码给修改了</li>
<li>还要保证链接地址有个有效期比如1天。</li>
</ol>
<p>具体做法：</p>
<ol>
<li>在发送邮件的时候，给携带携带3个参数，member_id、time、加密的字符串。</li>
</ol>
<p>加密的字符串是member_id和time和我们配置中一个配置项加密的结果。</p>
<p><img loading="lazy" decoding="async" width="1248" height="506" class="wp-image-8269" src="/wp-content/uploads/2018/06/word-image-849.png" srcset="/wp-content/uploads/2018/06/word-image-849.png 1248w, /wp-content/uploads/2018/06/word-image-849-300x122.png 300w, /wp-content/uploads/2018/06/word-image-849-768x311.png 768w, /wp-content/uploads/2018/06/word-image-849-1024x415.png 1024w" sizes="(max-width: 1248px) 100vw, 1248px" /></p>
<p>邮件地址生成的a链接地址如下：</p>
<p><a href="/goto/wto7" rel="nofollow">http://www.php15shop.com/home/public/updpassword/member_id/2/time/1529202630/hash/50730d397f3b07e62e52e4c5b5e1cf47</a></p>
<ol>
<li>在更新密码的updPassword方法中，判断邮件地址是否被篡改，且要在指定的有效期内</li>
</ol>
<p><img loading="lazy" decoding="async" width="1011" height="504" class="wp-image-8270" src="/wp-content/uploads/2018/06/word-image-850.png" srcset="/wp-content/uploads/2018/06/word-image-850.png 1011w, /wp-content/uploads/2018/06/word-image-850-300x150.png 300w, /wp-content/uploads/2018/06/word-image-850-768x383.png 768w" sizes="(max-width: 1011px) 100vw, 1011px" /></p>
<p>以后凡是防止用户篡改表单或者url中的参数，解决办法：加密后对比处理。</p>
<h1>二、QQ互联</h1>
<h2>1、注册QQ互联应用</h2>
<p>先去腾讯开发平台注册账号：<a href="/goto/efjr" rel="nofollow">http://open.qq.com/</a> 。</p>
<p><img loading="lazy" decoding="async" width="1342" height="240" class="wp-image-8271" src="/wp-content/uploads/2018/06/word-image-851.png" srcset="/wp-content/uploads/2018/06/word-image-851.png 1342w, /wp-content/uploads/2018/06/word-image-851-300x54.png 300w, /wp-content/uploads/2018/06/word-image-851-768x137.png 768w, /wp-content/uploads/2018/06/word-image-851-1024x183.png 1024w" sizes="(max-width: 1342px) 100vw, 1342px" /></p>
<p>等资料审核通过后便可去qq互联创建应用： <a href="/goto/p1rq" rel="nofollow">https://connect.qq.com/manage.html#/</a> ，创建好如下所示。</p>
<p><img loading="lazy" decoding="async" width="1048" height="604" class="wp-image-8272" src="/wp-content/uploads/2018/06/word-image-852.png" srcset="/wp-content/uploads/2018/06/word-image-852.png 1048w, /wp-content/uploads/2018/06/word-image-852-300x173.png 300w, /wp-content/uploads/2018/06/word-image-852-768x443.png 768w, /wp-content/uploads/2018/06/word-image-852-1024x590.png 1024w" sizes="(max-width: 1048px) 100vw, 1048px" /></p>
<p>点击上面的查看，进入以下页面：</p>
<p><img loading="lazy" decoding="async" width="1039" height="562" class="wp-image-8273" src="/wp-content/uploads/2018/06/word-image-853.png" srcset="/wp-content/uploads/2018/06/word-image-853.png 1039w, /wp-content/uploads/2018/06/word-image-853-300x162.png 300w, /wp-content/uploads/2018/06/word-image-853-768x415.png 768w, /wp-content/uploads/2018/06/word-image-853-1024x554.png 1024w" sizes="(max-width: 1039px) 100vw, 1039px" /></p>
<p>回调域设置：</p>
<p><img loading="lazy" decoding="async" width="899" height="379" class="wp-image-8274" src="/wp-content/uploads/2018/06/word-image-854.png" srcset="/wp-content/uploads/2018/06/word-image-854.png 899w, /wp-content/uploads/2018/06/word-image-854-300x126.png 300w, /wp-content/uploads/2018/06/word-image-854-768x324.png 768w" sizes="(max-width: 899px) 100vw, 899px" /></p>
<p>注意：</p>
<ol>
<li>上面的应用虽然审核不通过，但是不影响我们使用。我们只需要获取应用的appid和key即可。</li>
<li>只有网站备案通过，应用才可以审核通过，没通过审核的应用只能使用我们所注册的qq号进行登录测试，审核通过后就没限制。</li>
<li>当我们本地网站集成qq登录时，本地域名回调地址域需要和上面应用设置的一样。</li>
</ol>
<p>注意：</p>
<p>当应用创建好之后，立刻记住appid和appkey ,设置好和我们本地网站域名一样的回调域和回调地址。</p>
<h2>2、下载QQ登录PHP-SDK 集成包</h2>
<p>下载地址：<a href="/goto/il7d" rel="nofollow">http://wiki.connect.qq.com/</a></p>
<p><img loading="lazy" decoding="async" width="1073" height="691" class="wp-image-8275" src="/wp-content/uploads/2018/06/word-image-855.png" srcset="/wp-content/uploads/2018/06/word-image-855.png 1073w, /wp-content/uploads/2018/06/word-image-855-300x193.png 300w, /wp-content/uploads/2018/06/word-image-855-768x495.png 768w, /wp-content/uploads/2018/06/word-image-855-1024x659.png 1024w" sizes="(max-width: 1073px) 100vw, 1073px" /></p>
<p>下载php版本：</p>
<p><img loading="lazy" decoding="async" width="1148" height="484" class="wp-image-8276" src="/wp-content/uploads/2018/06/word-image-856.png" srcset="/wp-content/uploads/2018/06/word-image-856.png 1148w, /wp-content/uploads/2018/06/word-image-856-300x126.png 300w, /wp-content/uploads/2018/06/word-image-856-768x324.png 768w, /wp-content/uploads/2018/06/word-image-856-1024x432.png 1024w" sizes="(max-width: 1148px) 100vw, 1148px" /></p>
<p>下载下来如下所示：</p>
<p><img loading="lazy" decoding="async" width="271" height="29" class="wp-image-8277" src="/wp-content/uploads/2018/06/word-image-857.png" /></p>
<h2>进行QQ登录前的参数配置</h2>
<p>1、把qq登录开发包SDK中的以下目录复制到网站根目录下,即[应用目录]/public/中</p>
<p><img loading="lazy" decoding="async" width="752" height="349" class="wp-image-8278" src="/wp-content/uploads/2018/06/word-image-858.png" srcset="/wp-content/uploads/2018/06/word-image-858.png 752w, /wp-content/uploads/2018/06/word-image-858-300x139.png 300w" sizes="(max-width: 752px) 100vw, 752px" /></p>
<ol>
<li>直接在浏览器中访问connect2.1目录中即可</li>
</ol>
<p><img loading="lazy" decoding="async" width="553" height="155" class="wp-image-8279" src="/wp-content/uploads/2018/06/word-image-859.png" srcset="/wp-content/uploads/2018/06/word-image-859.png 553w, /wp-content/uploads/2018/06/word-image-859-300x84.png 300w" sizes="(max-width: 553px) 100vw, 553px" /></p>
<p>点击上面的设置配置项。</p>
<p><img loading="lazy" decoding="async" width="1108" height="489" class="wp-image-8280" src="/wp-content/uploads/2018/06/word-image-860.png" srcset="/wp-content/uploads/2018/06/word-image-860.png 1108w, /wp-content/uploads/2018/06/word-image-860-300x132.png 300w, /wp-content/uploads/2018/06/word-image-860-768x339.png 768w, /wp-content/uploads/2018/06/word-image-860-1024x452.png 1024w" sizes="(max-width: 1108px) 100vw, 1108px" /></p>
<p>进入如下：</p>
<p><img loading="lazy" decoding="async" width="1014" height="187" class="wp-image-8281" src="/wp-content/uploads/2018/06/word-image-861.png" srcset="/wp-content/uploads/2018/06/word-image-861.png 1014w, /wp-content/uploads/2018/06/word-image-861-300x55.png 300w, /wp-content/uploads/2018/06/word-image-861-768x142.png 768w" sizes="(max-width: 1014px) 100vw, 1014px" /></p>
<p>点击上面的example,，点击qq登录登录的logo图标，如果能够有一个qq登录的弹框说明配置成功</p>
<p><img loading="lazy" decoding="async" width="981" height="452" class="wp-image-8282" src="/wp-content/uploads/2018/06/word-image-862.png" srcset="/wp-content/uploads/2018/06/word-image-862.png 981w, /wp-content/uploads/2018/06/word-image-862-300x138.png 300w, /wp-content/uploads/2018/06/word-image-862-768x354.png 768w" sizes="(max-width: 981px) 100vw, 981px" /></p>
<p>注意：我们应用中的域名如果备案审核通过，则只能用我们所注册的qq进行登录测试</p>
<p>用注册的qq登录成功之后，会进入到我们之前所设置的callback回调地址</p>
<p><img loading="lazy" decoding="async" width="1120" height="173" class="wp-image-8283" src="/wp-content/uploads/2018/06/word-image-863.png" srcset="/wp-content/uploads/2018/06/word-image-863.png 1120w, /wp-content/uploads/2018/06/word-image-863-300x46.png 300w, /wp-content/uploads/2018/06/word-image-863-768x119.png 768w, /wp-content/uploads/2018/06/word-image-863-1024x158.png 1024w" sizes="(max-width: 1120px) 100vw, 1120px" /></p>
<h2>分析如何唤起QQ登录弹框</h2>
<p>分析qq图标的logo按钮</p>
<p><img loading="lazy" decoding="async" width="676" height="398" class="wp-image-8284" src="/wp-content/uploads/2018/06/word-image-864.png" srcset="/wp-content/uploads/2018/06/word-image-864.png 676w, /wp-content/uploads/2018/06/word-image-864-300x177.png 300w" sizes="(max-width: 676px) 100vw, 676px" /></p>
<p>再去对应的文件中查看toQzoneLogin()事件：</p>
<p><img loading="lazy" decoding="async" width="1064" height="323" class="wp-image-8285" src="/wp-content/uploads/2018/06/word-image-865.png" srcset="/wp-content/uploads/2018/06/word-image-865.png 1064w, /wp-content/uploads/2018/06/word-image-865-300x91.png 300w, /wp-content/uploads/2018/06/word-image-865-768x233.png 768w, /wp-content/uploads/2018/06/word-image-865-1024x311.png 1024w" sizes="(max-width: 1064px) 100vw, 1064px" /></p>
<p>可见事件在一个新窗口打开oauth 中的index.php。找到此文件</p>
<p><img loading="lazy" decoding="async" width="738" height="188" class="wp-image-8286" src="/wp-content/uploads/2018/06/word-image-866.png" srcset="/wp-content/uploads/2018/06/word-image-866.png 738w, /wp-content/uploads/2018/06/word-image-866-300x76.png 300w" sizes="(max-width: 738px) 100vw, 738px" /></p>
<p>可见，以上3行代码最终唤起qq登录弹框！。后面在项目中，点击qq登录的logo图标执行这三行代码即可完成qq登录弹框。</p>
<h2>5、集成到项目中实现QQ登录</h2>
<p>qq登录流程图：</p>
<p><img loading="lazy" decoding="async" width="1191" height="408" class="wp-image-8287" src="/wp-content/uploads/2018/06/word-image-867.png" srcset="/wp-content/uploads/2018/06/word-image-867.png 1191w, /wp-content/uploads/2018/06/word-image-867-300x103.png 300w, /wp-content/uploads/2018/06/word-image-867-768x263.png 768w, /wp-content/uploads/2018/06/word-image-867-1024x351.png 1024w" sizes="(max-width: 1191px) 100vw, 1191px" /></p>
<h3>1、点击qq登录的图片，唤起qq登录弹框</h3>
<ol>
<li>把之前测好的API目录复制到extend/qqLogin/目录下面</li>
</ol>
<p><img loading="lazy" decoding="async" width="736" height="205" class="wp-image-8288" src="/wp-content/uploads/2018/06/word-image-868.png" srcset="/wp-content/uploads/2018/06/word-image-868.png 736w, /wp-content/uploads/2018/06/word-image-868-300x84.png 300w" sizes="(max-width: 736px) 100vw, 736px" /></p>
<p>注：如果之前的配置参数写错了，可以直接修改inc.php文件</p>
<p><img loading="lazy" decoding="async" width="1270" height="164" class="wp-image-8289" src="/wp-content/uploads/2018/06/word-image-869.png" srcset="/wp-content/uploads/2018/06/word-image-869.png 1270w, /wp-content/uploads/2018/06/word-image-869-300x39.png 300w, /wp-content/uploads/2018/06/word-image-869-768x99.png 768w, /wp-content/uploads/2018/06/word-image-869-1024x132.png 1024w" sizes="(max-width: 1270px) 100vw, 1270px" /></p>
<ol>
<li>在login.html的登录模板给qq的登录图标，设置一个url地址，跳到home-memberController-qqLogin方法：</li>
</ol>
<p><img loading="lazy" decoding="async" width="1266" height="345" class="wp-image-8290" src="/wp-content/uploads/2018/06/word-image-870.png" srcset="/wp-content/uploads/2018/06/word-image-870.png 1266w, /wp-content/uploads/2018/06/word-image-870-300x82.png 300w, /wp-content/uploads/2018/06/word-image-870-768x209.png 768w, /wp-content/uploads/2018/06/word-image-870-1024x279.png 1024w" sizes="(max-width: 1266px) 100vw, 1266px" /></p>
<p>qqLogin方法如下：</p>
<p><img loading="lazy" decoding="async" width="931" height="362" class="wp-image-8291" src="/wp-content/uploads/2018/06/word-image-871.png" srcset="/wp-content/uploads/2018/06/word-image-871.png 931w, /wp-content/uploads/2018/06/word-image-871-300x117.png 300w, /wp-content/uploads/2018/06/word-image-871-768x299.png 768w" sizes="(max-width: 931px) 100vw, 931px" /></p>
<p>点击下面的qq登录，出现qq弹框说明引入项目成功：</p>
<p><img loading="lazy" decoding="async" width="553" height="142" class="wp-image-8292" src="/wp-content/uploads/2018/06/word-image-872.png" srcset="/wp-content/uploads/2018/06/word-image-872.png 553w, /wp-content/uploads/2018/06/word-image-872-300x77.png 300w" sizes="(max-width: 553px) 100vw, 553px" /> <img loading="lazy" decoding="async" width="738" height="364" class="wp-image-8293" src="/wp-content/uploads/2018/06/word-image-873.png" srcset="/wp-content/uploads/2018/06/word-image-873.png 738w, /wp-content/uploads/2018/06/word-image-873-300x148.png 300w" sizes="(max-width: 738px) 100vw, 738px" /></p>
<h3>在qq回调域callback中获取openid和token</h3>
<ol>
<li>在home模块member控制器中建立一个qq回调方法名为qqCallback</li>
</ol>
<p><img loading="lazy" decoding="async" width="1043" height="529" class="wp-image-8294" src="/wp-content/uploads/2018/06/word-image-874.png" srcset="/wp-content/uploads/2018/06/word-image-874.png 1043w, /wp-content/uploads/2018/06/word-image-874-300x152.png 300w, /wp-content/uploads/2018/06/word-image-874-768x390.png 768w, /wp-content/uploads/2018/06/word-image-874-1024x519.png 1024w" sizes="(max-width: 1043px) 100vw, 1043px" /></p>
<p>获取到openid和token和qq用户相关的信息如下：</p>
<p><img loading="lazy" decoding="async" width="1209" height="716" class="wp-image-8295" src="/wp-content/uploads/2018/06/word-image-875.png" srcset="/wp-content/uploads/2018/06/word-image-875.png 1209w, /wp-content/uploads/2018/06/word-image-875-300x178.png 300w, /wp-content/uploads/2018/06/word-image-875-768x455.png 768w, /wp-content/uploads/2018/06/word-image-875-1024x606.png 1024w" sizes="(max-width: 1209px) 100vw, 1209px" /></p>
<h3>实现qq完成系统的登录</h3>
<p>在前台会员表sh_member中加一个字段nickname在，记录用户登录成功的昵称。</p>
<p><img loading="lazy" decoding="async" width="548" height="218" class="wp-image-8296" src="/wp-content/uploads/2018/06/word-image-876.png" srcset="/wp-content/uploads/2018/06/word-image-876.png 548w, /wp-content/uploads/2018/06/word-image-876-300x119.png 300w" sizes="(max-width: 548px) 100vw, 548px" /></p>
<p>1、先去系统中判断有没有此qq的openid 。做不同的业务逻辑</p>
<p><img loading="lazy" decoding="async" width="714" height="296" class="wp-image-8297" src="/wp-content/uploads/2018/06/word-image-877.png" srcset="/wp-content/uploads/2018/06/word-image-877.png 714w, /wp-content/uploads/2018/06/word-image-877-300x124.png 300w" sizes="(max-width: 714px) 100vw, 714px" /></p>
<p>代码如下：</p>
<p><img loading="lazy" decoding="async" width="826" height="708" class="wp-image-8298" src="/wp-content/uploads/2018/06/word-image-878.png" srcset="/wp-content/uploads/2018/06/word-image-878.png 826w, /wp-content/uploads/2018/06/word-image-878-300x257.png 300w, /wp-content/uploads/2018/06/word-image-878-768x658.png 768w" sizes="(max-width: 826px) 100vw, 826px" /></p>
<p>注：需要在member模型的入库的前钩子中，对密码加密进行判断，因为qq登录没有密码</p>
<p><img loading="lazy" decoding="async" width="824" height="423" class="wp-image-8299" src="/wp-content/uploads/2018/06/word-image-879.png" srcset="/wp-content/uploads/2018/06/word-image-879.png 824w, /wp-content/uploads/2018/06/word-image-879-300x154.png 300w, /wp-content/uploads/2018/06/word-image-879-768x394.png 768w" sizes="(max-width: 824px) 100vw, 824px" /></p>
<p>登录成功效果：</p>
<p><img loading="lazy" decoding="async" width="488" height="121" class="wp-image-8300" src="/wp-content/uploads/2018/06/word-image-880.png" srcset="/wp-content/uploads/2018/06/word-image-880.png 488w, /wp-content/uploads/2018/06/word-image-880-300x74.png 300w" sizes="(max-width: 488px) 100vw, 488px" /></p>
<h1>三、完成分类列表页的面包屑导航</h1>
<p>如下：</p>
<p><img loading="lazy" decoding="async" width="918" height="182" class="wp-image-8301" src="/wp-content/uploads/2018/06/word-image-881.png" srcset="/wp-content/uploads/2018/06/word-image-881.png 918w, /wp-content/uploads/2018/06/word-image-881-300x59.png 300w, /wp-content/uploads/2018/06/word-image-881-768x152.png 768w" sizes="(max-width: 918px) 100vw, 918px" /></p>
<p>面包屑导航就是找当前分类的父分类。</p>
<p>核心：</p>
<p>找子分类：传递当前分类的cat_id,进行递归查找。</p>
<p>找父分类：传递当前分类的pid,进行递归查找。</p>
<p>代码</p>
<ol>
<li>设置好首页的分类的链接地址：以三级分类筛选地址为例：</li>
</ol>
<p><img loading="lazy" decoding="async" width="1262" height="623" class="wp-image-8302" src="/wp-content/uploads/2018/06/word-image-882.png" srcset="/wp-content/uploads/2018/06/word-image-882.png 1262w, /wp-content/uploads/2018/06/word-image-882-300x148.png 300w, /wp-content/uploads/2018/06/word-image-882-768x379.png 768w, /wp-content/uploads/2018/06/word-image-882-1024x506.png 1024w" sizes="(max-width: 1262px) 100vw, 1262px" /></p>
<ol>
<li>在home-CategoryController-index方法，取出当前分类的面包屑导航相关数据，并分配到模板中</li>
</ol>
<p><img loading="lazy" decoding="async" width="859" height="395" class="wp-image-8303" src="/wp-content/uploads/2018/06/word-image-883.png" srcset="/wp-content/uploads/2018/06/word-image-883.png 859w, /wp-content/uploads/2018/06/word-image-883-300x138.png 300w, /wp-content/uploads/2018/06/word-image-883-768x353.png 768w" sizes="(max-width: 859px) 100vw, 859px" /></p>
<p>同时在home模块的Category模型中定义一个getFamilyCats的方法，获取父分类</p>
<p><img loading="lazy" decoding="async" width="1034" height="600" class="wp-image-8304" src="/wp-content/uploads/2018/06/word-image-884.png" srcset="/wp-content/uploads/2018/06/word-image-884.png 1034w, /wp-content/uploads/2018/06/word-image-884-300x174.png 300w, /wp-content/uploads/2018/06/word-image-884-768x446.png 768w, /wp-content/uploads/2018/06/word-image-884-1024x594.png 1024w" sizes="(max-width: 1034px) 100vw, 1034px" /></p>
<ol>
<li>模板中遍历数据</li>
</ol>
<p>模板复制前台模板的list.html到 /home/view/category/目录下，并改名为index.html</p>
<p><img loading="lazy" decoding="async" width="592" height="486" class="wp-image-8305" src="/wp-content/uploads/2018/06/word-image-885.png" srcset="/wp-content/uploads/2018/06/word-image-885.png 592w, /wp-content/uploads/2018/06/word-image-885-300x246.png 300w" sizes="(max-width: 592px) 100vw, 592px" /></p>
<p>遍历数据：</p>
<p><img loading="lazy" decoding="async" width="1256" height="427" class="wp-image-8306" src="/wp-content/uploads/2018/06/word-image-886.png" srcset="/wp-content/uploads/2018/06/word-image-886.png 1256w, /wp-content/uploads/2018/06/word-image-886-300x102.png 300w, /wp-content/uploads/2018/06/word-image-886-768x261.png 768w, /wp-content/uploads/2018/06/word-image-886-1024x348.png 1024w" sizes="(max-width: 1256px) 100vw, 1256px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="352" height="97" class="wp-image-8307" src="/wp-content/uploads/2018/06/word-image-887.png" srcset="/wp-content/uploads/2018/06/word-image-887.png 352w, /wp-content/uploads/2018/06/word-image-887-300x83.png 300w" sizes="(max-width: 352px) 100vw, 352px" /></p>
<h1>四、实现分类列表页左侧分类菜单</h1>
<h3>分析</h3>
<p>思路：</p>
<p>不管点击哪一个分类到此分类列表页，下图的蓝色区域都是当前分类的最顶级分类。</p>
<p>蓝色顶级分类下面含有二级分类，二级分类下又包含三级分类。</p>
<p>如下：</p>
<p>顶级分类：电脑办公</p>
<p>二级分类：电脑整机、电脑配件、办公打印等</p>
<p>三级分类：如电脑整机下有笔记本、超极本、平板电脑</p>
<p><img loading="lazy" decoding="async" width="233" height="316" class="wp-image-8308" src="/wp-content/uploads/2018/06/word-image-888.png" srcset="/wp-content/uploads/2018/06/word-image-888.png 233w, /wp-content/uploads/2018/06/word-image-888-221x300.png 221w" sizes="(max-width: 233px) 100vw, 233px" /></p>
<h3>代码实现</h3>
<ol>
<li>在index方法中取出所有的分类，以cat_id 为二维数组下标，把每个元素通过pid进行分组</li>
</ol>
<p><img loading="lazy" decoding="async" width="897" height="672" class="wp-image-8309" src="/wp-content/uploads/2018/06/word-image-889.png" srcset="/wp-content/uploads/2018/06/word-image-889.png 897w, /wp-content/uploads/2018/06/word-image-889-300x225.png 300w, /wp-content/uploads/2018/06/word-image-889-768x575.png 768w" sizes="(max-width: 897px) 100vw, 897px" /></p>
<ol>
<li>模板中遍历数据</li>
</ol>
<p><img loading="lazy" decoding="async" width="1224" height="508" class="wp-image-8310" src="/wp-content/uploads/2018/06/word-image-890.png" srcset="/wp-content/uploads/2018/06/word-image-890.png 1224w, /wp-content/uploads/2018/06/word-image-890-300x125.png 300w, /wp-content/uploads/2018/06/word-image-890-768x319.png 768w, /wp-content/uploads/2018/06/word-image-890-1024x425.png 1024w" sizes="(max-width: 1224px) 100vw, 1224px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="241" height="276" class="wp-image-8311" src="/wp-content/uploads/2018/06/word-image-891.png" /></p>
<h1>五、完成分类列表页商品的展示</h1>
<h3>分析</h3>
<p>当点击某个分类的时候，应该把当前分类及其子孙分类下面的所有商品取出来。</p>
<p>如：当点击华为手机分类的时候，应该把华为分类下面的所有的商品取出来。</p>
<p>如：当点击国内手机分类时，应该把国内手机分类下面的所有的子孙分类的商品都取出来</p>
<h3>代码实现</h3>
<p>1、在home-categoryController-index方法中，取出当前分类及其子孙分类所有的商品</p>
<p>2、模板中遍历</p>
<p><img loading="lazy" decoding="async" width="1194" height="542" class="wp-image-8312" src="/wp-content/uploads/2018/06/word-image-892.png" srcset="/wp-content/uploads/2018/06/word-image-892.png 1194w, /wp-content/uploads/2018/06/word-image-892-300x136.png 300w, /wp-content/uploads/2018/06/word-image-892-768x349.png 768w, /wp-content/uploads/2018/06/word-image-892-1024x465.png 1024w" sizes="(max-width: 1194px) 100vw, 1194px" /> <img loading="lazy" decoding="async" width="1336" height="399" class="wp-image-8313" src="/wp-content/uploads/2018/06/word-image-893.png" srcset="/wp-content/uploads/2018/06/word-image-893.png 1336w, /wp-content/uploads/2018/06/word-image-893-300x90.png 300w, /wp-content/uploads/2018/06/word-image-893-768x229.png 768w, /wp-content/uploads/2018/06/word-image-893-1024x306.png 1024w" sizes="(max-width: 1336px) 100vw, 1336px" /></p>
<p>效果：</p>
<p><img loading="lazy" decoding="async" width="985" height="328" class="wp-image-8314" src="/wp-content/uploads/2018/06/word-image-894.png" srcset="/wp-content/uploads/2018/06/word-image-894.png 985w, /wp-content/uploads/2018/06/word-image-894-300x100.png 300w, /wp-content/uploads/2018/06/word-image-894-768x256.png 768w" sizes="(max-width: 985px) 100vw, 985px" /></p>
<h1>六、完成商品详情页</h1>
<h2>1、实现商品详情页面包屑导航</h2>
<h2>2、商品基本数据的展示</h2>
<h2>3、实现商品详情页中的图片画廊的展示</h2>
<h2>4、实现商品详情页属性的展示</h2>
<h3>分析</h3>
<p>单选属性：</p>
<p><img loading="lazy" decoding="async" width="662" height="241" class="wp-image-8315" src="/wp-content/uploads/2018/06/word-image-895.png" srcset="/wp-content/uploads/2018/06/word-image-895.png 662w, /wp-content/uploads/2018/06/word-image-895-300x109.png 300w" sizes="(max-width: 662px) 100vw, 662px" /></p>
<p>注意一点：</p>
<p>因为单选属性的值可能有多个，所以我们可以把根据属性的attr_id进行分组，把相同属性的attr_id的值归为同一组，方便在模板中进行循环遍历。</p>
<p>唯一属性：</p>
<p><img loading="lazy" decoding="async" width="858" height="178" class="wp-image-8316" src="/wp-content/uploads/2018/06/word-image-896.png" srcset="/wp-content/uploads/2018/06/word-image-896.png 858w, /wp-content/uploads/2018/06/word-image-896-300x62.png 300w, /wp-content/uploads/2018/06/word-image-896-768x159.png 768w" sizes="(max-width: 858px) 100vw, 858px" /></p>
<p>唯一属性不需要分组，因为唯一属性的值只有一个。</p>
<h3>代码实现</h3>
<h2>5、实现商品详情页的浏览历史</h2>
<h3>分析</h3>
<p><img loading="lazy" decoding="async" width="290" height="182" class="wp-image-8317" src="/wp-content/uploads/2018/06/word-image-897.png" /></p>
<p>基本思路：</p>
<p>①可以使用cookie技术来实现浏览商品历史的存储，cookie中存储商品的goods_id即可。</p>
<p>只所以只存储浏览商品的id，因为商品的价格后面可能随时会变化，且记录一般存储3-5个。</p>
<p>②最新访问的商品应该放置在浏览历史的第一个位置</p>
<p>③当浏览历史存储量到达最大值（如超过5），应把最早访问的商品id给移除。</p>
<p>④当访问相同商品的时候，只保留最后访问的商品，即数组需要删除重复的元素。</p>
<p>cookie怎么存储所访问商品的id: 我们把访问商品的id存进数组中，再把数组写入到cookie中，形式如：[1,4,6,2,8]。</p>
<h3>代码实现</h3>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>/%e5%90%8e%e5%8f%b0%e6%a1%86%e6%9e%b6/8241.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
