在之前的文章渣锦,已經實現了注冊登錄的功能,主要熟悉TP與HTML氢哮、JS交互袋毙,數據庫的基本操作等。接下來就要登錄到主頁冗尤,熟悉一下列表的處理听盖,以及數據庫多表聯查操作胀溺。為了簡化模型,列表的字段僅有文章標題皆看、簡介仓坞、內容、封面圖片腰吟、作者字段无埃。
Session保持,從登錄到主頁
要想實現上述的功能毛雇,就需要先進入到首頁嫉称,這里設計的是用戶必須先登錄才能進入到首頁,因此需要使用Session來記錄登錄的狀態(tài)禾乘。在TP中澎埠,使用Session格外簡單虽缕。
創(chuàng)建一個session
session('name','value');
刪除一個session
session('name',null);
刪除所有session
session(null);
以上僅是最基本的使用方法始藕,還有其他的一些用法可以查看文檔。
所以氮趋,需要在登錄成功時伍派,把session創(chuàng)建好,進入主頁后檢查session是否存在剩胁,存在則繼續(xù)诉植,不存在就返回到登錄。修改login方法:
public function login() {
//HTTP協議昵观,傳輸json需要添加請求頭
header('Content-Type:application/json; charset=utf-8');
...//校驗
session('username', $user_name);
$return['code'] = 1;
$return['message'] = '登錄成功';
echo json_encode($return);
}
然后在index.html里點擊登錄按鈕時晾腔,加入以下跳轉語句:
window.location.href = "{:U('Index/home')}";
為了測試這一點,先寫一個簡單的主頁啊犬,僅僅輸出一句話灼擂。然后創(chuàng)建home方法:
public function home() {
$username = session('username');
if (empty($username)) {
$this->redirect('Index/index');
} else {
$this->display();
}
}
這段邏輯是如果session為空,就跳轉到登錄頁面觉至,成功獲取到session時才顯示主頁剔应。跳轉要用重定向redirect
方法。
以上便實現了攜帶登錄信息并跳轉到主頁的功能了语御,然而有一個細節(jié)問題是峻贮,當用戶點擊瀏覽器的返回按鈕時,頁面又回退到了之前的登錄頁面应闯,很顯然這不是我們希望的行為纤控。我們希望用戶點返回按鈕時,如果已經登錄了碉纺,依然停在主頁船万。一般的做法是:進入登錄頁時請求數據细层,如果是已登錄狀態(tài),就跳轉到主頁唬涧,這樣點擊返回按鈕時疫赎,返回到了登錄頁,登錄頁又重新跳轉到了主頁碎节,便實現了我們需要的功能捧搞。代碼比較簡單,節(jié)約篇幅就不粘貼了狮荔,可以在文末鏈接查看胎撇。
創(chuàng)建文章數據表,初始化一些測試數據
在數據庫中加入以下這張表:
create table if not exists article(
id int unsigned auto_increment,
title varchar(50) not null,
descript text not null,
content text not null,
image_path varchar(100) not null,
author_id int unsigned not null,
create_time int unsigned not null default 0,
primary key (id)
)engine=InnoDB default charset=utf8;
其中author_id
對應的是User表中對應作者的id殖氏。然后在項目的根目錄創(chuàng)建一個upload文件夾晚树,因為是練手,所以圖片都直接放在項目里了雅采,實際中當項目比較大時爵憎,文件都是專門放在另外的服務器的。然后找?guī)讖垐D片婚瓜,命名后放在以下路徑:
接下來在數據庫中插入幾條數據宝鼓,其中圖片的路徑寫相對于根目錄的路徑,也就是/upload/home/image/xxx.jpg
巴刻。示例如下:
insert into article (title,descript,content,image_path,author_id,create_time)
values ('重磅消息1','Python超過Java了1','Python超過Java了,在Github上排名第二愚铡,Java屈居第三。1','/upload/home/image/article1.jpg',1,0);
多表聯查胡陪,顯示在主頁
如文章一開始所言沥寥,在頁面上展示列表需要的字段有:文章標題、簡介柠座、封面圖和作者信息邑雅。前幾個字段都在article
這張表中,而作者的信息是通過author_id
字段關聯到user
表中的愚隧,所以想要獲取作者的信息蒂阱,就涉及到了聯查。在MySQL中狂塘,使用join
關鍵字進行聯查录煤。規(guī)則為:
... FROM table1 INNER|LEFT|RIGHT JOIN table2 ON condition
其中INNER表示取得兩個表中存在連接匹配關系的記錄,LEFT表示取得左表(table1)完全記錄荞胡,即使右表(table2)并無對應匹配記錄妈踊,RIGHT表示取得右表(table2)完全記錄,即使左表(table1)并無匹配對應記錄泪漂。
文字表述很是生硬廊营,下面看如何利用這個規(guī)則來查詢出我們需要的數據歪泳,因為article表和user表對我們一樣重要,所以應該使用INNER模式:
select
article.title,
article.descript,
article.content,
article.image_path,
user.user_name
from
article
inner join
user
on
article.author_id=user.id;
以上語句就表示露筒,找到一條article
記錄呐伞,根據它的author_id
找到一條user
記錄,如果這個條件成立慎式,就把它的結果合并成一條數據返回伶氢,數據只取我們select
的字段。把數據庫中所有的數據都找完之后就返回了一個列表瘪吏,這個列表就是我們需要的癣防。除此以外,如果兩個表中有重復的字段時掌眠,還可以使用別名來區(qū)分蕾盯,如這條語句使用別名就表示為:
select
a.title title,
a.descript descript,
a.content content,
a.image_path image_path,
u.user_name user_name
from
article a
inner join
user u
on
a.author_id=u.id;
也就是給article
起別名為a
,給user
起別名為u
蓝丙,并給每個字段都起了別名级遭,這樣,如果a
和u
中如果有相同的字段迅腔,可以通過不同的命名使返回結果符合預期装畅。
以上是用MySQL命令行實現的查詢靠娱,那么用TP該怎么寫呢沧烈?首先別名使用alias
方法,限定要查詢的字段使用field
像云,join則有對應的方法锌雀,名稱也為join
。所以以上語句使用TP的連貫操作如下:
$Article = M('Article');
$res = $Article
->alias('a')
->field('a.title title,a.descript descript,a.content content,a.image_path image_path,u.user_name user_name')
->join('inner join user u on a.author_id=u.id')
->select();
當使用的join為inner
方式時迅诬,join方法中的“inner join”可以省略腋逆。
獲取到數據后,需要把數據渲染到頁面上侈贷,這里有兩種方式可以選擇惩歉。一種是已經很熟悉的Ajax,還有一種則是在HTML中嵌入php代碼俏蛮。因為更熟悉Ajax撑蚌,這里先展示Ajax的寫法。由于界面是列表搏屑,所以<div>
等標簽只能動態(tài)創(chuàng)建争涌,我們使用jQuery完成這個功能類似如下:
$.each(list,function(index,value,array)){
$('container').append('{這里寫要添加的div}');
}
套用一下,這里list就是我們的數組辣恋,$.each
是jQuery里的foreach循環(huán)的寫法亮垫,后邊的index模软、value就表示位置和值。append
方法就是往container
中添加組件饮潦,把全部代碼都寫在參數里就好了燃异,這里參數是字符串,所以引用變量要用+
和字符串連接起來继蜡。例如:
'<span class="left author">' +
value.user_name +
'</span>'
......
原理就是這樣的特铝,要看詳細的代碼,可以在文末鏈接找壹瘟。
接下來實現第二種方案鲫剿,就是在HTML中嵌入php代碼。這種方式稻轨,就需要在調用display
方法前灵莲,把數據從數據庫中查詢出來,然后通過assign
方法綁定到頁面上殴俱,然后在頁面里的php代碼就可以獲取到數據的值政冻。修改home方法:
public function home() {
$username = session('username');
if (empty($username)) {
$this->redirect('Index/index');
} else {
$Article = M('Article');
$res = $Article
->alias('a')
->field('a.title title,a.descript descript,a.content content,a.image_path image_path,u.user_name user_name')
->join('user u on a.author_id=u.id')
->select();
$this->assign('articles', $res);
$this->display();
}
}
以上代碼使用assign
把數據綁定到了頁面上articles
變量。接下來我們在html中使用這個變量线欲。因為是數組明场,所以也需要遍歷。
<foreach name="articles" item="art">
<div class="wz">
<h3><a href="#" title="{$art.title}">{$art.title}</a></h3>
......
</div>
</foreach>
可以看到李丰,使用也是非常簡單苦锨,只是使用變量時要使用php的規(guī)則,并且用花括號括起來趴泌。
在實際中舟舒,根據需要兩種方式都可以選擇,如果是前后端分離嗜憔,肯定只能用第一種方式了秃励,或者用別的框架實現,但php都只以接口的形式提供數據吉捶。
這樣一個展示列表的頁面就完成了夺鲜,相關代碼已經同步到github。
奉上github地址:https://github.com/LtLei/PHPLearn呐舔。