ThinkPHP初學者:主頁,獲取一個文章列表

之前的文章,已經(jīng)實現(xiàn)了注冊登錄的功能,主要熟悉TP與HTML、JS交互,數(shù)據(jù)庫的基本操作等。接下來就要登錄到主頁,熟悉一下列表的處理,以及數(shù)據(jù)庫多表聯(lián)查操作。為了簡化模型,列表的字段僅有文章標題、簡介、內(nèi)容、封面圖片、作者字段。

Session保持,從登錄到主頁

要想實現(xiàn)上述的功能,就需要先進入到首頁,這里設計的是用戶必須先登錄才能進入到首頁,因此需要使用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協(xié)議,傳輸json需要添加請求頭
    header('Content-Type:application/json; charset=utf-8');

    ...//校驗

    session('username', $user_name);

    $return['code'] = 1;
    $return['message'] = '登錄成功';
    echo json_encode($return);
}

然后在index.html里點擊登錄按鈕時,加入以下跳轉(zhuǎn)語句:

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為空,就跳轉(zhuǎn)到登錄頁面,成功獲取到session時才顯示主頁。跳轉(zhuǎn)要用重定向redirect方法。

以上便實現(xiàn)了攜帶登錄信息并跳轉(zhuǎn)到主頁的功能了,然而有一個細節(jié)問題是,當用戶點擊瀏覽器的返回按鈕時,頁面又回退到了之前的登錄頁面,很顯然這不是我們希望的行為。我們希望用戶點返回按鈕時,如果已經(jīng)登錄了,依然停在主頁。一般的做法是:進入登錄頁時請求數(shù)據(jù),如果是已登錄狀態(tài),就跳轉(zhuǎn)到主頁,這樣點擊返回按鈕時,返回到了登錄頁,登錄頁又重新跳轉(zhuǎn)到了主頁,便實現(xiàn)了我們需要的功能。代碼比較簡單,節(jié)約篇幅就不粘貼了,可以在文末鏈接查看。

創(chuàng)建文章數(shù)據(jù)表,初始化一些測試數(shù)據(jù)

在數(shù)據(jù)庫中加入以下這張表:

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片,命名后放在以下路徑:

image.png

接下來在數(shù)據(jù)庫中插入幾條數(shù)據(jù),其中圖片的路徑寫相對于根目錄的路徑,也就是/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);

多表聯(lián)查,顯示在主頁

如文章一開始所言,在頁面上展示列表需要的字段有:文章標題、簡介、封面圖和作者信息。前幾個字段都在article這張表中,而作者的信息是通過author_id字段關(guān)聯(lián)到user表中的,所以想要獲取作者的信息,就涉及到了聯(lián)查。在MySQL中,使用join關(guān)鍵字進行聯(lián)查。規(guī)則為:

... FROM table1 INNER|LEFT|RIGHT JOIN table2 ON condition

其中INNER表示取得兩個表中存在連接匹配關(guān)系的記錄,LEFT表示取得左表(table1)完全記錄,即使右表(table2)并無對應匹配記錄,RIGHT表示取得右表(table2)完全記錄,即使左表(table1)并無匹配對應記錄。

文字表述很是生硬,下面看如何利用這個規(guī)則來查詢出我們需要的數(shù)據(jù),因為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記錄,根據(jù)它的author_id找到一條user記錄,如果這個條件成立,就把它的結(jié)果合并成一條數(shù)據(jù)返回,數(shù)據(jù)只取我們select的字段。把數(shù)據(jù)庫中所有的數(shù)據(jù)都找完之后就返回了一個列表,這個列表就是我們需要的。除此以外,如果兩個表中有重復的字段時,還可以使用別名來區(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,并給每個字段都起了別名,這樣,如果au中如果有相同的字段,可以通過不同的命名使返回結(jié)果符合預期。

以上是用MySQL命令行實現(xiàn)的查詢,那么用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”可以省略。

獲取到數(shù)據(jù)后,需要把數(shù)據(jù)渲染到頁面上,這里有兩種方式可以選擇。一種是已經(jīng)很熟悉的Ajax,還有一種則是在HTML中嵌入php代碼。因為更熟悉Ajax,這里先展示Ajax的寫法。由于界面是列表,所以<div>等標簽只能動態(tài)創(chuàng)建,我們使用jQuery完成這個功能類似如下:

$.each(list,function(index,value,array)){
    $('container').append('{這里寫要添加的div}');
}

套用一下,這里list就是我們的數(shù)組,$.each是jQuery里的foreach循環(huán)的寫法,后邊的index、value就表示位置和值。append方法就是往container中添加組件,把全部代碼都寫在參數(shù)里就好了,這里參數(shù)是字符串,所以引用變量要用+和字符串連接起來。例如:

'<span class="left author">' +
  value.user_name +
 '</span>'
  ......

原理就是這樣的,要看詳細的代碼,可以在文末鏈接找。

接下來實現(xiàn)第二種方案,就是在HTML中嵌入php代碼。這種方式,就需要在調(diào)用display方法前,把數(shù)據(jù)從數(shù)據(jù)庫中查詢出來,然后通過assign方法綁定到頁面上,然后在頁面里的php代碼就可以獲取到數(shù)據(jù)的值。修改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把數(shù)據(jù)綁定到了頁面上articles變量。接下來我們在html中使用這個變量。因為是數(shù)組,所以也需要遍歷。

<foreach name="articles" item="art">
    <div class="wz">
        <h3><a href="#" title="{$art.title}">{$art.title}</a></h3>
        ......
    </div>
</foreach>

可以看到,使用也是非常簡單,只是使用變量時要使用php的規(guī)則,并且用花括號括起來。

在實際中,根據(jù)需要兩種方式都可以選擇,如果是前后端分離,肯定只能用第一種方式了,或者用別的框架實現(xiàn),但php都只以接口的形式提供數(shù)據(jù)。

這樣一個展示列表的頁面就完成了,相關(guān)代碼已經(jīng)同步到github。

奉上github地址:https://github.com/LtLei/PHPLearn。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容