/pj2

this is

Primary LanguageTSQL

project2

石天元 19302010036

pj完成情况

功能完备,运行良好。

首页

本次项目主要内容均用php编写。首先在所有页面中都引入了config.php文件,用于登入MySQL数据库。php的最开头生成一系列数组,用于预先存放从数据库中引入的信息。比如首页中的二维数组$picinfo为一个二维数组,其$picinfo['title']为图片id与标题对应关系的数组,$picinfo['description']为图片id与描述对应关系的数组,$picinfo['path']是图片路径。(在其他页面中,保存图片信息的方式也是类似的,仅有细微差别。)
用pdo从数据库中导入信息。首页需要实现展示收藏最多的图片,创建$picfavor数组用于保存图片对应的收藏人数,并将每一个值先设为0。
在方法initialPic()实现了页面初始化。首先创建数组$mostfavor,其中有6个键值对,键代表图片id,值代表收藏的人数(初始均为0)。先通过遍历travelimagefavor数据库得到有数据的$picfavor,然后对$picfavor进行遍历,如果遍历到的收藏数大于$mostfavor中的某个值,则用其替换$mostfavor中最小的值。然后将$mostfavor中按从大到小顺序将图片id保存到有序数组$picshow中去(用于显示)
方法randomPic ()用于随机选图片,生成一个1到图片总数量间的正整数。 方法showpic($order)为展示图片的方法。接受代表第几张图片整数$order,用echo的方式写html界面。如果展示初始按热度排序的图片则按照$picshow[$order]的id来展示,如果随机展示图片则按照图片id为randomPic()生成的id来展示。其他页面也有类似这个方法,有细微差异。
方法shownav()用于打印登录那一栏的信息。检查cookie中的UserName参数的值,若有,则为已登录,下拉菜单显示上传、我的照片、我的收藏、登出链接。若无,未登录,下拉菜单的地方变成登录链接。此方法在所有页面中均同。
然后就是正常的调用方法并打印页面。 其中是否随机展示图片用cookie中的ranpic参数决定,有此参数则随机展示图片,无则热度顺序展示。通过JavaScript为该按钮加监听器,点击按钮,则通过ajax传信息到index1.php文件,由该文件实现cookie的改写。点击按钮则将其设为1,并且刷新页面。cookie中的ranpic参数保存事件60秒,防止过一段时间后打开页面仍为随机展示。点击导航栏中的链接、下拉菜单中链接、点击图片跳转到详情页都将ranpic参数清空。而点击logout按钮也通过发送ajax请求的方式将cookie中的UserName参数清空。本pj主要以这种方式在js与php间建立联系。

浏览页

浏览页实现多种筛选模式。
浏览页与搜索页都通过读取cookie来决定展示哪些图片,浏览页中为'browser',搜索页中为'search'。参数形式为用字母x分隔开的图片id(如果搜索没有结果则为'nothing')。
在browser.php一开始先从数据库获取数据。用$picpath数组保存图片路径,用$geocountry数组保存travelimage表格中所有出现过的国家(键是ISO编号,值为国家名),$geocities保存所有出现过的城市(键为城市代码,值为城市名)。用$countrycity二维数组保存国家与城市的对应关系。 getPopularCountry(),getPopularCity(),getPopulartheme()方法分别对应热门国家快速浏览,热门城市快速浏览,热门主题快速浏览。以getPopularCountry()为例,首先用pdo遍历travelimage表,创建$countries数组,键为国家的ISO号码,值为该国的图片数量。再通过循环遍历生成有序数组$mascouns,共4个值,maxcouns[0],[1],[2],[3]分别对应第1、2、3、4多图片的国家。然后在热门国家快速浏览条目下面打印这几个国家的链接,id为ISO码,text为国家名。热门城市浏览与热门主题浏览过程与此类似。
showpic($pic)方法用于展示图片。接受字符串$pics(即用x分隔的图片id序列),通过echo打印html界面。$pic在筛选搜索时传入的是cookie中的'browser'参数,页面初始化加载时为随机图片序列。特殊地,若筛选无结果,则打印“没有找到相关照片”。
showpic方法实现了图片分页展示(其他页面的这个方法也通过类似的方法实现分页),这里为一页24张图片。将字符串$pics分割为有序数组$picarray(值为图片id),同时生成有序数组$patharray(值为图片的路径)。这两个数组每个元素两两对应。$pages是计算得到的需要的总页数,若大于5则只取5。$num为检索得到的图片数量。图片在第几页这个信息由url中的'page'属性决定,即$_GET('page')。若无该属性则默认为1。分两种情况打印页面,当$_GET['page']==$pages时,代表现在处于最后一页,故for循环遍历打印的$i范围为从(pages-1)*24到$num;若$_GET['page']!=$pages,说明不是最后一页,故从这一页起打印满24张图片即可。 方法还打印的下方的页码,实现跳转功能。点击上一页跳到:若当前为第一页则第一页,若非则上一页。点击下一页跳到:若当前为最后页则最后页,若非则下一页。点击数字页码跳到对应页面。同时通过JavaScript实现当前所在页的数字字体变大。
通过JavaScript的addEventListener实现点击热门国家/城市/主题筛选下的条目,发送ajax请求到browser1. php,在服务器端通过数据库检索得到数据并将其写入cookie中。
标题检索实现了模糊查询,sql语句模式为'... title like xxx'。其中这里用到了%x%,代表检索字符串x之前与之后有或无字符,即只要标题中间出现字符串x即可。并且实现了搜索时可以用空格或逗号分隔出多个词语。先将提交表单内的字符串用空格或逗号分隔开保存至$keywords数组中,遍历该数组。(假设输入的搜索为a b c,得到数组['a','b','c'],遍历得到sql语句为 select * from tracelimage where title is not null and title like '%a%' and title like '%b%' and title like '%c%')。通过pdo在数据库中检索,将检索到内容连接为序列,然后用echo打印出的<script>部分发送ajax请求到browser1.php。 下拉栏筛选实现二级联动。这个需要JavaScript来实现,但又发现纯js无法动态从数据库中获取相关信息,于是用echo方式打印内置<script>,因为这样可以将php中的字符串数据直接地传到JavaScript脚本中。遂将所有的国家城市信息放在$str中,经过的复杂的连接,格式为:country1?city1%cityname1&city2%cityname2#country2......(一共涉及到4个符号,不同国家间用#分隔,国家 和 其对应的城市 间用?分隔,不同城市间用&分隔,城市的号码与城市名间用%分隔)将字符串传入script中再在里面进行分割操作,得到数据。然后二级筛选和pj1中方法类似,就是当国家的select值改变时改变城市select的innerHTML。 该表单提交也是执行数据库中内容的筛选动作,与前面搜索的类似。

搜索页

search页面因为要显示图片描述所有一个页面最多放6张图片。图片的展示与搜索与浏览页中的搜索功能均类似,仅比浏览页多一个描述筛选,方法是和标题筛选相同的,这里不再赘述。

登录页面

表单提交时,通过validLogin()判断用户名与密码是否匹配。先判断travelusers内有无该用户,如无则返回false,如有则取出该用户的哈希加密后的密码与它的盐,将输入密码哈希加盐后的值与哈希值比对,相同则登录成功。
登陆成功后把cookie中的'UserName'设置为该用户24小时,并跳转至首页。

注册页面

注册会识别注册是否成功。若不成功则将原先注册信息保存在url后缀里返回,输入框读取url得到默认值,方便注册者在原先基础上进行修改。当信息传入url中时需要对特殊符号转义,translate()方法将?&等字符转义为相应的字符串,retranslate()方法将url中信息逆转义,用来填入表单。 提交表单判断以下内容:用户名是否与数据库中已有的重复,用户名是否太长或太短(要求5-20位之间),用户名是否有不允许的特殊符号,两次输入密码是否一致,邮箱格式是否正确,密码强度是否过低。都通过后随机生成盐,与将密码哈希加盐后的值一起存入数据库,注册成功。

上传页面

此页面实现上传图片和修改图片信息功能。如果url中有id属性则为修改此id图片的信息,无则新上传图片。根据上传还是修改用echo决定页面打印的信息。国家与城市实现二级联动,方法与浏览页中的类似,只不过此页面因为涉及到修改图片,所有页面加载时就需要一次二级联动。这个页面需要从数据库导入大量城市信息。
提交表单先检验是否登录。然后用$_FILE['file']接收上传的图片,并给它的PATH加上时间戳(date('YmdHis'))防止图片路径重复。将$destination 设为../img/normal/medium/后面加上图片的名字。使用$test=move_uploaded_file($file['tmp_name'],$destination)方法将图片保存到该目录下。若上传成功,$test返回值为true,若无图片上传或上传失败,返回false。之后分为上传和修改两种情况:上传需要所有信息都不为空,而修改可以上传的文件为空。判断完不为空之后提交表单,并对数据库进行操作,否则preventDefault()。

我的照片

打印页面的方法与其他页面类似。
getmine()方法用于从数据库中寻找当前用户所上传的图片,返回这些图片id所构成的数组。 判断有无登录,若无则提醒。若有,有上传照片则全部打印,无则打印"您还没有上传过照片"。 每张图片有两个按钮,修改和删除。点击修改直接跳转到上传页面,并将url后缀的id设为此图片id。点击删除用ajax发送请求到mypic1.php,执行删除图片功能。删除一张图片后将数据库中这张图片之后的所有图片id向前移动一位,使其id连贯。

我的收藏

getfavors()方法从数据库中获取当前用户所收藏的图片,以数组形式返回。 展示图片与我的照片页面相同。 点击取消收藏用ajax实现从数据库中删除该用户收藏该图片的条目。

图片详情

走流程,从数据库获取信息,打印。
booltostr($bool)方法接收布尔值$bool,返回为'true'或'false'的字符串。 判断当前用户是否收藏该图片,未收藏显示收藏按钮,已收藏显示取消收藏按钮。此功能通过echo里打印<script>实现,将用户有无收藏的信息在php中保存为$isfavored,用booltostr将其转为字符串,连接进script脚本里,保存为js中的var isfavored. 同理,判断用户是否登录的login也用此方式进入脚本。而在脚本中实现点击按钮收藏或取消收藏的功能。

bonus完成情况

完成了哈希加盐和部署在服务器上的bonus。

哈希加盐

用base64_encode(openssl_random_pseudo_bytes(32)),生成一个32位的随机盐。openssl_random_pseudo_bytes()是内置的专门用于生成随机字符串的方法,保密性很好。然后将盐连在密码后面,使用sha1生成哈希值。(php内置功能好强大)数据库中将密码列删除,新增哈希值与盐的列。登录时将该用户的盐连在输入密码的后面,用sha1哈希化,得到的值与数据库中的值进行比对,来代替密码的比对。

部署服务器

使bai用piao了阿里云的服务器,为了方便选择了windows的服务器。一开始发现无法连接到远程桌面,尝试许多方法均未果。之后发现自己电脑是win10家庭版,遂使用淘宝升级至专业版,乃可正常使用远程桌面功能。
用远程桌面连接到服务器,在服务器端使用宝塔面板,一键安装各种组件:php,apache,MySQL,phpmyadmin,filezila。将pj2的文件夹从自己电脑移动到服务器端桌面,放置于wwwroot文件夹下面,并将文件夹命名为我的域名:dapangqing.top。在服务器端新建travel数据库,将修改过的travel.sql导入,并且服务器端的mysql新建用户用于登录。 在阿里云平台上注册域名dapangqing.top,将域名于我的服务器实例绑定。实名认证之后进行备案,填入各种信息,目前正在备案中,备案通过即可在浏览器上访问网页。 部署服务器中出现了大量的问题,均通过面向搜索引擎的方法一一解决,由于不太记得有哪些问题了,故不再赘述。

对pj2和课程的意见于建议

课程学习还是很舒服的,lab一个个做下来基本上pj就没有问题了。pj2难度适中,没有占用太多时间,可以继续保持。 建议助教天团分享自动抢课工具。