中级篇项目二内容管理系统.ppt

上传人:小飞机 文档编号:5171954 上传时间:2023-06-10 格式:PPT 页数:110 大小:1.81MB
返回 下载 相关 举报
中级篇项目二内容管理系统.ppt_第1页
第1页 / 共110页
中级篇项目二内容管理系统.ppt_第2页
第2页 / 共110页
中级篇项目二内容管理系统.ppt_第3页
第3页 / 共110页
中级篇项目二内容管理系统.ppt_第4页
第4页 / 共110页
中级篇项目二内容管理系统.ppt_第5页
第5页 / 共110页
点击查看更多>>
资源描述

《中级篇项目二内容管理系统.ppt》由会员分享,可在线阅读,更多相关《中级篇项目二内容管理系统.ppt(110页珍藏版)》请在三一办公上搜索。

1、【中级篇】项目二:内容管理系统,模块五 后台功能实现,MySQL安装与使用HTTP、会话技术,PHP操作数据库文件、图像技术,任务一,任务二,任务三,项目准备,管理员登录,栏目管理,任务四,任务五,文章管理,排序与搜索,任务五,分页导航,目录,在项目开发的初始阶段,先进行项目的目录结构划分,才能合理、规范地管理项目中的各种文件。根据功能模块划分,本项目的目录结构如下所示。,项目初始化,任务一:项目准备,项目初始化,任务一:项目准备,项目初始化,项目首先分成了前台和后台两个平台将common和upload目录作为前后台公共目录后台相关的文件全部放到了admin目录中从而在目录结构上对前后台进行了

2、区分,任务一:项目准备,项目初始化,在完成目录划分后,接下来为项目的前后台创建初始化文件,为项目定义一些基础的常量,方便在项目中使用。,任务一:项目准备,项目初始化,为前台创建初始化文件init.php定义常量APP_DEBUG,用于表示是否开启调试,其值可以为true和false。当开启时将提示完整的错误信息以便于调试,否则只进行简单的错误提示。定义常量COMMON_PATH和UPLOAD_PATH,用于表示公共文件目录和上传文件目录的路径。从前台进行访问时,从当前目录“./”开始。,任务一:项目准备,项目初始化,为后台创建初始化文件admininit.php定义常量APP_DEBUG,用于

3、表示是否开启调试,其值可以为true和false。当开启时将提示完整的错误信息以便于调试,否则只进行简单的错误提示。定义常量COMMON_PATH和UPLOAD_PATH,用于表示公共文件目录和上传文件目录的路径。从后台进行访问时,从上级目录“./”开始。,任务一:项目准备,函数库与配置文件,函数库,在项目开发时,有许多常用的功能可以通过函数来完成,因此应该为项目创建一个函数库,保存项目中的常用函数。常用函数的名称,通过一个大写字母的命名风格,既书写方便,又便于程序阅读。,任务一:项目准备,函数库与配置文件,函数库,在common目录中创建文件function.php,编写一个“E()”函数。

4、,函数名是英文单词“error”的首字母缩写,表示程序遇到错误。该函数有两个参数$msg和$debug,参数$debug的默认值为空字符串该函数的参数$msg表示错误信息,$debug表示调试信息当开启调试时,显示错误信息和调试信息,而关闭调试时,只显示错误信息在完成编写函数库后,接下来在项目的初始化文件中载入函数库,任务一:项目准备,函数库与配置文件,配置文件,在项目中通常有一些常用的配置,如数据库连接信息,使用独立的配置文件来保存配置可以使代码更利于维护。,任务一:项目准备,函数库与配置文件,配置文件,接下来在common目录中创建配置文件config.php,保存数据库的连接信息。,在c

5、onfig.php中,直接返回数组,数组中的元素用于设置项目的配置信息DB_CONNECT元素的值是一个数组,用于保存数据库的连接信息,如数据库服务器地址、用户名、密码、默认数据库和端口号。DB_CHARSET元素用于保存数据库字符集,任务一:项目准备,函数库与配置文件,访问配置文件,完成配置文件commonconfig.php的创建后,接下来还需要对配置文件进行访问。,任务一:项目准备,函数库与配置文件,访问配置文件,在函数库文件commonfunction.php中编写函数C()实现此功能。,函数名是英文字母“config”的首字母缩写,表示访问程序的设置。参数$name表示待访问的数组元

6、素,如DB_CONNECT。在C()函数中设置静态变量$config,用于保存项目配置信息判断$config是否为null,若为null,则载入配置文件判断要获取的配置信息是否存在,若不存在赋值为空字符串返回要获取的配置信息,任务一:项目准备,函数库与配置文件,示例演示,在后台初始化文件admininit.php中,添加以下代码用于测试函数的使用。,/访问数据库连接信息$config=C(DB_CONNECT);echo$confighost;/输出结果:localhost/访问数据库字符集echo C(DB_CHARSET);/输出结果:utf8,任务一:项目准备,数据库函数,在基于数据库的

7、项目中,对数据库的操作是非常频繁的,因此可以利用函数将这部分代码提取出来,以方便后续的代码编写。接下来在common目录中创建db.php,保存数据库的常见操作函数,任务一:项目准备,数据库函数,连接数据库,编写db_connect()函数,用于完成数据库连接和设置字符集操作设置静态变量$link用于保存数据库连接实现函数第一次调用时进行数据库连接实现函数执行后返回数据库连接$link,任务一:项目准备,数据库函数,执行SQL语句,在完成数据库连接后接下来就可以执行SQL语句。由于MySQLi扩展提供的预处理语句更加高效和安全,因此在项目中执行SQL语句时,将通过预处理来实现。,任务一:项目准

8、备,数据库函数,执行SQL语句,编写函数db_query(),完成SQL语句的预处理操作该函数的参数依次为SQL语句、数据格式和数据内容。其中,数据格式的默认值为空字符串、数据内容的默认值为空数组。获取数据库连接后,利用mysqli_prepare()预处理SQL语句,获取$stmt数据内容为空,利用mysqli_stmt_execute()直接执行SQL语句。数据内容不为空,则执行自定义函数db_bind_param()进行参数绑定后,再执行SQL语句最后返回预处理结果$stmt,任务一:项目准备,数据库函数,执行SQL语句,编写函数db_bind_param(),完成SQL语句的参数绑定该

9、函数的参数依次$stmt、数据格式和引用传递的数据内容利用$params保存预处理函数mysqli_stmt_bind_param()需要的每个参数首先依次保存前两个参数$stmt和数据格式由于mysqli_stmt_bind_param()的参数绑定需要引用传参,因此通过遍历数据内容,为每个参数创建引用,并依次赋值给$param最后调用mysqli_stmt_bind_param()函数完成参数的绑定,任务一:项目准备,数据库函数,示例演示,/准备SQL语句$sql=INSERT INTO cms_category(name,sort)VALUES(?,?);/执行SQL语句db_query

10、($sql,si,test,0);,第二个参数si,表示插入数据的类型s表示字符串i表示整型,任务一:项目准备,数据库函数,批量操作,在db_query()函数中,第3个参数用于传入数据内容,目前只支持一维数组。MySQLi扩展的预处理机制还可以实现批量操作。因此,还可以改进db_query()函数,当传入数据内容是二维数组时,自动进行批量操作。,任务一:项目准备,数据库函数,批量操作,在db_query()函数实现参数绑定的位置进行修改首先进行预处理操作的参数绑定并执行预处理操作然后删除执行完的数据最后批量执行剩余的其他数据,任务一:项目准备,数据库函数,示例演示,/准备SQL语句$sql=

11、INSERT INTO cms_category(name,sort)VALUES(?,?);/准备数据$data=aa,1,bb,12,cc,30;/执行SQL语句db_query($sql,si,$data);,任务一:项目准备,数据库函数,其他数据库操作,在数据库操作中,除了执行SQL语句,还需要处理结果集、获取受影响行数、获取最后插入的ID等后续操作。接下来继续完善数据库操作函数。,任务一:项目准备,数据库函数,其他数据库操作,定义常用常量,用于表示后续的具体操作定义函数db_fetch(),处理有结果集的SQL语句;定义函数db_exec(),处理没有结果集的SQL语句。两个函数的参

12、数依次为后续的操作,SQL语句,数据格式和数据内容最后结合switch语句根据不同的操作,执行不同的处理函数,任务一:项目准备,数据库函数,示例演示,/查询数据,获得保存所有结果的关联数组$data=db_fetch(DB_ALL,SELECT*FROM cms_category);var_dump($data);/插入数据,获得最后插入的ID$sql=INSERT INTO cms_category(name,sort)VALUES(?,?);$id=db_exec(DB_LASTID,$sql,si,test,0);echo$id;,任务一:项目准备,输入过滤函数,在项目开发中,对于$_G

13、ET、$_POST数组的访问是非常频繁的,但是这两个数组保存的是来自外部提交的数据,如果直接进行访问,会带来安全隐患。因此,通过函数来统一接收外部变量,可以使项目代码更加严谨和规范。接下来,在commonfunction.php中编写I()函数用于接收外部变量。,任务一:项目准备,输入过滤函数,该函数名取自英文单词“input”的首字母,表示输入。该函数的参数依次为需要处理的变量名、接收方法、数据类型、默认值根据接收方法确定数据变量使用哪种接收类型通过isset()判断接收的数据变量是否存在,若不存在将其值设为默认值结合switch和数据类型进行不同的过滤处理,具体有字符串型、html转义、整

14、数、无符号整数、页码、浮点数、布尔型、数组型。,任务一:项目准备,输入过滤函数,结合htmlspecialchars()函数把一些预定义的 HTML 实体转换为字符,并设置第二个参数ENT_QUOTES完成对单引号和双引号的转义操作。结合trim()函数去除字符串首尾处的空白字符(或者其他字符)结合str_replace()函数将字符串中的空格替换成,其中,在对数据进行HTML特殊字符转义时,为方便管理和操作,接下来在commonfunction.php中实现该函数toHTML()。具体思路如下:,任务一:项目准备,输入过滤函数,示例演示,/POST方式$_POSTname=测试;$name=

15、I(name,post,html);echo$name;/输出结果:测试,/GET方式$_GETid=123abc;$id=I(id,get,id);echo$id;/输出结果:123,任务一:项目准备,后台页面布局,下面开始进入网站后台页面的开发。在设计后台页面时,通常使用“品”字形的页面布局,此布局的具体结构如图。,top是页面的顶部,通常用于显示系统名称、相关链接;nav是页面的左侧导航菜单,后台中的各个功能模块通过这个菜单进入;content是页面内容,根据当前访问的功能而改变。,任务一:项目准备,后台页面布局,在adminview目录中创建后台的布局文件layout.html,页面顶

16、部和左侧导航标签中添加响应,页面内容部分嵌套一个框架,用于动态改变内容创建后台首页adminindex.php,载入后台初始化文件和布局文件接下来在当前目录下,创建admincp_index.php文件,载入后台首页信息创建文件adminviewindex.html,该文件是后台首页的HTML模板文件,任务一:项目准备,后台页面布局,后台页面布局展示图,任务一:项目准备,实现管理员登录,添加管理员信息,在管理员表中添加初始数据,具体字段应包括ID、用户名和密码,SQL语句如下。,INSERT INTO cms_admin VALUES(1,admin,123456);,任务二:管理员登录,实现

17、管理员登录,创建后台登录表单,在后台adminview中创建后台用户登录的HTML表单login.html。,用户名:密码:,任务二:管理员登录,实现管理员登录,载入数据库操作函数,修改前后台的初始化文件admininit.php,载入数据库操作函数db.php。将数据库操作函数载入后,在项目中就可以使用来自db.php中的函数。,任务二:管理员登录,实现管理员登录,接收登录表单,创建后台登录文件adminlogin.php,实现载入HTML模板显示登录页面,当接收到提交的登录表单时处理表单。,任务二:管理员登录,实现管理员登录,接收登录表单,载入后台初始化文件init.php和表单模板文件l

18、ogin.html通过if与$_POST处理提交后的表单内容在处理表单时,先通过I()函数接收用户名和密码,到数据库中查询信息,然后取出密码后进行验证。如果验证通过,则将用户登录信息保存到Session中,然后利用自定义redirect()函数跳转到后台首页index.php如果验证失败,则调用E()函数停止程序继续执行。,任务二:管理员登录,实现管理员登录,接收登录表单,接下来在commonfunction.php中编写用于实现页面跳转的redirect()函数。,function redirect($url)header(Location:$url);/重定向到目标URL地址 exit;,

19、任务二:管理员登录,页面信息提示,当PHP处理用户提交表单时,如果在处理过程中发生了成功或失败的信息,应该以友好的提示信息在页面中显示。为了利于程序的维护,可以将载入HTML页面的代码放到一个函数中,通过调用函数的方式来决定程序在什么情况下显示页面。,任务二:管理员登录,页面信息提示,编写显示页面的函数,接下来在adminlogin.php中编写display()函数,将载入HTML模板的代码放到函数中。,function display($msg=null)require./view/login.html;exit;,任务二:管理员登录,页面信息提示,在页面中输出提示信息,编辑后台登录页面a

20、dminviewlogin.html,在页面中添加元素用于显示信息提示。,任务二:管理员登录,页面信息提示,在页面中输出提示信息,在commonfunction.php中编写该函数tips()输出提示信息。,function tips($msg=null)if(!$msg)return;/没有提示信息时直接返回空字符串 return$msg0?$msg1:$msg1;,tips()函数的参数$msg用于传入一个数组,数组的第1个元素表示成功或失败第2个元素是表示提示信息当省略参数$msg,或$msg为空时,直接返回空字符串,表示没有提示信息,任务二:管理员登录,页面信息提示,显示页面并提示信息

21、,在完成信息提示功能后,修改adminlogin.php中登录失败的提示代码,/修改前的代码:/E(登录失败:用户名或密码错误。);,/修改后的代码:display(false,登录失败:用户名或密码错误。);,任务二:管理员登录,页面信息提示,没有表单提交时显示页面,在完成创建display()函数后,当没有表单提交时,应显示登录页面,if($_POST)/有表单提交时,处理表单else/没有表单提交时,显示登录页面 display();,任务二:管理员登录,页面信息提示,效果展示,任务二:管理员登录,判断登录状态,在实现了用户登录功能后,还需要判断用户是否登录,如果没有登录则提示用户进行登

22、录,并阻止用户访问本来的功能。,任务二:管理员登录,判断登录状态,在后台中,Session操作是项目中的公共功能,为了更好地维护项目中的Session,可以在初始化文件中统一开启Session,并为项目中的Session创建前缀。修改文件admininit.php,具体如下:,开启Session,/启动sessionsession_start();/为项目创建Session,统一保存到cms中if(!isset($_SESSIONcms)$_SESSION=cms=;,任务二:管理员登录,判断登录状态,接下来在admininit.php中继续编写代码,实现检查用户登录。,检查用户登录,判断是否

23、已经定义了NO_CHECK_LOGIN常量如果没有定义则检查用户是否登录,如果已经定义了则不检查用户是否登录当用户登录时,取出用户信息保存到变量$user中如果没有登录则跳转到登录页面login.php并停止脚本继续执行当其他脚本载入这个文件时,就会自动判断用户是否登录,而如果不需要判断登录,则在载入admininit.php之前,先定义NO_CHECK_LOGIN常量。,任务二:管理员登录,判断登录状态,在adminlogin.php文件中,当用户登录成功时,将用户信息(ID和用户名)保存到了Session中。在admininit.php中判断用户是否登录,如果已经登录,则从Session中

24、取出用户信息,保存到$user中。当用户登录成功后进入后台首页时,可通过输出$user将用户名显示在页面中。,显示当前登录的用户名,任务二:管理员登录,判断登录状态,效果展示,任务二:管理员登录,登录验证码,在开发管理员登录功能时,还要考虑一个问题,就是除了浏览器,其他软件也可以向服务器提交数据。从系统安全的角度看,如果使用软件自动大批量向服务器提交表单,那么管理员的用户名、密码将会被穷举出来,导致管理员账号被盗取。为此,验证码就是一种防御的手段。,任务二:管理员登录,登录验证码,通常情况下,验证码是一张带有文字的图片,要求用户输入图中的文字。对于图片中的文字,人类识别非常容易,而软件识别非常

25、困难。因此,验证码是一种区分人类和计算机的程序。接下来,就在项目中实现验证码的功能。,任务二:管理员登录,登录验证码,生成验证码文本,在项目中创建commoncaptcha.php,该文件用于保存验证码相关的函数。,编写captcha_create()函数,用于生成指定位数的验证码该函数有一个参数,用于表示生成文本的位数,默认值为5从$charset字符串中随机取出$count个字符,保存到$code中调用该函数后,返回生成的验证码文本,任务二:管理员登录,登录验证码,生成验证码图像,通过PHP提供的GD库扩展,可以绘制一张图片。在绘制图片时,可以将文本写入到图片中。,任务二:管理员登录,登录

26、验证码,生成验证码图像,在commoncaptcha.php中继续编写代码,实现输出验证码图像的函数。,编写captcha_show()函数,用于验证码图像该函数有一个参数,用于表示验证码文本创建图片资源,随机生成背景颜色,设置字体颜色和样式生成指定长度的验证码添加8个干扰线和250个噪点向浏览器输出PNG格式的验证码图片,任务二:管理员登录,登录验证码,调用验证码函数,在完成了验证码文本和图像生成的函数后,接下来在后台中调用函数显示验证码。,创建文件admincaptcha.php,完成验证码函数的调用载入验证码函数文件commoncaptcha.php生成验证码值输出验证码图像,将验证码保

27、存到Session中,任务二:管理员登录,登录验证码,显示验证码,在完成验证码的调用后,接下来在后台管理员登录的表单中显示验证码。修改登录表单adminviewlogin.html,在表单中使用载入验证码图片。,验证码:,任务二:管理员登录,登录验证码,效果展示,任务二:管理员登录,登录验证码,判断验证码,在用户提交表单后,在判断用户名和密码之前,应该先判断验证码是否正确。如果验证码有误,则没有必要继续判断用户名和密码。,任务二:管理员登录,登录验证码,判断验证码,通过I()函数获取用户输入的验证码载入验证码函数调用自定义函数checkCode()验证用户输入的验证码是否正确若验证错误,则显示

28、验证码验证失败若验证正确,接着继续验证用户名和密码是否正确,任务二:管理员登录,登录验证码,判断验证码,接着自定义函数checkCode()该函数的参数是用户输入的验证码$code接着取出保存到Session中的验证码$captcha 在$captcha 不为空的情况下,为防止重复验证,清除验证码在不区分大小写的情况下,返回$code和$captcha 的比较结果在$captcha 为空的情况下,直接返回false,任务二:管理员登录,退出登录,在完成管理员登录功能后,还需要开发管理员退出功能。编辑adminviewlayout.html文件,在显示用户信息的位置,添加一个退出登录的链接。,您

29、好,前台首页退出,任务二:管理员登录,退出登录,接下来在adminlogin.php中接收参数,实现退出功能。,/接收操作参数$action=I(a,get,string);/执行操作if($action=logout)/退出登录 unset($_SESSIONcmsadmin);/清除Session display(true,您已经成功退出。);,任务二:管理员登录,读取栏目,准备测试数据,在管理员登录后,就可以对栏目进行管理。在项目数据库中,为栏目表添加测试数据,用于读取栏目功能的开发。添加测试数据的SQL语句如下。,INSERT INTO cms_category(id,pid,name

30、,sort)VALUES(1,0,PHP,0),(2,0,Java,1),(3,1,PHP基础,0),(4,1,PHP高级,1);,任务三:栏目管理,读取栏目,读取栏目数据,在项目中,读取栏目数据的需求可能会频繁出现,因此将此功能写在函数中。在common目录下创建文件module.php,用于保存和数据相关的功能模块函数。,任务三:栏目管理,读取栏目,读取栏目数据,定义函数module_category(),用于获取栏目列表该函数的参数$mode表示索引方式:id 或 pid,默认返回两种格式定义一个静态变量$result,用于缓存查询结果当第一次调用函数时,到数据库中获取数据,并分别根据i

31、d和pid创建数组索引,方便查找。最后根据索引方式返回查询结果,任务三:栏目管理,编辑栏目,输出已有栏目,在项目中创建cp_category.php文件,该文件用于读取栏目数据显示在HTML模板中。,在该文件中载入初始化文件接着定义display()函数,显示页面从数据库中根据pid取出数据,载入HTML模板文adminviewcateogory.html调用函数display(),任务三:栏目管理,编辑栏目,输出已有栏目,接下来编写用于显示栏目的adminviewcateogory.html文件。为了提高后台管理的操作效率,可以将栏目显示、添加、修改功能都在一个页面中完成。,pid的顶级分类

32、为0外层循环输出顶级栏目接着判断该分类下是否存在子栏目,若存在则循环输出,任务三:栏目管理,编辑栏目,效果展示,任务三:栏目管理,编辑栏目,添加栏目,在完成已有栏目的输出后,还需要开发栏目添加功能,在实现栏目添加时,为了更直观地在页面中添加栏目和子栏目,这里通过jQuery实现了页面的灵活处理。编辑adminviewcp_category.html文件,在页面底部添加JavaScript代码如下。,任务三:栏目管理,编辑栏目,添加栏目,当单击页面中的class属性为jq-add的元素时,就会触发点击事件在该元素的前面添加HTML内容,内容是添加新栏目的输入框对于添加表单的name属性,这里使用

33、了名称为add的二维数组,其外层用于区分多个添加的内容,内层是sort、name、pid三个字段由于是顶级栏目,所以pid的值为0,顶级分类栏目添加,任务三:栏目管理,编辑栏目,添加栏目,当单击页面中的class属性为jq-sub-add的元素时,就会触发点击事件为“添加子栏目”元素添加data-id属性,用于保存子栏目的上级栏目ID。添加子栏目的事件函数中应该先获取到此ID,然后保存到隐藏域的pid字段中。,二级分类栏目添加,任务三:栏目管理,编辑栏目,效果展示,任务三:栏目管理,批量保存,接收表单 调用addData()函数添加栏目,调用saveData()函数修改栏目 实现接收表单并处理

34、批量添加 添加栏目的信息保存在了add二维数组中 利用I()函数接收数组后保存到数据库中即可批量修改 批量修改的实现方式和批量添加类似 在接收表单时,修改栏目的信息保存在了save数组中,任务三:栏目管理,修改层级,添加编辑链接 为每个栏目添加“编辑”超链接,链接到cp_category_edit.php文件 同时,传递参数ID,表示编辑指定ID的栏目取出指定栏目信息先取出待编辑栏目的信息,然后取出所有顶级栏目信息保存信息 在admincp_category_edit.php中接收表单数据,将信息保存到数据库中,任务三:栏目管理,删除栏目,添加删除链接在开发删除功能时,为了防止误操作,在执行操

35、作前进行弹框提示执行操作判断待删除栏目下是否有子级栏目,若有则不执行删除操作;若没有则删除,任务三:栏目管理,删除栏目,效果展示,任务三:栏目管理,删除栏目,令牌保护,在前面实现删除功能时,通过一个URL地址直接实现了删除数据,然而这种方式在Web开发中存在安全隐患。当管理员在登录系统的状态下进行其他操作时,如果访问了其他用户恶意构造的危险URL地址,就会导致后台的操作被执行,这种安全漏洞称为CSRF(跨域请求伪造)。,任务三:栏目管理,删除栏目,令牌保护,防御CSRF安全问题的一个有效的措施,是为所有涉及更改数据的操作加上令牌保护,该令牌将在用户登录时随机生成,每个更改的操作都附加上令牌,没

36、有令牌时将无法执行操作。,任务三:栏目管理,删除栏目,令牌保护,token_get():利用md5()和microtime(true)生成令牌,将其保存在Session中token_check():先从GET参数中取出token,然后再与保存到Session中的token进行比较,判断是否正确。如果令牌有误,说明用户当前的操作是非法的。,在commonfunction.php中,自定义token_get()和token_check()函数,任务三:栏目管理,删除栏目,令牌保护,在admininit.php中添加代码实现令牌的自动生成和验证对删除栏目的操作添加令牌验证,需要注意的是,为了避免项目

37、中频繁的令牌验证影响代码演示,在本书后面的开发步骤中并没有加上令牌验证功能。同时为了确保项目的严谨性,在本书的配套源代码中已经全部加上了令牌验证。,任务三:栏目管理,文章列表,准备测试数据 在开发具体功能前,先向数据库中插入测试数据查询文章列表 通过文章表和栏目表的左连接查询,从数据库中获取到文章列表,在列表中包含了文章所属栏目的信息展示文章列表 编写代码输出文章列表,任务四:文章管理,文章列表,效果展示,任务四:文章管理,编辑文章,添加编辑链接当单击“编辑”链接时,访问cp_article_edit.php并传入参数id查询指定文章信息 接收文章id,显示修改页面 如果没有收到,或id的值为

38、0时,直接显示空表单,用于发布新文章显示文章编辑表单 创建一个表单显示文章编辑内容输出栏目列表 下面将栏目输出到一个下拉菜单中,任务四:文章管理,编辑文章,引入在线编辑器 在CKEditor的官方网站可以下载此编辑器 将编辑器放入到项目的adminjs目录中,并将编辑器目录命名为“ckeditor”在文章编辑页面adminviewarticle_edit.html的底部编写JavaScript代码,实现在线编辑器的引入。修改容器的name属性值,任务四:文章管理,编辑文章,效果展示,任务四:文章管理,保存文章,接收表单 接收用户填写的基本信息 接收由在线编辑器提交的内容时,没有进行HTML转义

39、,这是因为编辑器提交内容的本来就是HTML。,从安全角度来说,服务器端不进行HTML转义会带来安全问题,原因是浏览器端任何限制都可以被绕过。在项目开发时,可以考虑使用富文本过滤器(如HTML Purifier)对HTML内容进行安全过滤,这部分内容将在后面的项目中进行讲解。,任务四:文章管理,保存文章,实现文章修改 在执行接收表单后的操作时,如果接收到文章ID,就执行文章修改操作。实现文章添加 在处理表单时,如果没有接收到文章ID,就执行文章添加操作。,任务四:文章管理,上传封面图,检查上传文件 在进行添加或修改数据之前,先处理上传文件 在commonfunction.php中,自定义chec

40、k_upload()函数,用于判断上传文件是否成功,成功时返回true,失败时将错误信息保存到$error中准备缩略图函数 为图片生成缩略图image_thumb 根据原图文件创建图像资源image_create 保存图像资源image_save,任务四:文章管理,上传封面图,获取图片信息 实现image_thumb()函数的功能,完成缩略图的生成实现图片等比例缩放 通常会保持图片比例,防止图片被拉伸或者压扁,影响图片的美观生成保存路径 可以根据日期为图片生成子目录,并为文件自动生成文件名,防止文件名冲突调用缩略图函数在调用时,需要指定原图路径、缩略图宽高、上传目录等信息,任务四:文章管理,上

41、传封面图,效果展示,任务四:文章管理,删除文章,添加删除链接 该功能和栏目删除时的代码相同执行删除操作 当用户单击删除链接后,就会向PHP脚本发送待删除的文章ID参数 在实际进行文章记录删除操作之前,需要先判断文章是否有封面图。如果封面图存在,就先删除图片文件,再删除文章记录,任务四:文章管理,列表功能区,准备排序条件 在admincp_article.php文章列表程序中编写代码,获取列表相关的GET参数,并定义排序的方式以及对应的SQL语句显示列表功能区 栏目筛选和列表排序功能是两个下拉菜单 列表搜索功能是一个文本框 三个功能各放在三个表单中,单击表单提交按钮即可完成对应的功能操作。,任务

42、五:排序与搜索,列表功能区,效果展示,任务五:排序与搜索,组合SQL语句,组合ORDER和WHERE子句,在前面的步骤中,已经使用$cid、$search、$order三个变量接收了来自表单提交的数据。接下来就可以根据这些数据组合SQL语句进行查询。在文章列表功能admincp_article.php中继续编写代码,在接收变量后组合SQL语句。,/拼接排序条件$sql_order=ORDER BY$sql_order.=isset($order_arr$order)?$order_arr$ordersql:a.id DESC;/拼接WHERE条件$sql_where=WHERE 1=1;$sq

43、l_where.=$cid?AND a.cid IN(.module_category_sub($cid).):;$sql_where.=AND a.title LIKE?;$sql_search=%.db_escape_like($search).%;,任务五:排序与搜索,组合SQL语句,根据栏目ID取出所有子栏目ID,下面在commonmodule.php文件中编写module_category_sub()函数,实现根据栏目ID取出所有子栏目ID的功能。,function module_category_sub($id)$data=module_category(pid);$sub=iss

44、et($data$id)?array_keys($data$id):;array_unshift($sub,$id);/将$id放入数组开头 return implode(,$sub);,任务五:排序与搜索,组合SQL语句,转义LIKE搜索字符串,接下来在commondb.php文件中编写db_escape_like()函数,用于实现转义LIKE搜索字符串中的所有特殊字符。,function db_escape_like($like)return strtr($like,%=%,_=_,=);,在单引号字符串中书写“”字符时,如果一个“”后面跟一个单引号,单引号将会被转义成字符串中的字符,而非

45、字符串定界符,因此需要在“”前面加一个“”进行转义(字符串中实际只保存了一个“”字符)。,任务五:排序与搜索,组合SQL语句,修改文章列表查询SQL,在完成对ORDER和WHERE的组合后,接下来继续编写admincp_article.php,修改查询文章列表数据的代码,将筛选和排序条件加入到SQL语句中。,$data=db_fetch(DB_ALL,SELECT a.id,a.cid,a.title,a.author,a.show,a.time,c.name AS cname FROM cms_article AS aLEFT JOIN cms_category AS c ON a.cid=

46、c.id.$sql_where$sql_order,s,$sql_search);,任务五:排序与搜索,组合SQL语句,效果展示,任务五:排序与搜索,分页显示信息,分页查询原理,实现分页的原理是对SQL语句中的LIMIT进行控制,示例代码如下。,SELECT title FROM cms_article LIMIT 0,10;#获取第1页的10条数据SELECT title FROM cms_article LIMIT 10,10;#获取第2页的10条数据SELECT title FROM cms_article LIMIT 20,10;#获取第3页的10条数据SELECT title FRO

47、M cms_article LIMIT 30,10;#获取第4页的10条数据,任务六:分页导航,分页显示信息,分页查询原理,LIMIT的第2个参数“10”表示每次读取的最大条数;第1个参数与页码之间存在一定的数学关系,具体如下:,LIMIT 第1个参数=(页码-1)*每页查询的条数,任务六:分页导航,分页显示信息,分页查询原理,根据上述条件,接下来在common目录中创建page.php,用于实现分页功能。下面在文件中编写用于生成LIMIT参数的函数。,?php/获取SQL分页 Limit($page表示页码,$size表示每页查询条数)function page_sql($page,$siz

48、e)return($page-1)*$size.,.$size;,任务六:分页导航,分页显示信息,实现分页查询数据,接下来在文章列表功能admincp_article.php文件中实现分页查询,在display()函数中查询文章列表数据之前,编写代码定义每页显示的记录数和页码,并调用page_sql函数生成LIMIT参数。,任务六:分页导航,分页显示信息,实现分页查询数据,$page=I(page,get,page);/获取页码(限制最小值为1)$page_size=3;/每页显示3条记录require COMMON_PATH.page.php;/载入分页函数$sql_limit=LIMIT.

49、page_sql($page,$page_size);/拼接LIMIT/获取文章列表时,将LIMIT放入SQL语句中$data=db_fetch(DB_ALL,SELECT a.id,a.cid,a.title,a.author,a.show,a.time,c.name AS cname FROM cms_article AS aLEFT JOIN cms_category AS c ON a.cid=c.id.$sql_where$sql_order$sql_limit,s,$sql_search);,任务六:分页导航,生成分页导航,获取总页数,查询出符合$sql_where条件的总记录数,通过总记录数和每页显示的记录数,即可计算出总页数,计算公式为“总记录数每页数量”,然后向上取整。,例如,总记录数为7,每页显示3条,则7除以3的结果大于2且小于3,超出第2页的记录在第3页显示,因此总页数为3。,任务六:分页导航,生成分页导航,生成分页导航,生成分页导航的原理是,根据当前页码和总记录数,计算出“上一页”、“下一页”、“尾页”的页码值。其中,为了在输出分页链接时携带GET参数,获取原来所有的GET参数,清除原来的page参数,重新构造参数字符串并返回。在commonpage.php中编写程序,实现分页导航的自动生成。,任务六:分页导航,生成分页导航,效果展示,任务六:分页导航,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号