当前位置:   article > 正文

PHP Web应用开发 -用PHP实现简单的个人博客网站_php开发简单网站

php开发简单网站

题目

题目:用PHP实现一个贴吧的网站

一、项目简介

能够实现用户注册登录发帖会贴的功能。

二、需求分析

(1)统一友好的操作界面。具有良好的用户体验。
(2)只有管理员账户才有权限删除一切用户发的贴子。
(3)个体用户没有权限删除其他用户的帖子只能删除或改编自己的贴子
(4)发贴必须选择发贴类型,这样系统好完成分分类。
(5)回复帖子的内容所有用户可见。

三.总体设计

(1)系统框架
在这里插入图片描述
(2)数据库设计

在这里插入图片描述
在这里插入图片描述
(3)主要的代码类(或文件)介绍
在这里插入图片描述
Common文件夹用于保存公共的PHP文件、common/library文件夹用于保存公共的类文件、css文件夹用于保存项目的css文件、js文件夹用于保存项目的JavaScript文件、images文件夹用于保存项目的图片的文件、view文件夹用于保存项目的部分HTML文件、uploads/avatar文件夹用于保存用户上传的头像、uploads/category文件夹用于保存管理员上传的栏目图片、uploads/picture文件夹用于保存用户上传的图片内容、uploads/temp文件夹用户保存用户上传的临时文件。
Index.php文件网站首页,显示内容列表、login.php用户登录、退出、register.php注册新用户、user.php用户中心,可以上传图像、category.php贴吧栏目编辑,只有管理员可以进行操作、post.php发布内容,只有已登录用户可以操作、show.php查看内容,已登录用户可以发表内容、guanyu.html文件是关于作者的页面用于联系作者。

四. 详细设计

(1)创建域名
假设本项目的域名为“www.ggba.com“,编辑Apache2.4主机配置文件,具体如下:
在这里插入图片描述
为了使域名在本机内生效,更改系统hosts文件:
在这里插入图片描述
(2)准备公共函数和配置文件
在本项目的common/function.php文件中有相关函数,接下来,在common目录中创建项目的配置文件config.php,代码如下:
在这里插入图片描述
在上述配置中,“DB_PREFIX”用于在程序中自动为数据表加上前缀进行访问。
(3)引入公共类
创建项目的初始文件common/init.php,实现相关文件的引入和环境配置,代码如下:
在这里插入图片描述
完成上述代码,在具体功能脚本中引入common/init.php文件,即可实现项目的初始化。
(4)配置网页标题和顶部导航
在项目的HTML模板中,每个页面都需要显示网页标题和顶部导航,当需要修改这些内容时,直接编辑模板文件会非常繁琐,因此将这些数据保存到配置文件中,然后在模板中直接读取配置即可,使代码更简洁。编辑common/config.php文件中
在这里插入图片描述
在view目录下创建common目录,然后编写top.html用于保存顶部导航,代码如下
在这里插入图片描述
上述代码第2行使用了变量 t y p e 。该变量表示当前位于顶部导航的某个链接指向的页面中,值可以是 h o t 、 n e w 、 p i c 、 t e x t 或 v i d e o 。当 A P P N A V 数组的键名与 type。该变量表示当前位于顶部导航的某个链接指向的页面中,值可以是hot、new、pic、text或video。当APP_NAV数组的键名与 type。该变量表示当前位于顶部导航的某个链接指向的页面中,值可以是hotnewpictextvideo。当APPNAV数组的键名与type相同时,为链接添加class为curr的样式。$type的值是通过URL参数type获取的,因此,在载入HTML模板前,应先接收该参数。
(5)数据库操作类

  • 创建类文件
    Db类代码如下:
    在这里插入图片描述
    第7、13行调用了自定义函数config(),以及在第11行通过exit()函数停止脚本,都会影响Db类的通用性。通过getlnstance()方法的参数传入数据库连接配置,若连接失败,则先记录错误信息,然后getError()方法专门用于错误信息的获取。
    (6)文件上传类
  • 创建类文件
    编写一个文件上传类,将代码保存到common/library/Upload.php文件中。Upload类的代码如下:
    在这里插入图片描述
    第2个和第3个参数指定了文件成功上传后保存的路径为“./Uploads/当前年份/文件名.jpg”。
  • 解析文件上传数组
    在Upload类中,私有方法parse()用于解析给定“ F I L E S [ ‘ X X ’ ] ”数组,自动识别单文件上传和多文件上传两种情况,同时进行错误检查、控制文件数量在 _FILES[‘XX’]”数组,自动识别单文件上传和多文件上传两种情况,同时进行错误检查、控制文件数量在 FILES[XX]数组,自动识别单文件上传和多文件上传两种情况,同时进行错误检查、控制文件数量在limit的限制内。为了在遇到错误时给予提示信息,代码如下:
    在这里插入图片描述
    接下来,编写parse()方法,代码如下:
    在这里插入图片描述
    从上述代码可以看出,parse()方法会将$file数组整理成一维数组的形式返回。如果文件存在错误,则记录错误信息并跳出。在记录错误信息后,通过geterror()方法可以获取错误信息。
  • 实现单文件和多文件上传
    编写用于多文件上传的upload()方法和用于单文件上传的uploadone()方法,代码如下:
    在这里插入图片描述
    Upload()方法和uploadone()方法的区别在于返回值的形式不同,前者返回的是数组,后者返回的是字符串。值得一提得是,将upload()类得参数$limit设为1时也可以实现单文件上传,但uploadone()方法在获取结果时会更加方便。
  • 保存上传文件
    编写save()方法,代码如下:
    在这里插入图片描述
    (7)用户登录与退出
  • 实现用户登录
    显示登录页面代码如下:
    在这里插入图片描述
    其中创建了一个用户登录表单。
    接收表单代码如下:
    在这里插入图片描述
    f i e l d 表示待验证的字段; field表示待验证的字段; field表示待验证的字段;data表示待验证的内容;$msg用于保存格式信息,当验证失败时可以用于输出,一提醒用户更正格式问题。第6行正则表达式中的“\x{4E00}-{9FA5}”用于匹配汉字.
    为判断当前是否有表单提交,在common/init.php中定义常量IS_POST,代码如下:

根据 P O S T 和 _POST和 POST_FILES数组是否为空,来判断当前是否有表单提交。
载入HTML模板之前,先接收表单进行处理,代码如下:
在这里插入图片描述
当程序中的每一步验证失败时,都会停止脚本并输出提示信息。
友好提示登录失败信息
代码如下:
在这里插入图片描述
参数 t i p s 表示提示信息;参数 tips表示提示信息;参数 tips表示提示信息;参数name表示在登录表单中,用户名输入框默认显示的值,用于在登录失败时保留上次输入的内容。
修改view/login.html为填写用户的文本框添加默认值,代码如下:
在这里插入图片描述
在这里插入图片描述
判断用户名以及密码是否正确
代码如下:
在这里插入图片描述
编写login_form()函数,代码如下:
在这里插入图片描述
第7行代码在根据给定的用户名取出数据库中保存的密码后,调用了password()函数对输入的密码进行加密,然后比较加密结果与数据库中保存的结构是否一致。
代码如下:
在这里插入图片描述
当密码验证通过后,就会调用login_success()函数保存当前的登录状态,代码如下:
在这里插入图片描述
第4行代码用于将当前登录的用户id、用户名和用户组保存到Session中;第6行代码调用了redirect()函数用于实现页面跳转。代码如下:
在这里插入图片描述
当页面跳转后,就会通过第4行代码停止脚本继续执行。

  • 获取登录信息
    当login_success()函数将用户的登录状态保存到了Session中以后,就可以在每个功能脚本中判断用户是否已经登录。代码如下:
    在这里插入图片描述
    第4行代码用于在用户登录后,将Session中的用户信息保存到user()函数中。
    User()函数代码如下:
    在这里插入图片描述
    当user()函数的第2个参数不为空时,表示第2行参数保存到user()函数中的静态变量$data中;若省略第2个参数,则表示根据第1行参数获取用户信息;为了确登录用户是否为网站管理员,代码如下:
    在这里插入图片描述
    通过IS_ADMIN常量可以方便地进行管理员身份验证。
    在未登录状态下显示“登录”和“注册”链接;在已登录状态下显示当前登录的用户名,并提供“退出”链接,代码如下:
    在这里插入图片描述

  • 用户退出
    通过login.php传递URL参数action=logout来实现。修改用户登录后显示的“退出”链接,代码如下:
    在这里插入图片描述
    接收action参数,如果值为logout,表示用户需要退出,清除Session中保存的用户信息即可,代码如下:
    在这里插入图片描述
    (8)用户注册
    创建register.php代码如下:

在这里插入图片描述
Display()函数用于显示页面并退出,参数 n a m e 和 name和 nameemail分别表示注册表单中默认显示的用户名和电子邮箱。
创建一个用户注册表单,代码如下:
在这里插入图片描述
在register.php中的display()函数调用之前添加代码如下:
在这里插入图片描述
第14-16行代码用于验证邮箱格式,在input_check()函数switch语句中增加邮箱格式验证的代码。验证成功后,调用register()函数实现新用户的注册,register()函数的代码如下:
在这里插入图片描述
第4-7行代码用于判断用户名是否已经存在,由于用户名是登录的凭证,因此不允许出现相同的用户名;第8行用于生成用于加密密码的密钥;第9-14行将新用户的相关数据保存到数据库中。当用户注册成功以后,通过第15行代码调用register_success()函数,将用信息保存到Session中,然后跳转,代码如下:
在这里插入图片描述
(9)记住登录状态
View\login.html中增加一个“记住登录状态”的复选框,代码如下:
在这里插入图片描述
当用户选中复选框后,处理登录表单时,如果登录成功,将用户名和密码保存到Cookie中,用于在Session过期后进行登录验证证。需要注意的是,由于Cookie安全性差,网站不应将用户的密码明文存储在cookie中。下面在common/config.php中添加如下配置,用于提搞安全性:
在这里插入图片描述
在login.php中处理登录表单时,当密码验证成功后,在调用login_success()函数之前,判断用户是否选中了表单中的“记住登录状态”复选框,如果选中了,将用户名和加密后的密码保存到Cookie中,代码如下:
在这里插入图片描述
第4行的autologin_cookie()函数用于将数据库中已经保存的密码再次进行加密,用于限制Cookie密码的有效时间。在common/function.php中编写 代码如下:
在这里插入图片描述
当前时间戳与加密后的Cookie密码通过“|”分隔拼接成一个字符串,在调用password()函数时,将数据库保存的密码 d a t a 、当前时间戳 data、当前时间戳 data、当前时间戳time和配置文件中的Cookie密钥一起进行运算。其中,“|”前面的 t i m e 用于验证 C o o k i e 密码时判断当前是否在有效期内,而 p a s s w o r d ()函数参数中的 time用于验证Cookie密码时判断当前是否在有效期内,而password()函数参数中的 time用于验证Cookie密码时判断当前是否在有效期内,而password()函数参数中的time用于确保“|”前面的 t i m e 无法被伪造。为了验证 C o o k i e 密码的有效性,接下来编写 a u t o l o g i n c h e c k ( ) 函数,代码如下: ! [ 在这里插入图片描述 ] ( h t t p s : / / i m g − b l o g . c s d n i m g . c n / 20201211152145801. p n g ) 函数的参数 time无法被伪造。 为了验证Cookie密码的有效性,接下来编写autologin_check()函数,代码如下: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201211152145801.png) 函数的参数 time无法被伪造。为了验证Cookie密码的有效性,接下来编写autologincheck()函数,代码如下:![在这里插入图片描述](https://imgblog.csdnimg.cn/20201211152145801.png)函数的参数cookie表示来自Cookie中保存的密码, d a t a 是数据库中保存的密码。首先通过第 3 行代码根据“ ∣ ”分割字符串,然后在第 4 行代码判断 data是数据库中保存的密码。首先通过第3行代码根据“|”分割字符串,然后在第4行代码判断 data是数据库中保存的密码。首先通过第3行代码根据“∣”分割字符串,然后在第4行代码判断arr数组是否有2个元素。如果有,再判断当前时间戳减去有效时间后是否超过了Cookie中的时间戳,超过即表示Cookie密码已过期。如果时间戳没有过期,继续利用数据库中的密码判断Cookie中的时间戳和Cookie密钥加密后的结果是否与Cookie中的密码相同,只有相同的情况下,才能保证这个Cookie密码是有效的。
接下来,编写login.php,判断当前用户是否已经在Cookie中保存了登录状态,代码如下:
在这里插入图片描述
当用户保存了登录状态时 代码如下:
在这里插入图片描述
第2行通过input()函数获取$_COOKIE中保存的信息,需要在该函数中增加针对Cookie的处理。
(10)用户上传头像
在这里插入图片描述

第10-11行用于根据当前用户的id查询用户头像,保存到$avatar变量中。编写显示当前用户头像和上传头像的页面代码如下:
在这里插入图片描述

当用户头像$avatar值不为空时,显示“./uploads/avatar”中保存的用户头像,否则显示默认头像“./images/noavatar.gif”。
实现接收用户上传头像的表单,代码如下:
在这里插入图片描述

第3行代码调用了input()函数,用于获取 F I L E S 数组中的信息,需要在该函数中增加对 _FILES数组中的信息,需要在该函数中增加对 FILES数组中的信息,需要在该函数中增加对_FILES数组的支持。
实现头像文件上传的代码:
在这里插入图片描述
第4行实列化了文件上传类Upload,第5行调用了uploadone()方法上传单个文件,上传成功后的返回值为自动生成的文件名;第6行用于当上传文件失败时获取错误信息。
(11)栏目管理

  • 栏目数据的读取和显示
    栏目数据的代码封装成category_list()函数代码如下:

在这里插入图片描述
栏目页代码如下:
在这里插入图片描述
第10行通过调用category_list()函数获取了栏目数据。在侧边栏中输出栏目数据值之前,先将侧边栏的HTML代码提取出来,保存到slide,html文件中,代码如下:
在这里插入图片描述
编写栏目管理页面代码如下:
在这里插入图片描述
第2-13行用于修改栏目,第14-18行用于添加栏目。值得一提的是,默认情况下第14-18行代码是隐藏且禁用的,因为这部分代码仅用于JavaScript进行处理。当用户单击第19行的“添加栏目”时,页面中的JavaScriot程序会读取第14-18行代码,将这部分代码复制一份后取消隐藏和取消禁用,并追加到表单中。用户可以单击多次“添加栏目”添加多个,每次复制时,会将input元素name属性中的占位符“ID”替换为数字。该数字从0开始,每次添加新栏目后自增1,从而确保在表单中区分每个新增的栏目。
将添加、修改、删除、功能分别封装到category_add()函数、category_save()函数、category_delete()函数中,代码如下:
在这里插入图片描述

  • 栏目添加
    代码如下:
    在这里插入图片描述
    第3行调用了category_cover_upload()函数用于上传图片,第4-12行用于收集表单数据,进行过滤后保存到数据库中。代码如下:
    在这里插入图片描述
    第5行的upload()方法用于上传多个文件,返回值是一维数组,数组的键为表单中文件上传输入框的name属性,期值是“save_cover[键名]”或“add_cover[键名]”中的一种,数组的值包括目录的文件名的数组。第4行的config(‘PICTURE_EXT‘)表示读取配置文件中允许上传的图片扩展名,代码如下:
    在这里插入图片描述
  • 栏目修改
    代码如下:
    在这里插入图片描述
    第3-14行代码实现了对栏目记录的修改;第16-20行代码用于当用户选中栏目图片上的“删除”复选框时,通过 c o v e r 记录需要删除的图片的栏目记录;第 21 − 25 行代码用于调用 c a t e g o r y c o v e r u p l o a d ( ) 函数上传图片文件;第 28 行用于将栏目图片修改结果保存到 cover记录需要删除的图片的栏目记录;第21-25行代码用于调用category_cover_upload()函数上传图片文件;第28行用于将栏目图片修改结果保存到 cover记录需要删除的图片的栏目记录;第2125行代码用于调用categorycoverupload()函数上传图片文件;第28行用于将栏目图片修改结果保存到cover中;第27行代码用于根据$cover中保存的栏目id删除该栏目的图片文件;第28行用于将栏目图片修改结果保存到数据库中。
    编写category_cover_delete()函数,代码如下:
    在这里插入图片描述
  • 栏目删除
    代码如下:
    在这里插入图片描述
    第5-8行代码实现了先删除栏目图片再删除栏目记录,第10行用于将被删除栏目下POST表中的记录更改为空栏目。
    (11)内容发布与修改
  • 内容发布
    代码如下:
    在这里插入图片描述
    编写post.php,文件代码如
    在这里插入图片描述
    第9-11行用于限制URL参数type的值只能是pic、text或video,如果是其他值则自动修改为text;第12行调用了display()函数,用于显示页面并退出,代码如下:
    在这里插入图片描述
    i d 的值不为 0 时,执行第 5 − 15 行代码,根据 i d 查找对应的内容,其中第 7 行用于查找 p o s t 记录,保存到变量 id的值不为0时,执行第5-15行代码,根据id查找对应的内容,其中第7行用于查找post记录,保存到变量 id的值不为0时,执行第515行代码,根据id查找对应的内容,其中第7行用于查找post记录,保存到变量post中;第8-10行用于判断当 p o s t 为空,或当前登录用户不是管理员且不是内容作者时 , 禁止编辑;第 13 行用于查找 a t t a c h m e n t 记录,保存到变量 post为空,或当前登录用户不是管理员且不是内容作者时,禁止编辑;第13行用于查找attachment记录,保存到变量 post为空,或当前登录用户不是管理员且不是内容作者时,禁止编辑;第13行用于查找attachment记录,保存到变量atch中。
  • 创建表单
    代码如下;
    在这里插入图片描述
  • 接收表单
    代码如下:
    在这里插入图片描述
    第2-6行用于获取表单数据,第8-17行用于修改记录,第19-22行用于添加记录
    (12)处理图片和视频
  • 修改内容时删除关联的图片或视频
    代码如下:
    在这里插入图片描述
    第4行调用了post_picture_delete()函数来删除图片,代码如下
    在这里插入图片描述
    根据attachment表中的pid和id字段查询记录,查询后删除图片文件,然后再删除数据库中的记录。
  • 接收图片或视频
    代码如下:
    在这里插入图片描述
    第3行代码用于当整个流程没有错误时,跳转到内容查看页面,查看当前编辑后的内容;若流程中发生错误,则显示内容编辑页面并提示错误信息。
    编写post_attachment()函数代码如下:
    在这里插入图片描述
    (13)内容查看
  • 获取查看内容
    代码如下:
    在这里插入图片描述
  • 输出到页中
    在这里插入图片描述
    (14)发表回复
  • 发表回复
    代码如下:
    在这里插入图片描述
    表单提交到了show.php中,并传递了参数action=reply。接下来处理表单代码如下:
    在这里插入图片描述
    第9行代码用于增加被回复内容在post表中的回复量统计数,回复成功后,程序跳转到show.php页面,并添加锚点”#reply”定位到查看回复的位置
  • 查看回复
    代码如下:
    在这里插入图片描述
    接下来输出回复列表,代码如下:
    在这里插入图片描述
  • 删除回复
    用于管理员或发表回复的用户删除回复,代码如下:
    在这里插入图片描述
    处理删除回复的请求,代码如下:
    在这里插入图片描述
    第6行代码在删除回复时先判断是否为管理员,如果是管理员则直接删除指令id的回复,否则在删除回事的同时将当前用户id作为WHERE条件,防止普通用户删除其他用户的回复。

五、运行测试

(1)主页
在这里插入图片描述
(2)登录页面
在这里插入图片描述
(3)注册
在这里插入图片描述
(4)查看回复
在这里插入图片描述
(5)发布页面
在这里插入图片描述
(6)管理员删除编辑页面提示
在这里插入图片描述
(7)编辑栏目
在这里插入图片描述
(8)关于作者用户帮助页面
在这里插入图片描述

六、 总结

学习PHP的基础知识和技术。这些知识大概有语言基础、字符串、数组、正则表达式、与web页面交互、加密、面向对象、会话等等,花了几天的时间来学习。不管学什么语言,基础都是最重要的。在语法上感觉php跟javascript也有一些相似之处。随着学习的知识不断增多,不懂的问题也开始出现,一直有写笔记的习惯。主要是一些自己的总结,收藏的博客,重复代码块等等。
再接下来接触到数据库。PHP支持多种数据库,尤其与MySQL关系最好。刚开始学习数据库基础的时候,还是建议大家在命令提示符下操作数据库。虽然有MySQL图形化管理工具,但是一开始不要太过于依赖它了。PHP提供了mysql扩展和mysqli扩展,用来操作数据库,前者已经被废除。还有就是对所有数据库都通用的一个扩展PDO,它屏蔽了各种数据库系统的差异,使用同一个接口来访问各种数据库。就像Java的JDBC那样,很方便程序从不同数据库之间的移植。
在这里还要提到有关数据库的一些函数封装,我们用一般方法进行数据库操作要分开写很多方法。用面向对象的方法会增强开发效率。可以从网上找一些源代码来研究。另外还要注意MySQL的优化,让数据库尽量用更少的时间 找到我们需要的东西。
还有就是调试程序的技巧,比如说可以分段echo结果,缩小调试范围,特别是在与数据库交互的时候,先输出SQL语句看看,再分析怎么会操作不成功等等。调试程序可能会占用很多的时间,当然还是要总结自己的调试经验。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/708210
推荐阅读
相关标签
  

闽ICP备14008679号