首页 » PHP和MySQL Web开发(原书第4版) » PHP和MySQL Web开发(原书第4版)全文在线阅读

《PHP和MySQL Web开发(原书第4版)》27.7 实现书签推荐

关灯直达底部

最后,我们将讨论书签推荐脚本recommend.php。我们可以通过许多方法实现书签推荐。在此,我们决定应用“相似意向”的推荐。该推荐的含义是,查找与给定用户至少有一个相同书签的其他用户。其他用户的其他书签也对给定的用户有吸引力。

将“相似意向”应用到SQL查询最简单的方法是使用子查询。第一个子查询如下所示:

select distinct(b2.username)

from bookmark b1,bookmark b2

where b1.username='".$valid_user."'

and b1.username!=b2.username

and b1.bm_URL=b2.bm_URL)

这个查询使用别名将数据库表bookmark进行自身连接——这是一个很奇怪但是有时候又非常有用的概念。假设有两个书签表,b1和b2。在b1中,查询当前用户及其书签。在另一个表中,查询所有其他用户的书签。我们需要查找的是用户书签中有一个URL与当前用户相同(b1.bm_URL=b2.bm_URL)的其他用户(b2.username)。其他用户不包括当前用户(b1.username!=b2.username)。

该查询将给出一个与当前用户意向相似的人的列表。得到了这个用户列表后,可以用下面的查询搜索他们的其他书签了:

select bm_URL

from bookmark

where username in

(select distinct(b2.username)

from bookmark b1,bookmark b2

where b1.username='".$valid_user."'

and b1.username!=b2.username

and b1.bm_URL=b2.bm_URL)

可以添加第二个子查询来过滤当前用户的书签;如果用户已经有了这些书签,就不必再将该书签推荐给他。最后,对$popularity变量进行书签过滤。我们不希望推荐太个性化的URL,因此只将一定数量的其他用户做了书签的URL推荐给用户。最终的查询如下所示:

select bm_URL

from bookmark

where username in

(select distinct(b2.username)

from bookmark b1,bookmark b2

where b1.username='".$valid_user."'

and b1.username!=b2.username

and b1.bm_URL=b2.bm_URL)

and bm_URL not in

(select bm_URL

from bookmark

where username='".$valid_user."')

group by bm_url

having count(bm_url)>".$popularity;

如果我们期望许多用户使用我们的系统,可以调整变量$popularity,只推荐许多其他用户做了书签的URL。许多人做了书签的URL可能质量更高,这样的书签当然比一般的页面更大众化、更具吸引力。

实现书签推荐的完整脚本如程序清单27-26和程序清单27-27所示。推荐的主脚本称为recommend.php(请参阅程序清单27-26),它调用来自url_fns.php函数库(请参阅程序清单27-27)的函数recommend_urls。

程序清单27-26 recommend.php——推荐某一用户可能喜欢的书签

<?php

require_once('bookmark_fns.php');

session_start;

do_html_header('Recommending URLs');

try{

check_valid_user;

$urls=recommend_urls($_SESSION['valid_user']);

display_recommended_urls($urls);

}

catch(Exception$e){

echo$e->getMessage;

}

display_user_menu;

do_html_footer;

?>

程序清单27-27 url_fns.php文件中的recommend_urls函数——该脚本做出实际的推荐

function recommend_urls($valid_user,$popularity=1){

//We will provide semi intelligent recommendations to people

//If they have an URL in common with other users,they may like

//other URLs that these people like

$conn=db_connect;

//find other matching users

//with an url the same as you

//as a simple way of excluding people's private pages,and

//increasing the chance of recommending appealing URLs,we

//specify a minimum popularity level

//if$popularity=1,then more than one person must have

//an URL before we will recommend it

$query="select bm_URL

from bookmark

where username in

(select distinct(b2.username)

from bookmark b1,bookmark b2

where b1.username='".$valid_user."'

and b1.username!=b2.username

and b1.bm_URL=b2.bm_URL)

and bm_URL not in

(select bm_URL

from bookmark

where username='".$valid_user."')

group by bm_url

having count(bm_url)>".$popularity;

if(!($result=$conn->query($query))){

throw new Exception('Could not find any bookmarks to recommend.');

}

if($result->num_rows==0){

throw new Exception('Could not find any bookmarks to recommend.');

}

$urls=array;

//build an array of the relevant urls

for($count=0;$row=$result->fetch_object;$count++){

$urls[$count]=$row->bm_URL;

}

return$urls;

}

recommend.php的输出示例如图27-11所示。

图 27-11 脚本向该用户推荐了他可能喜欢的amazon.com,数据库中至少有两位用户将amazon.com作为他们的书签