当前位置: 首页 > news >正文

北苑做网站的公司制作网页类型一般分为什么

北苑做网站的公司,制作网页类型一般分为什么,网站备案信息被注销,自定义表情在线制作学习目标 了解搭建一般网站的简便方式了解最原始一般站点搭建了解内容管理站点搭建了解权限设计及完成了解使用设计模式减少代码冗余了解前端拖拽页面生成及生成了解自定义数据的创建了解动态生成的前端页如何绑定自定义数据 开发环境 Windows7 *64 SP1php5.6apache/nginxth…学习目标 了解搭建一般网站的简便方式了解最原始一般站点搭建了解内容管理站点搭建了解权限设计及完成了解使用设计模式减少代码冗余了解前端拖拽页面生成及生成了解自定义数据的创建了解动态生成的前端页如何绑定自定义数据 开发环境 Windows7 *64 SP1php5.6apache/nginxthinkphp5.1mysqlphpstudy2018sqlyoglayoutit 声明 文章为从0到1了解内容管理系统搭建与编写由于一篇文章内容篇幅过长文章内容经过压缩该项目中相同逻辑的实现只以一个实例作为描述主要以核心关键功能的开发作为主要的讲解步骤。如有想学习完整内容系统编写可在留言区留言我会尽快完成完整版的实战教程发布。谢谢。本篇不涉及vue、nodejs的前端框架。 知识门槛 以下内容有过一些了解即可 htmlsqlphptp框架 面向人群 刚学了php不懂怎么用的同学会一点点建站但是又不清楚流程的同学学习完了一些框架不懂怎么使用的同学有过一些web开发经验的同学等希望本篇文章对每一个阅读完的同学都有帮助 注意本篇文章部分细节由于篇幅关系并不会去深入完善并且相同逻辑的实现只以一个实例作为描述主要以核心功能的开发作为主要的讲解步骤。本篇不涉及vue、nodejs的前端框架。 一、 了解一些专业术语及概念 在了解搭建网站前需要普及一些基本的知识概念防止某些同学在一方面有概念性的错误并且我个人认为在学习一方面知识前需要对这一方面的知识有一个广度的了解这里所指的广度为这东西是用来干什么的、作用是什么、为什么要这样写所以在正式开始介绍如何编写CMS前将会介绍这一部分内容。为了方便阅读第一点内容引入我另外一篇原创文章。 1.1了解浏览一个网页的基本流程方式 在学习一门技术的时候往往是了解整体体系架构才能更好的学习不然在学习的过程中会出现不知道为什么这样做做出这一部分是该整体部分的哪个区域只会跟着做但是并不了解这是在干啥。可能一些萌新体会颇深就照着打老师教怎么写我就怎么写反正做出来了。 本篇博文就来用最接地气的方式对基本的web开发做一个整体的讲解带各个萌新过一遍web开发的流程好让各位萌新知道学习的时候学习了什么知识点这个知识点能够干哈。 最开始我们就以个人浏览网站的方式给大家说一下这一个过程是如何运作的。 我们访问网站一般先打开浏览器不要杠输入一个网址随后浏览器打开一个网页。在你在请求这一个网址数据的时候已经发生了一系列的操作。 1.2了解IP地址 假设你输入的是“csdn.net”浏览器想要去访问你这个网站首先需要的是获得你这个网站的IP地址。可能就有萌新问了**“什么是IP地址”。IP地址就是“指互联网协议地址或者说网际协议地址”。又有萌新说了“你这么说我怎么懂”**好了现在容我慢慢道来。 IP地址就是在网络中定位你这台电脑或者说是设备的一个标记这个标记是人们指定好的标准协议而产生的协议就是你和我说好了一件事拉钩了以后要这样做。就像你家的门牌号例如叫做“CSDN市CSDN区CSDN街道的CSDN小区第CSDN栋的第CSDN号”…这是由有关机构制定的一套规范名称不允许随意更改我们换个例子例如你家是“深圳市南山区深南大道某某小区第八栋808”你写快递的收件地址肯定是写这个难道你写“宇宙第一星球第一市第一栋第一号”地址是由专门组织规范且制定的一套定位规范遵循这个规范可以使遵循该规范的设备或者人之间相互通信这个通信指可以传达交互能够定位、找到。综上所述IP地址就不要纠结为什么要这样写只要知道这个IP地址是你要用的就行。 1.3了解DNS 现在IP地址知道是什么了那么怎么获得IP地址这个时候就需要用到DNS了啥是DNS DNS的英文全称是 Domain Name System翻译过来就是域名系统。好了这个时候问题又来了。 1.4了解域名 啥是域名域名就是用来标识IP地址的一个标记或者说是昵称。“为什么不直接用IP地址”这个问题问得好如果我们人不用名称就用身份证号我叫你的时候就会叫“450333333333333333…”。。。我觉得这样不是很好。。。当人们觉得使用IP地址不方便记忆后就产生了域名地址就像CSDN我们就知道是CSDN就好了难道还要去记她的IP地址吗例如CSDN的地址是192.168.1.1难不难受…以后可能你记网站名称就在记数字了又不方便又崩溃。好了回归正题我们输入了网址后按下Enter键后浏览器将会去DNS请求这个域名对应的IP是什么如果找到了就返回一个IP地址。可能又有萌新问了“浏览器会自动去找DNS”会是会但是我们也会给它一个目标在我们的网络连接里面本地连接右键属性里面有个IPV4双击进去就可以查看自己配置的DNS了一般别乱改不然很难过的有时候浏览器打不开网址就是这个原因。 记住网络IP冲突可能会导致上不了网这种情况在学校的机房里很常见只要改成自动获取IP就ok了会自动分配闲置的IP地址。 1.5 了解数据请求 当找到了IP地址这个时候就会向该IP地址的设备去请求数据请求数据的意思就是这个设备或者说服务器就像一个大型的分发机构就是送情报的一个部门一共有65535个窗口每个窗口送不同的情报例如我们需要请求网站之类的数据就通过第80个窗口请求这个时候浏览器派来的小弟来到这个80号窗口可能会排一下队拿到数据后回到浏览器浏览器把拿到的数据显示给你看。 1.6 了解“ 渲染” 其实在这个时候浏览器显示的数据会根据一些标记进行排版这些标记就称是HTMLHTML是 Hyper Text Markup Language 的缩写中文名是超级文本标记语言其实说那么深奥还不方便理解简单来说就是通过特定的标签把一段文本信息标记起来表示这段文本信息要怎么样去进行显示或者是这个文本信息是啥东西例如 titleCSDN-专业IT技术社区/title是CSDN官网首页的标题用了title这个标签把文本信息标记标记好后浏览器就知道这个文本要显示在哪里要怎么进行显示最终浏览器把这一段信息显示在了浏览器标题头位置 我们再看看另外的一个例子 这一段HTML语言所标记了一个博客的文本整个标记的情况为了清晰的看清楚我在这里列出a href//blog.csdn.net/ classtoolbar_to_feed title博客博客/a标记语言HTML那一些标记并不会进行显示只显示了博客这个这个文本在网页上 那是因为浏览器是通过标记语言的内容去进行显示标记语言的作用就是告诉浏览器这里你要怎么显示这个内容或者说这个内容有什么功能。这里是博客的一个跳转使用的是a标签a标签是什么a标签就是a这里是要显示的文本/a在a标签里面可以添加一些固定的操作例如a标签的作用是跳转到指定的页面那么这个页面肯定是有一个链接的那么这个链接需要什么来指定呢 答案就很简单了使用href来指定这个href呢就需要把要跳转到的页面的地址给加上在我们查看到的HTML代码中是href//blog.csdn.net/这就表示会跳转到blog.csdn.net这个地址有人点击就会跳转到博客了。 那 classtoolbar_to_feed 是什么东西在这里我们可以把它当做给定了一个样式给定了一个style要怎么样显示你要显示的样子是什么可能红色的底绿色的字俗话说红配绿。。。这个样式的名称就叫做 toolbar_to_feed 。在这里并不会深入的讲解这个样式要让博客这个文本显示成啥样大家只要通过例子知道这个html是用来告诉浏览器怎么样显示这个文本或者这个文本有什么用就ok了。其实还有些动态的数据但是在这里并不会讲解基本的理解这样就没问题了。专业点的说法就是构件编排用户界面。 1.7 了解前端 通过以上描述就很清楚的知道如果我们做web开发的话做html相关的就是给页面制作布局怎么样好看甚至可以做特效让页面显示多姿多彩一般我们称做HTML这种是为了数据的显示的排版工作或者说是为了包装数据工作的这类职位叫做前端不过前端是个相对概念在web上可以这样理解是没问题的不过现在的前端如果不去大厂基本上要做的不止是包装数据的排版那么简单可能还会做得更多。如果我们去做前端工作的话还要掌握跟服务器交互的一些操作打个比方用户点击了一个按钮这个按钮的功能是获取到你们的用户人数这个时候你需要编写一个逻辑去服务器获取到这个用户想要的数据。不过这点只是作为一个提醒当真正接触前端的话会了解的。 1.8 了解后端 有很多小问号的朋友可能会记得刚刚说的前端可能要向服务器请求数据那么这个数据是不是就是传说中的后端做的听没听过后端某问题反正就是后端 后端可以理解为一些业务逻辑的代码编写实现就是需要后端什么是业务逻辑简单的举个例子就像你淘宝买东西你点了这个物品下单了我要在代码上怎么实现这个下单这个背后的操作因为下单后你还需要交易交易要收钱收钱你还要把这个记录记载到你存放数据的地方我们可以叫做数据库存进去后用户查看自己的下单记录你还需要把这个记录取出来用代码实现这个取出来这个过程给用户看到不然没有记录那就很尴尬了只收钱不卖货流批所以一般是指的是数据库因为要存储数据例如你网站的用户数据肯定要用东西来存储这个东西就是数据库进行交互以处理相应的业务逻辑。虽然后端要考虑很多东西但是一般来说这样举例子就比较方便理解就不过多的谈论其它东西了。 现在整个逻辑基本上就通了简单的理解后端就是实现一些数据操作业务逻辑的实现其实可能会运维前端呢就是负责用户的页面数据的展示排版嗯大体这样理解问题不大。 1.9 了解建站 既然理解通了我们就来说说一个网站搭建的流程是什么吧 首先我们需要租一个服务器嗯…这个萌新不理解那我们降一个档次那就是我们在我们自己的本地电脑进行试验这样就问题不大了方便快捷。 搭建一个简单企业门户网站其实贼简单不吹不黑几年前的时候做这个还是挺得钱的接接外包舒舒服服现在就不行了毕竟技术在更新过时的技术也变得更加廉价了但是依旧是基本。 以下我使用一个静态网站作为例子演示一个网站的搭建“啥是静态网站”。静态网站就是没有后端好吧简单来说就是这样由于后端需要一些其它语言本篇博文针对于普遍人群为了方便理解就不用后端了直接静态网站作为演示列出html的代码到时候萌新们可以直接复制代码拿去自己试验舒舒服服美滋滋。 1.10 了解集成环境 首先我们下载一个集成环境。“啥是集成环境”。 集成环境打个比方就像你做菜、需要火源、锅、锅铲这种就是环境我做网站也要一个环境这个环境有人给你做好了你直接拿过来用就好就不需要自己搭建有些初学者就喜欢自己搭建然后发现一堆问题搞着搞着发现太难就不学了简直嘤嘤嘤初学者我个人建议先别增加自己的难度先学不然没搞懂就上会一脸懵圈的。现在我们下载一个叫做phpstudy的软件下载点这里 去官网。然后进行傻瓜式安装。 安装完后打开服务 Apache可能会有人问是什么Apache是服务器软件它就是你做菜需要的必要工具之一开启了就对了可能你只开启Apache只能做汤那也没事毕竟我现在演示的是静态网站。 首先我们把我们的资源文件带到网站根目录下 根目录不会找没关系我们打开网站点击管理找到根目录就ok 找到后把资源文件放到根目录下删除以前的根目录下的内容即可。 然后在浏览器输入http://127.0.0.1/ 或者输入 http://localhost/ 就可以访问我们本地电脑上的网站了 二、给所搭建的静态网站添加后端 在以上第一节内容中我们已经做好了一个静态的网站但该网站并没有一些后台功能。例如后台设置网页的所展示的内容那为什么要后台设置网页展示的内容呢当我们的网站成功架设后假设该网站是双十一的推广网站图片这些全部都是标有双十一字样当双十一过后该网站难道就不能继续使用了吗答案当然是不只需要编写一管理后台用户在后台中可自由设置图片要显示哪一张。该功能完成后用户可根据自己的需要更改对应的图片既然图片都可以更改了那么文章也同样可以更改这时网站的自由度将会更高。 更改网站图片的显示与更改文字内容的显示都需要使用数据库当然其它方式也可以但我们在这里使用一种较为常规与成熟的数据库方式进行存储并且使用一个php的开发框架thinkphp来方便我们的搭建。thinkphp的版本是5.1版本。可能有些小伙伴们问为什么要使用框架这不是增加学习成本吗其实使用框架并不会增加你的开发时长并且会增加你的开发效率框架就像搭建房子时的地基直接使用一个地基比你自己再去做一个地基更加简单方便而且更为标准如果你是一个新手自己去搭建一个地基往往会做到一半就“塌”了这种情况也不是不可能。 2.1 了解thinkphp5.1 的使用 首先我们下载thinkphp5.1解压后目录如下 目录参考可以根据thinkpp5.1手册 thinkphp5.1的目录结构在本文并不需要了解过多本文将会说明需要了解的目录。 我们复制解压出来的文件至网站根目录下并且删除原有网站根目录下的内容 由于thinkphp框架的入口在public目录下我们打开public目录进行查看 在public目录下找到了index.php文件。由于该框架的入口文件是index.php需要更改网站的根目录为public。打开phpstudy依次点击其它菜单选项-软件设置-端口常规设置 在弹出来的根目录设置中选择public作为根目录 此时输入localhost进行访问 出现如上示例则表示当前thinkphp部署成功。接下来就可以进行相应的代码编写了。 2.2 完成第一节静态网站的移植部署 在第一节中我们实现了一个静态网站的搭建现在将第一节编写好的静态网站index.html文件复制到如下路径中 我的目录是 E:\devlop\phpstuy\PHPTutorial\WWW\application\index\view\index如果没有该目录可以自己创建。我们浏览器再次输入localhost查看发现依旧出现之前的web页提示这是什么回事呢因为我们需要在thinkphp的控制器中添加一行跳转到该html文件的代码。控制器文件在 E:\devlop\phpstuy\PHPTutorial\WWW\application\index\controller 下 该目录是存放当前模块下所有控制器的地方当然你可以不这样控制器在thinkphp框架中用于对用户访问进行控制例如用户需要访问首页则需要访问首页的控制器默认是index控制器index控制器可以对index这个页面进行逻辑控制可以传值、权限控制等一些列操作。换句话说则是控制用户访问指定资源的逻辑不理解也没关系。我们打开index.php这个控制器 ?php namespace app\index\controller;class Index {public function index(){return style typetext/css*{ padding: 0; margin: 0; } .think_default_text{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: Century Gothic,Microsoft yahei; color: #333;font-size:18px} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }/stylediv stylepadding: 24px 48px; h1:)/h1p ThinkPHP V5.1br/span stylefont-size:30px十年磨一剑 - 为API开发设计的高性能框架/span/p/divscript typetext/javascript srchttp://tajs.qq.com/stats?sId9347272 charsetUTF-8/scriptscript typetext/javascript srchttp://ad.topthink.com/Public/static/client.js/scriptthinkad idad_bd568ce7058a1091/thinkad;}public function hello($name ThinkPHP5){return hello, . $name;} }改php控制器默认index为访问方法index方法将会返回一条html的字符串改字符串通过渲染将会显示成我们之前所看到的部署成功的欢迎界面。在这里需要将该代码删除。换成 return $this-view-fetch();整个php文件则为 ?php namespace app\index\controller; use think\Controller;class Index extends Controller{public function index(){return $this-view-fetch();}public function hello($name ThinkPHP5){return hello, . $name;} }return $this-view-fetch(); 我们可以查看thinkphp5.1手册 使用 fetch 方法将会自动定位到模板文件。thinkphp已经帮我们写好了一定的规则自动定位到默认view目录下对应控制器名下的index文件。在此注意是自动定位到view目录下与控制器同名的目录下的文件不加参数自动定位到index.html也就是view/控制器名/index.html由于控制器名是index,则是view/index/index.htmlview目录下的index目录则是之前复制静态网站html文件的目录。 保存php文件访问localhost 这时发现整个web页错乱这时因为所有css文件、js文件、img文件的路径都有所改变这时需要更改到正确的资源加载目录。为了方便加载在网站根目录public目录下新建一个home目录复制该页面所需的资源文件到该目录下 网站根目录资源的访问路径是“/”表示网站根目录下由于在根目录下创建了一个home目录则进一步可以写为“/home/”在home目录下有一个asset则可以写为“/home/assets/”assets下的文件访问则可以根据目录进行具体访问例如asset下的目录img有一个图片叫做1.png那么访问则可以写成“/home/assets/img/1.png”。 了解了访问的规则后修改index.html文件将所有 assets/ 都更换为 /home/assets/我使用的编辑器是 vscode快捷键 ctrlh 即可调出一键替换 点击如上图中的一键替换即可完成资源内容的目录修改随后保存再次访问 完美呈现是不是贼爽那么接下来就实现这些图片资源的可后台更换。 三、完成后台模块的编写 3.1 完成管理后台模块搭建 首先复制application目录下的index目录 更改index-副本名为admin 随后更改admin目录下controller目录中的index.php文件内容原文件内容如下 ?php namespace app\index\controller; use think\Controller;class Index extends Controller{public function index(){return $this-view-fetch();} }更改为 ?php namespace app\admin\controller; use think\Controller;class Index extends Controller{public function index(){return $this-view-fetch();} }以上的内容主要更改在命名空间从 namespace app\index\controller;更改为了 namespace app\admin\controller;。命名空间主要是为了区分不同区域或空间内的不同“东西”。例如学校中A班的小明与B班的小明这两者有着班别的区别命名空间也是如此表示不同区域不同空间内的值。 更改完成后访问 http://localhost/index.php/admin/index这行url地址表示该网站中admin模块下的index方法其中index.php在访问首页的时候是默认隐藏即http://localhost/index.php等于localhost由于当下访问其他模块在此需要写全当然可以配置隐藏但不是本节内容则不过多增加难度。访问后发现该页面与访问localhost出现的内容一致这是因为admin模块中的index方法也用了return $this-view-fetch();这一行代码输出了html文件的代码这个html文件并不是index模块下的view/index下的index.html而是admin模块下的view/index下的index.html因为刚刚整个模块我们都进行了复制。这时该html不符合我们的需求需要更换html内容在此我使用了一模板该模板编写是前端内容在此并不过多赘述实现逻辑与index.html类型均是修改页面的资源路径即可访问效果如下 注本节项目代码将会打包分享给大家。 3.2 完成数据库的导入 完成后台管理页的搭建后发现该后台所有用户均可访问这对于一个网站是不好的权限行为必须实现可控的权限管理使得网站内容不得随意更改。 首先打开sqlyog输入数据库的帐号密码一般帐号为root密码为root或空 连接成功后邮件你本地数据库点击创建数据 输入数据库名我创建数据库名为minimalism_cms并且选择字符集字符集为utf8即可点击创建 在出现的新建数据库中选择创建表 输入表信息如以下 以上所有所需的数据库表我将会导出sql文件同学们使用时在数据库导入即可导入步骤如下 在对应数据库中右键选择导入点击执行sql脚本即可。 导入完将会出现如下的数据库表 以上数据库表考虑排错等操作并没有过多约束。 3.3 完成权限内容添加功能编写 权限管理首先需要有账户账户属于什么角色该角色又有什么权限这是实现权限管理的思想。例如有个账户名为adminadmin属于超级管理员这个角色该角色拥有所有的权限。接下来首先创建管理员用户。 在权限管理下拉列表中选择管理员管理进入页面 我们查看url连接http://localhost/index.php/admin/auth/adminauth.html 以上链接中admin表示admin这个模块auth表示控制器adminauth表示方法名auth控制器我们还未创建在admin模块下的index控制器同目录创建一个名为Auth.php文件内容如下 ?php /*** |-----------------------* | 页面跳转* |-----------------------*/ namespace app\admin\controller; use think\Controller;class Auth extends Controller{//Auth 管理首页public function adminAuth(){return $this-view-fetch();} }通过以上控制器可以使url连接访问到该控制器并且访问adminAuth所对应的html文件该html对应的文件在view目录下的auth目录中。在thinkphp中对应的view目录根据控制器名分配Auth控制器需要一个名为auth的目录存放该控制器下的html文件在auth目录下创建一个名为admin_auth的html文件为什么要名为admin_auththinkphp会访问方法名默认控制器对应的目录中一同方法名的html文件如方法名有大写则表示在该名称前有一下划线则adminAuth则为admin_auth。该html代码将会打包下载即用。 点击添加添加管理员进入页面 该url为http://localhost/index.php/admin/auth/adminadd.html 在控制器中添加方法 ?php /*** |-----------------------* | 页面跳转* |-----------------------*/ namespace app\admin\controller; use think\Controller;class Auth extends Controller{//Auth 管理首页public function adminAuth(){return $this-view-fetch();}//管理员添加页public function adminAdd(){return $this-view-fetch();} } 该页面拥有管理员账户、管理员密码、名称及角色组内容。暂时我们并没有角色组首先创建一个管理员账户。查看html中的关键代码 form classform-horizontal roleformdiv classform-grouplabel classcol-md-2 control-label管理员账户/labeldiv classcol-md-10input iduser typetext classform-control placeholder帐号/div/divdiv classform-grouplabel classcol-md-2 control-label管理员密码/labeldiv classcol-md-10input idpassword typepassword classform-control placeholder密码/div/divdiv classform-grouplabel classcol-md-2 control-label名称/labeldiv classcol-md-10input idrealname typetext classform-control placeholder输入名称或代号/div/div/form通过以上html得知id为user是账户id为password为密码id为realname为真实姓名。在此使用ajax进行数据提交到php后台实现内容访问。查看ajax代码 scriptfunction add(){var user$(#user).val();var password$(#password).val();var realname$(#realname).val();$.ajax({type:post,url:/index.php?s/admin/Authpost/adminAdd/,data:{user:user,password:md5(password),realname:realname,group:group},dataType:json, success:function(data){if(data.success1){alert(data.msg);}else{alert(data.msg);}},error:function(jqXHR){}}) }/script从以上ajax代码中使用jq获取了id为user、password、realname元素的值在此并没有做检查是否合规希望小伙伴们在使用该代码的时候注意。在获取密码时使用了md5加密md5我是在线引入的引入如下 script srchttps://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.js/script获取值后使用ajax传递给 /index.php?s/admin/Authpost/adminAdd/ 这个url地址。该地址使用了兼容模式因为担心一些同学本地环境有问题所以特地在此使用该模式进行传值。该模式的格式为http://serverName/index.php或者其它应用入口文件?s/模块/控制器/操作/[参数名/参数值…]。则admin为模块名Authpost表示控制器名adminAdd表示控制器中的方法。我们在admin的控制器目录创建一个名为Authpost的控制器并且编写adminAdd方法代码如下 ?php /*** |-----------------------* | 对数据库操作* |-----------------------*/ namespace app\admin\controller; use think\Controller; use think\Db; use think\facade\Request;use app\admin\model\Admin; use app\admin\code\ReturnCodeInfo;class Authpost extends Controller{//administartor add public function adminadd(){$request_data Request::post();$data[password] md5(trim($request_data[password]));$data[username]$request_data[user];$data[realname]$request_data[realname];$data[group]$request_data[group];$data[logintime] time();$data[create_time] time();$data[loginip] Request::ip();$data[status] 1;$res Admin::create($data);if($res){return json((new ReturnCodeInfo())-actionSuccess());}else{return json((new ReturnCodeInfo())-actionError());}}}先不看以上代码我们查看需要存储值的数据库字段有哪些 通过表得知数据库字段包括 username、password、logintime、loginip、realname、create_time。我们接收值需要设定这几个初始字段Authpost 控制器adminadd方法中这部分代码为 $request_data Request::post();$data[password] md5(trim($request_data[password])); $data[username]$request_data[user]; $data[realname]$request_data[realname]; $data[group]$request_data[group];$data[create_time] time(); $data[loginip] Request::ip(); $data[status] 1;以上代码使用了 Request::post();接收post值在使用Request时必须引用use think\facade\Request;随后将值赋给$request_data变量。随后使用 $data 变量存储即将要存储到数据库的值。在存储password密码时使用了md5加密提高安全性。最后使用模型的create方法将数据库的值存储 $res Admin::create($data);模型方法可以方便的使值进行存储。模型对应的是一个数据库例如我数据库名为tp_admin设置前缀为tp_后可以直接创建一个名为Admin的模型其实也就是名为Admin的php文件文件中类名也为Admin该类集成model基类故此有模型特性。创建模型的方法如下在admin下的controller同目录注意是同目录创建一个model文件夹在该文件夹下创建一个Admin的php文件内容如下 ?php namespace app\admin\model; use think\Model;class Admin extends Model {}创建完成后在需要使用到该模型的文件中引入我们在Authpost头部引入 添加代码 use app\admin\model\Admin;其实以上代码是通过模型所在目录进行引入app表示根目录根目录下的admin模块中model目录下的Admin模型。 在引入后还差很关键的一步需要配置数据的连接。 在application目录下config文件夹中找到database.php文件打开修改hostname为127.0.0.1或者是localhost、修改database为我们创建的数据库的名称例如minimalism_cms、修改username帐号为root、修改password密码为root。配置内容如下 ?php // ---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // ---------------------------------------------------------------------- // | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // ---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // ---------------------------------------------------------------------- // | Author: liu21st liu21stgmail.com // ----------------------------------------------------------------------return [// 数据库类型type mysql,// 服务器地址hostname 127.0.0.1,// 数据库名database minimalism_cms,// 用户名username root,// 密码password root,// 端口hostport ,// 连接dsndsn ,// 数据库连接参数params [],// 数据库编码默认采用utf8charset utf8,// 数据库表前缀prefix tp_,// 数据库调试模式debug true,// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)deploy 0,// 数据库读写是否分离 主从式有效rw_separate false,// 读写分离后 主服务器数量master_num 1,// 指定从服务器序号slave_no ,// 自动读取主库数据read_master false,// 是否严格检查字段是否存在fields_strict true,// 数据集返回类型resultset_type array,// 自动写入时间戳字段auto_timestamp false,// 时间字段取出后的默认时间格式datetime_format Y-m-d H:i:s,// 是否需要进行SQL性能分析sql_explain false,// Builder类builder ,// Query类query \\think\\db\\Query,// 是否需要断线重连break_reconnect false,// 断线标识字符串break_match_str [], ];修改完成后保存。 修改完成后查看 adminadd 方法中 if($res){return json((new ReturnCodeInfo())-actionSuccess());}else{return json((new ReturnCodeInfo())-actionError());}以上代码为返回通用的操作返回值码减少代码冗余。使用 json返回json值该值为new ReturnCodeInfo中的actionSuccess方法返回值代码内容为 ?php namespace app\admin\code;class ReturnCodeInfo{//验证器成功代码 10001,错误 10002private $validate_success10001;private $validate_error10002;private $validate_info验证成功;//数据库存private $action_success10003;private $action_error10004;private $action_sinfo操作成功;private $action_einfo操作失败;//验证器 Codepublic function validataSuccess(){return [code$this-validate_success,msg$this-validate_info];}public function validataError($msg){return [code$this-validate_error,msg$msg];}//规则 Codepublic function actionSuccess(){return [code$this-action_success,msg$this-action_sinfo];}public function actionError(){return [code$this-action_error,msg$this-action_einfo];}}以上类定义了操作失败或成功的返回状态方便之后的操作调用该状态码。该php文件我写在controller同目录下的code目录中名为ReturnCodeInfo的php文件。则在Authpost代码中使用了如下代码引入 use app\admin\code\ReturnCodeInfo;接着我们返回到html中在提交按钮上绑定onclick事件当然你使用别的方式也行代码如下 button typebutton onclickadd() classbtn btn-success btn-bordered waves-effect w-md waves-light m-b-5提交/button随后在页面中填入内容 点击提交 操作成功。 我们按照如上方式创建角色组的创建点击角色组管理 角色组实现逻辑与管理员实现逻辑类似不再赘述。点击添加进入添加页 填入组名后点击提交操作成功 该逻辑实现一致均是创建模型后进行数据插入。 随后开始添加规则进入规则添加页 点击提交进行添加。 上述相同过程完成后开始实现权限认证的逻辑。 接下来完全用户对角色组的绑定进入管理员管理页点击编辑 进入编辑页后选择超级管理员 点击提交完成绑定 提交方法使用ajax所访问的接口为Authpost下的groupBindUser方法 //组绑定用户public function groupBindUser(){$request_data Request::post();$data[uid]$request_data[uid];$data[group_id]$request_data[gid];$data[create_time]$data[update_time]time();//存储$res AuthGroupAccess::create($data);if($res){return json((new ReturnCodeInfo())-actionSuccess());}else{return json((new ReturnCodeInfo())-actionError());}}该方法主要使用AuthGroupAccess模型调用create方法进行数据插入。数据库存储如下 为用户id对应的组id。 随后进入组页面进行组绑定规则的操作点击编辑进入超级管理员编辑页 选择需要的规则点击提交完成规则与组的绑定 数据库存储如下 以上表中id为组idrules则为规则的id。 3.4 完成权限管理逻辑编写 为了使验证层能够灵活的使用在admin目录下创建一个AuthRuleValidate目录新建一php文件名为AuthRuleValidateBase内容如下 ?phpnamespace app\admin\AuthRuleValidate; use think\Controller; use think\Db;class AuthRuleValidateBase extends Controller{//传入uid 与当前 路由验证是否有此权限public function check($uid,$access){$resDb::table(tp_admin)-alias(a)-field(rules)-join(tp_auth_group_access agc,a.id .$uid)-join(tp_auth_group ag,ag.id agc.group_id)-find(); $rulesDb::name(auth_rule)-field(rule)-where(id,in,$res[rules])-select();$rulesarray_column($rules, rule);in_array($access,$rules)?:$this-error(权限不足);}}逻辑很简单该方法接受当前的uid用于查询用户所属组改组拥有的规则再通过规则与当前规则进行匹配如含有则表示拥有该权限。 首先查询tp_admin管理员表所在的组 $resDb::table(tp_admin)-alias(a)-field(rules)-join(tp_auth_group_access agc,a.id .$uid)-join(tp_auth_group ag,ag.id agc.group_id)-find(); 得到结果后查询与改组id匹配的规则最后判断该权限是否在当前的规则内是的话不做任何操作否则提示权限不足。 随后在controller控制器目录下创建一基类php文件名为Base。内容为 ?php namespace app\admin\controller;use think\Controller; use think\facade\Session; use app\admin\AuthRuleValidate\AuthRuleValidateBase;class Base extends Controller{protected $beforeActionList [ruleCheck[except login]];protected function ruleCheck(){session(?admin)?:$this-error(未登录或已失效,Index/login);$AuthRuleValidatenew AuthRuleValidateBase();$ssession(admin);/*echo request()-module()./.request()-controller()./.request()-action(); */$AuthRuleValidate-check($s[id],strtolower(request()-controller())./.strtolower(request()-action()));} }该文件引入了刚刚创建的权限判断类在此基础上并且判断了该用户是否登录。 查看代码 protected $beforeActionList [ruleCheck[except login]];该代码为设置前置曹祖其中except表示除什么方法之外在这里设置除login登录方法外因为所有用户都必须登录后才能判断权限登录方法则不受此影响。随后查看ruleCheck方法该方法首先判断用户是否登录 session(?admin)?:$this-error(未登录或已失效,Index/login);随后新建权限判断类 $AuthRuleValidatenew AuthRuleValidateBase();接着使用seesion获取uid $ssession(admin);最后调用权限判断方法传入当前控制器方法与uid进行权限判断 $AuthRuleValidate-check($s[id],strtolower(request()-controller())./.strtolower(request()-action()));完全权限判断基类后使所有管理后台的控制器继承与该方法例Auth控制器该操作可以等待登录页编写后再进行 class Auth extends Base{3.5 完成登录功能编写 在admin模块中index控制器添加方法login内容为 public function login(){return $this-view-fetch();}前端代码使用ajax传值前端页显示如下 随后填入帐号及密码通过ajax传值到admin模块下的Authpost控制器中login方法中内容如下 //登录public function login(){$request_data Request::post();$data[username]$request_data[user];$data[password]md5(trim($request_data[password]));$resdb(admin)-where($data)-find();$res?session(admin, $res):$this-error(帐号或密码错误);}使用find方法对传入值进行对比密码正确则将值传入到seesion否则将提示帐号密码错误。 3.6 完成传入值的判断 在基本权限实现完成后使用验证器对传入值进行判断毕竟外部值都是不可靠的值。 在controller同级下创建一目录validate创建目录后在该目录下创建一php文件名为BaseValidate作为对数据进行判断类的基类代码内容如下 ?php namespace app\admin\validate;use think\Validate; use think\Controller; use app\admin\code\ReturnCodeInfo;class BaseValidate extends Validate{public function gocheck($validata){if(!$this-check($validata)){return (new ReturnCodeInfo())-validataError($this-getError());}return (new ReturnCodeInfo())-validataSuccess();} }该类继承验证器类具有验证器特性。验证器的使用查看tp5.1文档。 查看gocheck方法gocheck方法调用了验证器本身的check方法其接收的参数$validata为需要验证的数据。check判断错误则调用 ReturnCodeInfo类中的报错数据返回否则则返回正确。 假设在管理员添加时需要验证数据是否合规那么在validate目录中创建一名为AdminValidate的php文件内容为 ?php namespace app\admin\validate;use app\admin\validate\BaseValidate;class AdminValidate extends BaseValidate{protected $rule [password require|max:50,username require|max:30,realname require|max:30,group require|max:30];}在管理员添加方法中Authpost控制器中的adminadd方法添加 //验证器$valires(new AdminValidate())-gocheck($data);if ($valires[code]10002){return json($valires);}即可完成但一定要注意需要引入该验证器 use app\admin\validate\AdminValidate;四、完成内容管理功能的编写 4.1 完成管理后台模块搭建 我们首先实现查看轮播图区域元素 发现元素包含轮播图标题、简介以及轮播图标题1、简介1以及背景图。数据库设计如下 我们通过sqlyog的可视化操作添加轮播图所需要资源的数据可以通过邮件检查直接获取资源路径及内容 首先得到轮播图第一张图片的数据 复制内容填入sqlyog表中 同理获取所有的内容填入至表 所有内容填入数据库 回到index模块下的index控制器中在index方法中添加获取轮播图数据表中数据 ?php namespace app\index\controller; use think\Controller; use think\Db;class Index extends Controller{public function index(){$banner_resDb::table(tp_home_banner)-order(id, desc)-limit(4)-select();print_r($banner_res);die;return $this-view-fetch();}}在以上代码中使用select方法查询轮播图数据表中的数据查询方式是id的降序这样使轮播图将会以最新添加的作为显示依据并且每次只查询前4条查询结构复制给变量banner_res使用print_r对该变量进行输出随后在输出模板前使用die终止查看输出。 访问localhost成功获得数据 在index方法中添加代码像前端传递banner_res变量并且删除die代码 ?php namespace app\index\controller; use think\Controller; use think\Db;class Index extends Controller{public function index(){$banner_resDb::table(tp_home_banner)-order(id, desc)-limit(4)-select();$this-view-assign(banner,$banner_res);return $this-view-fetch();}}接下来我们将在html代码中使用tp的前端模板语法对一些html元素进行控制。我们通过元素查询得知轮播图元素id为homev1 在代码中找到id为homev1的元素查看代码每个轮播图标签类似只有默认选项多了个class修饰 但是有些小伙伴觉得很麻烦那我们换一种方式使用tp框架前端的模板语法类似if判断从而输出内容 首先使用volist标签进行循环在标签中设置循环变量key该key循环第一次的值为1当为1使用eq标签判断是1则输出第一个轮播图的html代码 {eq namek value1}需要输出的html代码需要使用成对的eq标签包含结束的eq标签为 {/eq}。 代码如下 div classcarousel-inner rolelistbox!-- Third Slide --{volist namebanner idvo keyk }{eq namek value1}div classitem active!-- Slide Background --img src{$vo.img} altSeoPress Slider /div classbs-slider-overlay/divdiv classcontainerdiv classrowdiv classcol-md-8 col-md-offset-2div classslide-text slide_style_centerh1 classtext-white data-animationanimated zoomInRight{$vo.title}/h1p classtext-white m-top-10 data-animationanimated fadeInLeft{$vo.content}/pa classbtn btn-primary btn-round m-top-30 data-animationanimated fadeInLeft href target_blankRead More/aa classbtn btn-default btn-round m-top-30 data-animationanimated fadeInRight href target_blankRead More/a/div/div/div/div/div{/eq}!-- End of Slide --{eq namek value2}!-- Second Slide --div classitemimg src{$vo.img} altSeoPress Slider /div classbs-slider-overlay/divdiv classcontainerdiv classrow!-- Slide Text Layer --div classcol-md-6div classslide-text slide_style_lefth1 classtext-white data-animationanimated fadeInRight{$vo.title}/h1p classtext-white m-top-10 data-animationanimated zoomInLeft{$vo.content}/pa classbtn btn-default btn-round m-top-30 data-animationanimated fadeInRight href target_blankRead More/aa classbtn btn-primary btn-round m-top-30 data-animationanimated fadeInLeft href target_blankRead More/a/div/div/div/div/div!-- End of Slide --{/eq}{eq namek value3}!-- Third Slide --div classitemimg src{$vo.img} altSeoPress Slider /div classbs-slider-overlay/divdiv classcontainerdiv classrow!-- Slide Text Layer --div classcol-md-6div classslide-text slide_style_lefth1 classtext-white data-animationanimated fadeInDown{$vo.title}/h1p classtext-white m-top-10 data-animationanimated fadeInLeft{$vo.content}/pa classbtn btn-primary btn-round m-top-30 data-animationanimated fadeInLeft href target_blankRead More/aa classbtn btn-default btn-round m-top-30 data-animationanimated fadeInRight href target_blankRead More/a/div/div/div/div/div{/eq}{eq namek value4}!-- Fourth Slide --div classitemimg src{$vo.img} altSeoPress Slider /div classbs-slider-overlay/divdiv classcontainerdiv classrow!-- Slide Text Layer --div classcol-md-6div classslide-text slide_style_lefth1 classtext-white data-animationanimated fadeInLeft{$vo.title} br /Online Marketing Needs/h1p classtext-white m-top-10 data-animationanimated fadeInRight{$vo.content}/pa classbtn btn-primary btn-round m-top-30 data-animationanimated fadeInLeft href target_blankRead More/aa classbtn btn-default btn-round m-top-30 data-animationanimated fadeInRight href target_blankRead More/a/div/div/div/div/div{/eq}{/volist}!-- End of Slide --/div!-- End of Wrapper For Slides --接着我们往下查看首页内容 个人觉得该区域可以放一个“有利于”之类的宣传语那么建一表存放标题、图片、内容信息 在该表中填入网页中原有的数据 在index控制器中添加查询tp_home_advantageous表数据的代码并将结果传至前端 ?php namespace app\index\controller; use think\Controller; use think\Db;class Index extends Controller{public function index(){$banner_resDb::table(tp_home_banner)-order(id, desc)-limit(4)-select();$advantageous_resDb::table(tp_home_advantageous)-order(id, desc)-limit(6)-select();$this-view-assign(advantageous,$advantageous_res);$this-view-assign(banner,$banner_res);return $this-view-fetch();}}修改前端代码发现该区域代码的html几乎一致前3个的class“service-item sm-m-top-65”后3个的class“service-item m-top-65” div classmain-service-area text-center m-top-80div classcol-md-4 col-sm-6div classservice-item sm-m-top-65div classservice-iconimg src/home/assets/images/service1.png alt //divh5 classtext-info m-top-50Search Engine Optimization/h5p classtext-black m-top-20With our 17 years of experience, our SEO services will get your site ranking./p/div/divdiv classcol-md-4 col-sm-6div classservice-item sm-m-top-65div classservice-iconimg src/home/assets/images/service3.png alt //divh5 classtext-info m-top-50Content Marketing/h5p classtext-black m-top-20From blogs and social posts to infographics videos we create and promote quality./p/div/divdiv classcol-md-4 col-sm-6div classservice-item sm-m-top-65div classservice-iconimg src/home/assets/images/service2.png alt //divh5 classtext-info m-top-50Social Media Marketing/h5p classtext-black m-top-20Boost brand awareness and reach your customers on a human level./p/div/divdiv classcol-md-4 col-sm-6div classservice-item m-top-65div classservice-iconimg src/home/assets/images/service4.png alt //divh5 classtext-info m-top-50Web Design Development/h5p classtext-black m-top-20Our designers and developers will create an attractive, SEO-friendly fully functional./p/div/divdiv classcol-md-4 col-sm-6div classservice-item m-top-65div classservice-iconimg src/home/assets/images/service5.png alt //divh5 classtext-info m-top-50eCommerce Solutions/h5p classtext-black m-top-20With our 17 years of experience, our SEO services will get your site ranking./p/div/divdiv classcol-md-4 col-sm-6div classservice-item m-top-65div classservice-iconimg src/home/assets/images/service6.png alt //divh5 classtext-info m-top-50Inbound Marketing/h5p classtext-black m-top-20With our ecommerce solutions, youll provide an enjoyable, seamless./p/div/div/div这是把其它div删除留下1个div使用volist标签进行遍历输出值并且设置循环变量key使用tp框架的前端判断标签判断小于4时输出class为col-sm-6 {lt namek value4}col-sm-6{/eq}当循环后3三位则是k值大于3大于3输出col-sm-6使用gt标签 {gt namek value3}col-sm-6{/eq}将两个前端代码编写与div中完整代码如下 div classmain-service-area text-center m-top-80{volist nameadvantageous idvo keyk }div classcol-md-4 col-sm-6div classservice-item {lt namek value4}col-sm-6{/eq} {gt namek value3}col-sm-6{/eq}div classservice-iconimg src{$vo.img} alt //divh5 classtext-info m-top-50{$vo.title}/h5p classtext-black m-top-20{$vo.content}/p/div/div{/volist} /div运行结果 接着往下查看页面区域 我们将该页面编写成产品展示区域。新建一数据库表 填入内容 在index控制器index方法中添加product数据库查询代码并传至前端 ?php namespace app\index\controller; use think\Controller; use think\Db;class Index extends Controller{public function index(){$banner_resDb::table(tp_home_banner)-order(id, desc)-limit(4)-select();$advantageous_resDb::table(tp_home_advantageous)-order(id, desc)-limit(6)-select();$product_resDb::table(tp_home_product)-order(id, desc)-limit(2)-select();$this-view-assign(product,$product_res);$this-view-assign(advantageous,$advantageous_res);$this-view-assign(banner,$banner_res);return $this-view-fetch();}}随后在html代码中输出内容即可 section idleading classleading bg-primary sections2div classcontainerdiv classrowdiv classmain-leadingdiv classcol-md-6div classleading-contentdiv classhead-titleh2 classtext-white{$product[0][title]}/h2p classm-top-30 text-white{$product[0][specs]}/pdiv classseparator2 hv2span/spanspan/spanspan/span/div/divp classm-top-40{$product[0][content]}/pa href classbtn btn-default btn-round m-top-20Our Team/a/div/divdiv classcol-md-5div classleading-img sm-m-top-50img src{$product[0][img]} alt //div/div/div/div!-- End off row--/div!-- End off container --/section!-- End off leading section--!--Allies Section--section idallies classallies sectionsdiv classcontainerdiv classrowdiv classmain-alliesdiv classcol-md-5div classallies-imgimg src{$product[1][img]} alt //div/divdiv classcol-md-7div classallies-content sm-m-top-50div classhead-titleh2 classtext-blackO{$product[1][title]}/h2h5 classtext-black m-top-30{$product[1][content]}/h5div classseparator2span/spanspan/spanspan/span/div/divp classm-top-40{$product[1][specs]}/pa href classbtn btn-primary btn-round m-top-30Portfolio/a/div/div/div/div!-- End off row --/div!--End off container --/section!-- End off Allies Section--接着往下看 该区域可以更改成文章的展示创建已数据库表 添加内容 查看html代码 div classcol-md-4 col-sm-6div classstudies-itemdiv classstudies-feature borderimg classimg-rounded src/home/assets/images/studies-img-01.jpg alt /div classstudies-overlay img-roundeda hrefspan classicon icon-arrows-2 hvr-hang/span/a/divdiv classcustom-hover/div/divdiv classstudies-conten m-top-30h4a hrefAcme Corporation/a/h4p classm-top-10Objective: Build a larger twitter community/p/div/div/divdiv classcol-md-4 col-sm-6div classstudies-item xs-m-top-35div classstudies-feature borderimg classimg-rounded src/home/assets/images/studies-img-02.jpg alt /div classstudies-overlay img-roundeda hrefspan classicon icon-arrows-2 hvr-hang/span/a/div/divdiv classstudies-conten m-top-30h4a hrefSoylent Corp /a/h4p classm-top-10Objective: Make tone branding consistency/p/div/div/divdiv classcol-md-4 col-sm-6div classstudies-item sm-m-top-35div classstudies-feature borderimg classimg-rounded src/home/assets/images/studies-img-03.jpg alt /div classstudies-overlay img-roundeda hrefspan classicon icon-arrows-2 hvr-hang/span/a/div/divdiv classstudies-conten m-top-30h4a hrefUmbrella Corporation/a/h4p classm-top-10Objective: Eliminate the residue of black-hat methods/p/div/div/divdiv classcol-md-4 col-sm-6div classstudies-item m-top-35div classstudies-feature borderimg classimg-rounded src/home/assets/images/studies-img-04.jpg alt /div classstudies-overlay img-roundeda hrefspan classicon icon-arrows-2 hvr-hang/span/a/div/divdiv classstudies-conten m-top-30h4a hrefInitech/a/h4p classm-top-10Objective: Improve site load speed functionality/p/div/div/divdiv classcol-md-4 col-sm-6div classstudies-item m-top-35div classstudies-feature borderimg classimg-rounded src/home/assets/images/studies-img-05.jpg alt /div classstudies-overlay img-roundeda hrefspan classicon icon-arrows-2 hvr-hang/span/a/div/divdiv classstudies-conten m-top-30h4a hrefVehement Capital Partners /a/h4p classm-top-10Objective: Increase nationwide sales/p/div/div/divdiv classcol-md-4 col-sm-6div classstudies-item m-top-35div classstudies-feature borderimg classimg-rounded src/home/assets/images/studies-img-06.jpg alt /div classstudies-overlay img-roundeda hrefspan classicon icon-arrows-2 hvr-hang/span/a/div/divdiv classstudies-conten m-top-30h4a hrefMassive Dynamic/a/h4p classm-top-10Objective: Increase qualified traffic/p/div/div/div发现该html代码中前3个div的class有所变化后3个div布局内容则无变化。我们使用eq标签使前3个div照原样输出后3个div遍历输出 {volist namearticle idvo keyk } {eq namek value1}div classcol-md-4 col-sm-6div classstudies-itemdiv classstudies-feature borderimg classimg-rounded src{$vo.img} alt /div classstudies-overlay img-roundeda hrefspan classicon icon-arrows-2 hvr-hang/span/a/divdiv classcustom-hover/div/divdiv classstudies-conten m-top-30h4a href{$vo.title}/a/h4p classm-top-10{$vo.content}/p/div/div/div{/eq}{eq namek value2}div classcol-md-4 col-sm-6div classstudies-item xs-m-top-35div classstudies-feature borderimg classimg-rounded src{$vo.img} alt /div classstudies-overlay img-roundeda hrefspan classicon icon-arrows-2 hvr-hang/span/a/div/divdiv classstudies-conten m-top-30h4a href{$vo.title}/a/h4p classm-top-10{$vo.content}/p/div/div/div{/eq}{eq namek value3}div classcol-md-4 col-sm-6div classstudies-item sm-m-top-35div classstudies-feature borderimg classimg-rounded src{$vo.img} alt /div classstudies-overlay img-roundeda hrefspan classicon icon-arrows-2 hvr-hang/span/a/div/divdiv classstudies-conten m-top-30h4a href{$vo.title}/a/h4p classm-top-10{$vo.content}/p/div/div/div{/eq}{gt namek value3}div classcol-md-4 col-sm-6div classstudies-item m-top-35div classstudies-feature borderimg classimg-rounded src{$vo.img} alt /div classstudies-overlay img-roundeda hrefspan classicon icon-arrows-2 hvr-hang/span/a/div/divdiv classstudies-conten m-top-30h4a href{$vo.title}/a/h4p classm-top-10{$vo.content}/p/div/div/div{/gt}{/volist}在index控制器的首页方法index中添加对article表数据的查询 ?php namespace app\index\controller; use think\Controller; use think\Db;class Index extends Controller{public function index(){$banner_resDb::table(tp_home_banner)-order(id, desc)-limit(4)-select();$advantageous_resDb::table(tp_home_advantageous)-order(id, desc)-limit(6)-select();$product_resDb::table(tp_home_product)-order(id, desc)-limit(2)-select();$article_resDb::table(tp_home_article)-order(id, desc)-limit(6)-select();$this-view-assign(article,$article_res);$this-view-assign(product,$product_res);$this-view-assign(advantageous,$advantageous_res);$this-view-assign(banner,$banner_res);return $this-view-fetch();}}其它的前端内容通过数据库更改不再赘述。 4.2 完成通过后台设置更改与添加前端内容 创建控制器Contentmanger添加方法bannerMangerbannerManger方法跳转到一页面用于显示banner数据点击每条数据可进行编辑 由于有数据的查询在控制器中需要查询banner表数据代码为 ?php /*** |-----------------------* | 页面跳转* |-----------------------*/ namespace app\admin\controller; use think\Controller; use think\Db; use think\facade\Request;class Contentmanger extends Base{//官网首页内容管理public function bannerManger(){$listDb::table(tp_home_banner)-order(id)-select();$this-view-assign(list,$list);return $this-view-fetch();} }此处可添加验证器检测传入值是否正确为了节省篇幅接下来的代码中不再过多的添加其它内容。 html代码前端的编辑修改按钮使用了url方法传参传参后获取该id的内容方便进行修改 点击编辑后将会可以随意修改banner的值 点击choosefile可选择img文件修改banner图片。 创建一控制器用来管理内容修改操作的逻辑创建一php文件名为 Contentmangerpost 添加 bannerEdit 方法 ?php /*** |-----------------------* | 页面跳转* |-----------------------*/ namespace app\admin\controller; use think\Controller; use think\Db; use think\facade\Request; use \think\File;use app\admin\model\Goods; use app\admin\validate\IdValidate; use app\admin\code\ReturnCodeInfo;class Contentmangerpost extends Base{//轮播图编辑public function bannerEdit(){$save_path/public;$save_path_/uploads/imgs/;$request_data Request::post();$con[id]$request_data[id];$data[title]$request_data[title];$data[title_2]$request_data[title_2];$data[content]$request_data[content];$data[content_2]$request_data[content_2];// 获取表单上传文件 例如上传了001.jpg$file request()-file(file);if($file){// 移动到框架应用根目录/uploads/ 目录下$info $file-move(...$save_path.$save_path_);if($info){// 成功上传后 获取上传信息$data[img]$save_path_.str_replace(\\,/,$info-getSaveName());}else{// 上传失败获取错误信息echo $file-getError();} }else{$data[img]/home/assets/images/slide-bg-01.jpg;}$resDb::name(home_banner)-where($con)-update($data);if($res){return json((new ReturnCodeInfo())-actionSuccess());}else{return json((new ReturnCodeInfo())-actionError());}} }以上代码使用request()-file(‘file’);判断是否接收到file值如接收到说明用户选择了新图片那么使用move方法保存图片通过getSaveName方法获取保存图片名。最终更新至数据库中。其它数据的更新方法与该步骤类似不再赘述。接下来通过拖拽实现web并且绑定数据。 五、完成页面拖拽生成并绑定数据功能的编写 拖拽页面在此提供一个思想通过bootstrap的layoutit可视化布局可以完成简单页面拖拽生成需要完成更多复杂的界面需要对layoutit进行二次开发。本篇内容为一个demo通过可视化layoutit生成界面且进行代码替换完成对于thinkphp模板的制作最后通过可视化数据绑定生成php代码。 5.1 完成拖拽界面的前端搭建 首先为layoutit添加一个控制器并更改资源路径此操作不再赘述。部署完成后打开界面 可拖拽布局实现界面编辑 拖拽成如下界面 点击下载可查看生成的html代码 在点击下载时我通过js保存了生成的代码 var template; $([data-target#downloadModal]).click(function(e) {e.preventDefault();downloadLayoutSrc();});function downloadLayoutSrc() {var e ;$(#download-layout).children().html($(.demo).html());var t $(#download-layout).children();t.find(.preview, .configuration, .drag, .remove).remove();t.find(.lyrow).addClass(removeClean);t.find(.box-element).addClass(removeClean);t.find(.lyrow .lyrow .lyrow .lyrow .lyrow .removeClean).each(function() {cleanHtml(this)});t.find(.lyrow .lyrow .lyrow .lyrow .removeClean).each(function() {cleanHtml(this)});t.find(.lyrow .lyrow .lyrow .removeClean).each(function() {cleanHtml(this)});t.find(.lyrow .lyrow .removeClean).each(function() {cleanHtml(this)});t.find(.lyrow .removeClean).each(function() {cleanHtml(this)});t.find(.removeClean).each(function() {cleanHtml(this)});t.find(.removeClean).remove();$(#download-layout .column).removeClass(ui-sortable);$(#download-layout .row-fluid).removeClass(clearfix).children().removeClass(column);if ($(#download-layout .container).length 0) {changeStructure(row-fluid, row)}formatSrc $.htmlClean($(#download-layout).html(), {format: true,allowedAttributes: [[id],[class],[data-toggle],[data-target],[data-parent],[role],[data-dismiss],[aria-labelledby],[aria-hidden],[data-slide-to],[data-slide]]});$(#download-layout).html(formatSrc);$(#downloadModal textarea).empty();$(#downloadModal textarea).val(formatSrc)console.log(formatSrc);templateformatSrc;}此代码为layoutit的js代码在此基础上我新建了已js全局变量保存数据变量为template在js代码清洗完成后把清洗后的值赋值给全局变量template。 随后点击保存 button classbtn btn-primary onclickbc()保存/button保存按钮点击后对应的js代码为 function bc(){{literal} template{$head|raw}body stylemin-height: 816px; cursor: auto; classdevpreview sourcepreviewtemplate/body;{/literal} $.ajax({type:post,url:/index.php?s/admin/Autoviewpost/test/,data:{template:template},dataType:json, success:function(data){},error:function(jqXHR){}}) }在因为生成的代码需要一定的js文件引入在此我添加了{$head|raw}为前端的模板代码使用了{literal} 标签对thinkphp的模板代码进行修饰表示不解析其中内容。head变量的内容为 $headlink href/autoview/css/bootstrap-combined.min.css relstylesheetlink href/autoview/css/layoutit.css relstylesheet!-- Le styles --link href/autoview/css/bootstrap-combined.min.css relstylesheetlink href/autoview/css/layoutit.css relstylesheet!-- HTML5 shim, for IE6-8 support of HTML5 elements --!--[if lt IE 9]script src/autoview/js/html5shiv.js/script![endif]--!-- Fav and touch icons --link relshortcut icon href/autoview/img/favicon.pngscript typetext/javascript src/autoview/js/jquery-2.0.0.min.js/script!--[if lt IE 9]script typetext/javascript srchttp://code.jquery.com/jquery-1.9.1.min.js/script![endif]--script typetext/javascript src/autoview/js/bootstrap.min.js/scriptscript typetext/javascript src/autoview/js/jquery-ui.js/scriptscript typetext/javascript src/autoview/js/jquery.ui.touch-punch.min.js/scriptscript typetext/javascript src/autoview/js/jquery.htmlClean.js/scriptscript typetext/javascript src/autoview/ckeditor/ckeditor.js/scriptscript typetext/javascript src/autoview/ckeditor/config.js/scriptscript typetext/javascript src/autoview/js/scripts.js/script;点击保存后生成的html代码文本将会传到Autoviewpost控制器下的test方法中test方法代码如下 public function test(){$request_data Request::post();$template$request_data[template];/* $regex4/div class\media\.*?.*?\/div.*?\/div/ism; */$templatepreg_replace(getMediaReStr(),getMediaHtmlStr(),$template);//media 替换$templatepreg_replace(getCarouselReStr(),getCarouselHtmlStr(),$template);//轮播图 替换$templatepreg_replace(getThumbnailsReStr(),getThumbnailsHtmlStr(),$template);//缩略图 替换$templatepreg_replace(getUnitReStr(),getUnitHtmlStr(),$template);//概述 替换$templatestr_replace({eq namequot;keyquot; valuequot;1quot;}active{/eq},{eq namekey value1}active{/eq},$template);file_put_contents(dirname(dirname(__FILE__)).\view\templates\t1.html,$template);/* print_r($request_data[template]); */}该方法在接收值后对一部分进行替换。使用preg_replace对文本进行替换在该对比中我使用了正则对数据进行匹配该方法我编写在common公共函数的php文件中地址为application\common.php内容为 ?php // ---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // ---------------------------------------------------------------------- // | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. // ---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // ---------------------------------------------------------------------- // | Author: 流年 liu21stgmail.com // ----------------------------------------------------------------------// 应用公共文件 function arrunset($arr){array_splice($arr,0,1); }//Media php code function getMediaHtmlStr(){$str{volist namemedia iddata }.div classmedia.a href{$data.src} classpull-leftimg src{$data.img} classmedia-object alt\\ //a.div classmedia-body.h4 classmedia-heading.{$data.title}./h4 {$data.content}./div./div.{:arrunset($media)}.{/volist};return $str; } //Media regex str function getMediaReStr(){$re/div class\media\.*?.*?\/div.*?\/div/ism; return $re; }//轮播图 php code function getCarouselHtmlStr(){$strdiv classcarousel slide idcarousel-998124div classcarousel-inner .{volist namebanner iddata}.div class\item {eq namekey value1}active{/eq} \.img alt src{$data.img} /.div classcarousel-caption.h4.{$data.title}./h4.p.{$data.content}./p./div./div.{/volist} ./div .a data-slideprev href#carousel-998124 classleft carousel-control‹/aa data-slidenext href#carousel-998124 classright carousel-control›/a/div;return $str; } //轮播图 regex str function getCarouselReStr(){$re/div class\carousel slide\.*?.*?class\right carousel-control\.*?\/div/ism; return $re; }//缩略图 php code function getThumbnailsHtmlStr(){$strul classthumbnails.{volist namearticle iddata}.li classspan4.div classthumbnail img alt300x200 src{$data.faceimg}.div classcaption contenteditabletrue.h3{$data.title}/h3.p{$data.content}/p.pa classbtn btn-primary href#浏览/a a classbtn href#分享/a/p./div./div./li.{/volist}./ul;return $str; } //缩略图 regex str function getThumbnailsReStr(){$re/ul class\thumbnails\.*?.*?\/ul/ism; return $re; }//概述 php code function getUnitHtmlStr(){$str{volist namead iddata offset0 length\1\}.div classhero-unit contenteditabletrue.h1{$data.title}/h1.p{$data.content} /p.pa classbtn btn-primary btn-large href#参看更多 »/a/p./div.{:arrunset($ad)}.{/volist} ;return $str; } //概述 regex str function getUnitReStr(){$re/div class\hero-unit\.*?.*?\/div/ism; return $re; }使用不同的方法返回不同组件、html代码的正则匹配替换成所需的带有thinkphp框架语法的html代码这些代码同样在common文件中。完成替换后由于发现某些字符需要进行替换编写代码 $templatestr_replace({eq namequot;keyquot; valuequot;1quot;}active{/eq},{eq namekey value1}active{/eq},$template);完成清洗替换后生成html模板生成危机 file_put_contents(dirname(dirname(__FILE__)).\view\templates\t1.html,$template);由于是demo所以位置写死了。 随后访问Autoview控制器下的createcontrol方法页面没写 输入你想要生成的控制器名、方法名该方法需要绑定数据表中哪些元素以及绑定的页面路径 输入完成后点击提交数据将会传到Autoview控制器中的buildcontrol方法中方法代码如下 //控制器生成 方法名及数据库public function buildcontrol(){$request_data Request::post();$data[controll] $request_data[controll];$data[function]$request_data[function];$data[datas]$request_data[datas];$data[templatepath]$request_data[templatepath];$controlcode?phpnamespace app\admin\controller;use think\Controller;use think\Db;class .$data[controll]. extends AutoviewBase{public function .$data[function].(){return $this-view-fetch(dirname(dirname(__FILE__))..$data[templatepath].);}};file_put_contents(dirname(dirname(__FILE__)).\controller\\.$data[controll]..php,$controlcode);$res Url_datas::create($data);if($res){return json((new ReturnCodeInfo())-actionSuccess());}else{return json((new ReturnCodeInfo())-actionError());}}该方法controlcode变量为控制器模板变量该模板文本可以得知该控制器名称为自定义名称继承于AutoviewBase基类方法名也是自定义模板位置根据指定路径进行输出渲染。最后使用 file_put_contents 进行控制器生成。最后将数据存入到Url_datas模型中也是Url_datas表中数据表结构数据如下 我们从控制器生成路径中可以得知是admin内的控制器我们访问生成的控制器方法查看效果 数据页面得到显示这些数据都是数据库中的数据。在创建控制器时我们在指定数据表及字段时使用的格式内容为如下 { banner:id,title,img,content, article:id,title,content,faceimg, media:id,src,img,title,content, ad:id,title,content,img }数据指定格式为“数据表”“字段1,字段2…”通过在AutoviewBase的前置方法中对该json数据进行解析AutoviewBase基类如下 ?php /*** |-----------------------* | 前端页面自定义* |-----------------------*/ namespace app\admin\controller; use think\Controller; use think\Db;class AutoviewBase extends Controller{protected $beforeActionList [toview];public function toview(){$headlink href/autoview/css/bootstrap-combined.min.css relstylesheetlink href/autoview/css/layoutit.css relstylesheet!-- Le styles --link href/autoview/css/bootstrap-combined.min.css relstylesheetlink href/autoview/css/layoutit.css relstylesheet!-- HTML5 shim, for IE6-8 support of HTML5 elements --!--[if lt IE 9]script src/autoview/js/html5shiv.js/script![endif]--!-- Fav and touch icons --link relshortcut icon href/autoview/img/favicon.pngscript typetext/javascript src/autoview/js/jquery-2.0.0.min.js/script!--[if lt IE 9]script typetext/javascript srchttp://code.jquery.com/jquery-1.9.1.min.js/script![endif]--script typetext/javascript src/autoview/js/bootstrap.min.js/scriptscript typetext/javascript src/autoview/js/jquery-ui.js/scriptscript typetext/javascript src/autoview/js/jquery.ui.touch-punch.min.js/scriptscript typetext/javascript src/autoview/js/jquery.htmlClean.js/scriptscript typetext/javascript src/autoview/ckeditor/ckeditor.js/scriptscript typetext/javascript src/autoview/ckeditor/config.js/scriptscript typetext/javascript src/autoview/js/scripts.js/script;$con[controll]strtolower(request()-controller());$con[function]strtolower(request()-action());//by controll and action select rules$data_rulesDb::name(url_datas)-where($con)-order(id, desc)-field(datas)-find();//get datas$datas[];$tables json_decode($data_rules[datas], true);foreach($tables as $key $value){$datas[$key]Db::name($key)-column($value);}//输出到前端foreach($datas as $key $value){$this-view-assign($key,$value);}$this-view-assign(head,$head);return $this-view-fetch(dirname(dirname(__FILE__)).\view\templates\t1.html);}}以上代码中定义了前置操作toview方法在toview方法中定义了head为头部资源文件之后使用如下代码获取当前控制器及方法名 $con[controll]strtolower(request()-controller()); $con[function]strtolower(request()-action());把控制器及方法名当作条件至url_datas数据表中查询所需的数据要求及格式 //by controll and action select rules$data_rulesDb::name(url_datas)-where($con)-order(id, desc)-field(datas)-find();得到了所需数据后对该数据进行json解析解析后遍历该数据作为对指定表与数据的查询 $datas[];$tables json_decode($data_rules[datas], true);foreach($tables as $key $value){$datas[$key]Db::name($key)-column($value);}之后使用遍历把得到的数据结果输出到前端 //输出到前端foreach($datas as $key $value){$this-view-assign($key,$value);}最后把head传递值前端代码渲染输出 $this-view-assign(head,$head); return $this-view-fetch(dirname(dirname(__FILE__)).\view\templates\t1.html);以上内容准备过于匆忙只讲解了实现中较为重要的地方很多优化及细节没有说明希望下次将会编写一份完全的教程给大家如有错误欢迎指出想要深入学习可以关注博主,点赞博主、收藏博文谢谢~ 原创作品CSDN 1_bit https://blog.csdn.net/A757291228
http://wiki.neutronadmin.com/news/201304/

相关文章:

  • 兰州企业网站制作百度软件推广联盟
  • 手机视频网站开发化妆品网站建设实施方案
  • 这么做国外网站的国内镜像站长沙网页培训
  • 网站数据库是谁提供百度识图网页版 在线
  • 建站免费加盟网站 租用服务器
  • 做网站的步骤视频游戏在线玩免费免登录
  • 如何用电脑主机做网站广州市官网网站建设多少钱
  • 佛山营销网站建设咨询网业进不去什么原因
  • seo网站优化推广怎么做如何修改wordpress的字体
  • 电子商务网站功能设计与分析网站运营工作是干什么的
  • 你建立的网站使用了那些营销方法鲁中网站
  • 网站怎么优化呢网络营销岗位技能
  • 横岗做网站公司大庆市最新公告
  • 舟山网站建设企业昆山市住房和城乡建设局网站
  • 内蒙古网站建设信息做二手车网站需要什么
  • 无锡网站建设维护邯郸广告公司网站建设
  • 做网站的流程视频线上营销模式有哪些
  • 微信的官方网站怎么做wordpress登录界面插件
  • 昆山门户网站九江集团网站建设公司
  • 专业做ppt的网站做网站送白酒
  • 天津网站建设费用磁力链最佳的搜索引擎
  • 怀化招标网站WordPress文章百度收录插件
  • 网站推送怎么做的网站建设手机站
  • 源码网站下载wordpress标签统一
  • 金华浦江网站建设下述不属于网页制作工具
  • 简单描述一下网站制作的流程网站建设栏目分级
  • 房屋中介做网站的温州网站搭建
  • 建行手机网站网址是多少钱wordpress主题演示站
  • 青海网站建设与制作网站建设实训记录
  • 德州网站推广wordpress国内工作室主题