ThinkPHP初学者:主页,获取一个文章列表

之前的文章,已经实现了注册登录的功能,主要熟悉TP与HTML、JS交互,数据库的基本操作等。接下来就要登录到主页,熟悉一下列表的处理,以及数据库多表联查操作。为了简化模型,列表的字段仅有文章标题、简介、内容、封面图片、作者字段。

Session保持,从登录到主页

要想实现上述的功能,就需要先进入到首页,这里设计的是用户必须先登录才能进入到首页,因此需要使用Session来记录登录的状态。在TP中,使用Session格外简单。

创建一个session
session('name','value');
删除一个session
session('name',null);
删除所有session
session(null);

以上仅是最基本的使用方法,还有其他的一些用法可以查看文档。

所以,需要在登录成功时,把session创建好,进入主页后检查session是否存在,存在则继续,不存在就返回到登录。修改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')}";

为了测试这一点,先写一个简单的主页,仅仅输出一句话。然后创建home方法:

public function home() {
    $username = session('username');
    if (empty($username)) {
        $this->redirect('Index/index');
    } else {
        $this->display();
    }
}

这段逻辑是如果session为空,就跳转到登录页面,成功获取到session时才显示主页。跳转要用重定向redirect方法。

以上便实现了携带登录信息并跳转到主页的功能了,然而有一个细节问题是,当用户点击浏览器的返回按钮时,页面又回退到了之前的登录页面,很显然这不是我们希望的行为。我们希望用户点返回按钮时,如果已经登录了,依然停在主页。一般的做法是:进入登录页时请求数据,如果是已登录状态,就跳转到主页,这样点击返回按钮时,返回到了登录页,登录页又重新跳转到了主页,便实现了我们需要的功能。代码比较简单,节约篇幅就不粘贴了,可以在文末链接查看。

创建文章数据表,初始化一些测试数据

在数据库中加入以下这张表:

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。然后在项目的根目录创建一个upload文件夹,因为是练手,所以图片都直接放在项目里了,实际中当项目比较大时,文件都是专门放在另外的服务器的。然后找几张图片,命名后放在以下路径:

image.png

接下来在数据库中插入几条数据,其中图片的路径写相对于根目录的路径,也就是/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关键字进行联查。规则为:

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

其中INNER表示取得两个表中存在连接匹配关系的记录,LEFT表示取得左表(table1)完全记录,即使右表(table2)并无对应匹配记录,RIGHT表示取得右表(table2)完全记录,即使左表(table1)并无匹配对应记录。

文字表述很是生硬,下面看如何利用这个规则来查询出我们需要的数据,因为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的字段。把数据库中所有的数据都找完之后就返回了一个列表,这个列表就是我们需要的。除此以外,如果两个表中有重复的字段时,还可以使用别名来区分,如这条语句使用别名就表示为:

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中如果有相同的字段,可以通过不同的命名使返回结果符合预期。

以上是用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>等标签只能动态创建,我们使用jQuery完成这个功能类似如下:

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

套用一下,这里list就是我们的数组,$.each是jQuery里的foreach循环的写法,后边的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的规则,并且用花括号括起来。

在实际中,根据需要两种方式都可以选择,如果是前后端分离,肯定只能用第一种方式了,或者用别的框架实现,但php都只以接口的形式提供数据。

这样一个展示列表的页面就完成了,相关代码已经同步到github。

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容