一、sphinx简介
1、为什么要用sphinx
在mysql数据库中,对于如下sql语句,select * from xxx where xxx like ‘%xxx’(以%开头的like查询),无法使用到任何索引优化,导致如果数据量非常大,查询速度会非常慢。而这种sql语句在很多功能中都要用到,如根据歌词查询歌曲,根据剧情查询电影等。如果要加快查询只能使用第三方软件,sphinx和lucence。
mysql中也提供了全文索引的功能,但是有两个问题:(1)只有myisam引擎支持(2)对中文支持不好。不过现在最新的mysql5.6版本中的innodb1.2的版本也同样支持全文索引。
2、sphinx介绍?
中文名:全文索引引擎。只支持英文和俄文。
但是只要有相应的语言包也可支持任何语言。国内有一团队在sphinx基础上封装了一个带中文包的软件:coreseek。
3、使用原理
(1)先创建数据源(一张表的select查询结果),
(2)根据数据源创建索引,使用分词技术。
(3)php把查询的关键词给sphinx服务器,sphinx根据关键词查找到关键字在mysql表里面的记录的id.sphinx把id返回给php查询端
(4)php根据返回的id,查询mysql服务器,
原理图:
根据数据源创建索引,
php把关键词给sphinx的服务器,sphinx服务器返回关键词在mysql表里面的id,
php根据id再查询mysql数据库,最终返回想要的数据。
二、安装shpinx软件
1、下载软件,进行解压
2、把解压后的软件拷贝到指定位置,(便于管理要和其他的环境软件在同级目录里面)
三、具体的配置使用
创建数据源(一张表的数据,或sql语句的执行结果)
1、修改sphinx配置文件,创建数据源与索引位置
复制etc/目录下的 csft_mysql.conf 一份到上一级目录,并改名为:shpinx.conf
(1)配置数据源:
打开sphinx.conf 的配置文件
语法:source 数据源的名称{
//具体的配置
}
要注意:一个配置文件中,可以配置多个数据源,通过数据源的名称来区分。
sql_query_pre = SET NAMES utf8
#主查询,其中第一个字段必须是id,并且类型为非负,非空,唯一的整数。
select id,title,description from movie
(2)配置数据源生成的索引文件存放的位置。
语法:index 索引的名称 (必须与一个数据源相对应)
就是一个数据源对应一个索引文件的配置,
语法 index 索引的名称 {
//具体的配置
}
charset_dictpath = d:/wamp/sphinx/etc/
charset_type=zh_cn.utf-8
(3)配置sphinx服务器的一些配置
2、对查询的数据创建索引
执行sphinx下的一个程序indexer.exe –c配置文件 --all | 索引的名字
注意:
--all:为配置文件中所有的索引创建索引文件。也可以使用索引的名字只为某一个索引创建索引文件
(1)以管理员的方式打开cmd窗口,进入到sphinx 的安装目录里面的bin目录,执行indexer.exe命令
语法:indexer.exe –c配置文件 --all | 索引的名字
indexer –c e:/wamp/sphinx/sphinx.conf movie
(2)查看创建的索引文件
注意:若出现错误:
原因:配置文件的编码是utf-8+的,改成:utf-8即可。
3、启动sphinx的服务器,开始查询
(1)把sphinx安装成window的一个服务。
以管理员的方式进入cmd,进入到sphinx安装文件里面的bin目录,执行
可以通过searchd --help查看帮助
安装的语法:
searchd -c sphinx的配置文件 --install
searchd -c e:/wamp/sphinx/sphinx.conf --install
(2)启动sphinx的服务。
net start searchd
查看是否启动成功。
4、sphinx的查询应用
(1)需要复制一个接口文件到项目中来。
sphinxapi.php
(2)开始执行查询的操作
$sc = new SphinxClient();
$sc->setServer(‘localhost’,9312);
$sc->query(关键词,定义索引的名称);
$keyword = “电影”
$indexName = ‘movie’
$res = $sc->query($keyword,$indexName);
array_keys($res['matches']);//返回的是一个一维数组,
具体的代码如下;
5、对查询到关键词进行标注显示,
可以对关键词添加一些样式,进行显示。
使用一个方法
$sc->buildExcerpts(),给关键词添加样式显示。
foreach($data as $v){
//参数1:在此处循环的一维数组
//参数2:是索引的名称
//参数3:是查询的关键词
//参数4:是添加的样式
//该函数返回的结果是一个索引数组了。
$row = $sc->buildExcerpts($v,$indexName,$keyword,array(
'before_match'=> "<font color='red'>",
'after_match'=>"</font>"
));
echo $row[1].'<br/>';
echo $row[2].'<hr>';
}
访问效果如下;
四、sphinx的匹配模式
1、SPH_MATCH_ALL 完全匹配所有的词
如“冬天 的 雪”,并不会匹配 “我爱冬天”,
但可以匹配 “我的朋友,爱冬天,和雪”。
因为“冬天的雪” 被分成 “冬天”,“的”,“雪”三个词,匹配条件是同时包含
这三个词,“我爱冬天”里只包含一个“冬天”
$keyword = “中国香港”;
$indexName = ‘movie’;
$sc->setMatchMode(SPH_MATCH_ALL);
2、SPH_MATCH_ANY: 匹配任意一个词
如“冬天 的 雪”,并会匹配 “我爱冬天”。
"冬天的雪“ -》 ”冬天“ ”的“ ”雪“
因为“我爱冬天”里有一个“冬天”相匹配。
$keyword = “中国百团”;
$indexName = ‘movie’;
$sc->setMatchMode(SPH_MATCH_ANY);
效果:
3、SPH_MATCH_PHRASE: 必须匹配整个短语,不能分割。
如“冬天的雪”,不会匹配 “我的朋友,爱冬天,和雪”,虽然都包含同样的
$keyword = “武侠电影”;
$indexName = ‘movie’;
$sc->setMatchMode(SPH_MATCH_PHRASE);
4、SPH_MATCH_EXTENDED: 支持一些扩展的语法
支持 @字段 查询
如,查询title包含 abc , content 包含 bcd的:
'@title abc @content bcd'
$keyword = “@title 中国”;
$indexName = ‘’;
$sc->setMatchMode(SPH_MATCH_EXTENDED);
5、SPH_MATCH_BOOLEAN 与,或,非,分组 &,or,!,()
如:hello | world
查询“手机”,或“冬天”,:
$keyword = “大陆|内地”;
$indexName = ‘movie’;
$sc->setMatchMode(SPH_MATCH_BOOLEAN);
五、增量索引
可以对后来增加的数据,单独建立索引,把建立的索引再合并到主索引里面。
新增数据的索引:
实现原理:
1、新建一张表,记录一下上次已经创建好索引的最后一条记录的id
2、当索引时,然后从数据库中取出所有大于id的数据,这些就是新的数据然后创建一个小的索引文件。
3、把增量这部分数据生成的小的索引合并到主索引文件上去。
4、把最后一条记录的id更新到第一步创建的表中。
原理图:
步骤:
(1)创建一张表,用于存储记录最大的 id
create table a(max_id int);
insert into a values(0);
(2)修改配置文件,movie的主索引的数据源的配置。
sql_query = select id,title,description from movie
执行完成主查询后,执行的一个sql语句;
sql_query_post = update a set max_id = (select max(id) from movie);
(3)创建增量数据源和增量数据源对应的索引配置。
sql_query = select id,title,description from movie where id>(select max_id from a);
(4)生成主索引,
在重新生成主索引时,要停止sphinx服务器;
indexer –c d:/wamp/sphinx/sphinx.conf movie
执行完毕后,a表里面,已经记录了movie表里面的最大id
(5)添加数据到数据库里面,
(6)创建增量索引
indexer –c d:/wamp/sphinx/sphinx.conf movie_zl
创建的增量索引如下;
(7)把增量索引合并到主索引里面。
合并的语法:
indexer –c 配置文件 --merge 主索引文件 增量索引文件
indexer –c d:/wamp/sphinx/sphinx.conf --merge movie movie_zl
(7)启动sphinx的服务器,进行查询操作
注意;如果不关闭sphinx服务器,需要在合并时添加一个参数 --rotate 强制合并的意思
indexer –c 配置文件 --merge 主索引文件 增量索引文件 --rotate
六、网页静态化介绍
1、概述:
就是把一个动态的页面(.php)变成一个静态页面(.html),后续用户直接访问静态页面。
页面静态化技术分为两种:真静态和伪静态。
真静态:把一个动态的页面,转成一个静态的页面,即.html文件
伪静态:所谓伪静态是从url地址上看是一个静态页面,但是实际上还是对应一个动态页面,
比如:http://www.abc.com/news-sport-id12.html
实际上是操作。http://www.abc.com/news.php?type=sport&id=12,
2、几个重要的概念
(1)动态网址:
所谓动态网址,一般来说去查询数据库,比如:http://www.abc.com/goods.php?id=20
特点:查询数据库,速度慢;接收参数,安全性要注意(sql注入);不利于seo搜索引擎优化。
(2)静态网址
比如:http://www.abc.com/index.htm这个就是一个静态网址:
特点:不查询数据库,速度快;不接收参数,安全性高;利于seo
(3)伪静态网址:
从形式上看是一个静态页面,但是实际上对应一个动态页面,
特点:本身需要查询数据库,执行速度慢;不接收参数,因此安全;利于seo
3、真静态实现方式
真静态:使用ob缓存技术来实现,
伪静态:使用web服务器的rewrite机制(url的重写机制)来实现。
4、OB基本介绍
ob就是output_buffering输出缓存,在请求一个php的过程中,我们实际上经过三个缓存,
程序缓存、ob缓存、浏览器缓存。
(1)程序缓存(默认开启,不能关闭)
该缓存是php固有的,不能关闭,缓存返回到客户端(浏览器端包括头信息和响应主体信息)的数据。
(2)ob缓存(默认开启,可以关闭)
ob缓存(output_buffering)又叫ob缓冲:缓存响应主体的数据,
在请求一个php文件时,实际上是经过3个缓存区,ob缓存(如果开启)--》程序缓存-》浏览器缓存。
如果开辟了ob缓存,主体数据首先存储到ob缓存里面,头信息要存储到程序缓存(无论是否开启ob缓存),当代码执行完毕后,ob缓存里面的数据刷新(移动)到程序缓存,程序缓存再输出到浏览器缓存中,最后输出内容。
开启方式:
(1)通过在页面中使用函数ob_start(),如果使用该函数,则只对当前页面有效。
(2)通过php.ini配置文件来开启。
output_buffering = 4096
4096是设置ob缓存的容量,也可以不指定容量开启,使用on
output_buffering=on|off|具体的容量
5、ob 缓存对应的函数。
ob_start();开启ob 缓存,在当前页面有效
ob_get_contents();//获取ob缓存里面的数据。
ob_clean();清空ob缓存里面的数据,没有关闭ob缓存。
ob_end_clean();清空ob缓存里面的数据,并关闭ob缓存。
ob_flush();//把ob缓存里面的数据,刷新(移动)到程序缓存,不关闭ob缓存。
ob_end_flush();//把ob缓存里面的数据刷新(移动,推送)到程序缓存,并关闭ob缓存。
ob_gzhandler();函数,对数据进行压缩,依赖于浏览器所能接受的压缩格式,形成不同的压缩编码。
ob_start("ob_gzhandler");可以对ob缓存里面的数据进行压缩后返回数据。
总结:
常用的是:ob_start() ob_get_contents() ob_clean()
$content = ob_get_contents();
file_put_contents(‘index.html’,$content);
6、真静态典型案例。
需要操作:
目标:要判断有没有生成静态页面,如果有静态页面,则直接读取静态页面里面内容,如果没有则要重新生成静态页面。
新闻列表页面:
list.php
新闻详情页面是:
shownews.php页面。
$filename = ‘news_id.’$id.’.html’;
if(file_exists($filename)){
include $filename;
exit;
}
$content = ob_get_contents();
file_put_contents($filename,$content);
7、真静态典型案例扩展
给生成的静态页面一个缓存周期,比如缓存5分钟,过了5分钟之后,则要重新生成静态页面。
比如缓存5分钟,300秒,
判断是否在缓存周期内,
文件的最后修改时间+缓存周期 > 当前的时间戳。
filemtime — 取得文件修改时间,返回的是时间戳。
if(file_exists($filename) && $filemtime($filename)+300>time()){
include $filename;
exit;
}
8、真静态优缺点说明:
优点: (1)速度快 (2)安全性高 (3)利于seo
缺点:就是占有磁盘空间., 如果过大,对磁盘响应速度有影响。
在什么情况下,建议不要使用真静态
(1)页面的数据更新频繁,最好不要使用真静态(比如股票,基金,等实时报价系统)
(2)会生成海量页面(比如大型论坛 bbs ,csdn)
(3)查询该页面一次后,以后再也不查询该页面.
(4)不愿意被搜索引擎抓取的页面.
(5)访问量小的页面.
七、伪静态
概述:在实际开发项目中,我们的页面不适合使用真静态,但是你不仅希望页面安全性高,同时利于seo,可以考虑使用伪静态技术。
伪静态:把一个动态的地址伪装成一个静态的地址。
比如:原来的访问地址是:http://www.abc.com/news.php?type=sport&id=2
改成http://www.abc.com/news-sport-id.html
1、实现方式
实现方式:利用web服务器的rewrite机制。
rewrite机制:将一个请求URL重写到另一个请求上!
在rewrite机制中,使用正则表达式来完成重写规则。
比如:
index.html 重写成 index.php
abc.php 重写成 123.php
news_sport_id12.html 重写成 news.php?type=sport&id=12
2、如何开启
找apache服务器的配置文件httpd.conf
LoadModule rewrite_module modules/mod_rewrite.so
3、具体配置:
三个指令:
RewriteEngine on 开启重写模块,
RewriteCond 重写条件
RewriteRule 重写规则。
(1)RewriteEngine on
重写引擎开关,一旦开启,所有的重写条件都生效。
(2)RewriteCond 重写条件,
当达到什么条件时,完成重写。
语法为:
RewriteCond 判断依据 条件表达式 [条件标志]
判断依据可以使用服务器变量。服务器可以得到一些特定信息
条件表达式,可以为如下形式:
正则或特殊标识
-f 表示是一个文件,!-f 不是文件
-d 表示是一个目录,!-d 不是目录
正则,正则表达式字符串。
条件标志:
[OR] 条件间的或者关系,当出现多个条件时,默认为并且的关系,条件应该是或者的关系下,可以使用OR来表示!
[NC]条件不区分大小写。条件匹配时不区分大小写
[OR,NC]
(3)RewriteRule :定义重写规则
RewriteRule :定义重写规则,哪个地址应该被重写到哪个目标地址。
语法:
RewriteRule匹配地址 目标地址 [标识]
匹配的地址:所请求的地址,可使用正则匹配
目标地址: 所重写到的地址,可以使用反向引用!$N表示正则匹配到的第N个子模式!
比如:RewriteRule goods-id(\d+)\.html goods.php?id=$1
标志:
[NC] 不区分大小写
[QSA] 查询字符串追加,在目标地址已经具有get参数时,会将真实请求的get参数追后边。
案例:当访问index.html页面时,重写到index.php页面
我们使用分布式文件配置来完成,.htaccess文件
步骤:
第一步:打开虚拟主机里面的配置,配置支持分布式配置。
第二步:在e:/amp/home目录下面新建一个.htaccess文件
通过编辑器另存为的方式建立.htaccess文件
第三步:在.htaccess文件里面进行具体的配置。
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule index.html index.php
</IfModule>
第四步:在网站的根目录下面,新建一个 index.php文件,进行测试
效果
4、入门案例
如果访问的文件存在,则访问该文件,若不存在,则执行重写:
比如:我们访问index.html 文件,如果 index.html文件存在,则访问该文件,如果该文件不存在,则重写到请求one.php页面。
我们使用分布式配置.htaccess文件:通过另存为新建一个.htaccess 文件。
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f [NC]
RewriteRule index.html index.php [NC]
5、新闻案例,配置成伪静态
注意点:把新闻的连接改成伪静态方式:
具体在.htaccess文件里面的配置
news-info-id(\d).html newsinfo.php?id=$1
newsinfo.php?id=$1里面的$1是一个反向引用,就是前面(\d)里面的内容;(\d)是谁,$1就表示谁,比如如下;
news-info-id4.html newsinfo.php?id=4
news-info-id5.html newsinfo.php?id=5
列表页面里面的内容:
.htaccess里面的配置;
效果如下;
6、使用rewrite机制完成防盗链。
(1)什么是盗链,
(2)如何防止被盗链:
第一:采用非技术手段,添加水印,添加自己公司的logo
第二:使用rewrite机制来,完成防盗链。
核心思路:判断请求的来源,在连接图片时,要判断是否本网站的页面来连接,如果是就允许连接,如果不是本网站则就拒绝。
如何判断是自己访问还是其他网站访问图片呢?
通过referer的头信息,该头信息记录了请求的来源。
其他域名网站访问图片资源:
自己网站的页面访问图片资源:
思路:判断referer头信息里面是否有自己的域名,如果有,则是自己访问,就允许访问,如果没有就拒绝访问。
配置代码:
RewriteEngine on
RewriteCond %{HTTP_REFERER} !www.demo.com
RewriteRule \.(gif|jpg|bmp)$ - [F]
其他域名网站访问效果如下;
可以给盗链的一个网站一个提示:
RewriteRule \.(gif|jpg|bmp)$ 110.gif
其他域名网站访问效果如下: