做个自己站内搜索引擎


Posted in PHP onOctober 09, 2006

ccterran(原作)

作者:iwind

  朋友用dreamweaver做了一个网站,没有动态的内容,只是一些个人收藏的文章,个人介绍等等。现在内容比较多了,想叫我帮他做一个搜索引擎。说实在的,这是一个不难的问题,于是就随手做了一个。现在我在其它论坛上也看到有人想做这个,于是就想说说这方面的知识,重在了解一下方法。

写程序前先要想好一个思路,下面是我的思路,可能谁有更好的,但注意这只是一个方法问题 :遍历所有文件  读取内容  搜索关键字,如果匹配就放入一个数组  读数组。在实现这些步骤之前,我假定你的网页都是标准的,就是有标题(<title></title>),也有(<bod *></body>),如果你是用dreamweaver或者frontpage设计的,那么除非你故意删掉,它们都在存在的。下面就让我们一步步来完成并在工程中改善这个搜索引擎。

一,设计搜索表单
在网站的根目录下建个search.htm,内容如下
<html>
<head>
<title>搜索表单</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>

<body bgcolor="#FFFFFF" text="#000000">
<form name="form1" method="post" action="search.php">
  <table width="100%" cellspacing="0" cellpadding="0">
    <tr>
      <td width="36%">
        <div align="center">
          <input type="text" name="keyword">
        </div>
      </td>
      <td width="64%">
        <input type="submit" name="Submit" value="搜索">
      </td>
    </tr>
  </table>
</form>
</body>
</html>

二,搜索程序
再在根目录下建个search.php 的文件,用来处理search.htm表单传过来的数据.内容如下
<?php
//获取搜索关键字
$keyword=trim($_POST[“keyword”]);
//检查是否为空
if($keyword==””){
   echo”您要搜索的关键字不能为空”;
   exit;//结束程序
}
?>

这样如果访问者输入的关键字为空时,可以做出提示。下面是遍历所有文件。

我们可以用递归的方法遍历所有的文件,可以用函数opendir,readdir,也可以用PHP Directory的类。我们现在用前者.
<?php
  //遍历所有文件的函数
  function listFiles($dir){
   $handle=opendir($dir);
   while(false!==($file=readdir($handle))){
          if($file!="."&&$file!=".."){
          //如果是目录就继续搜索
          if(is_dir("$dir/$file")){
             listFiles("$dir/$file");
          }
              else{
            //在这里进行处理
             }
      }
   }
}

?>

在红字的地方我们可以对搜索到的文件进行读取,处理.下面就是读取文件内容,并检查内容中是否含有关键字$keyword,如果含有就把文件地址赋给一个数组。
<?php
//$dir是搜索的目录,$keyword是搜索的关键字 ,$array是存放的数组
function listFiles($dir,$keyword,&$array){
   $handle=opendir($dir);
   while(false!==($file=readdir($handle))){
          if($file!="."&&$file!=".."){
          if(is_dir("$dir/$file")){
             listFiles("$dir/$file",$keyword,$array);
          }
              else{
            //读取文件内容
            $data=fread(fopen("$dir/$file","r"),filesize("$dir/$file"));
            //不搜索自身
            if($file!=”search.php”){
              //是否匹配
                          if(eregi("$keyword",$data)){
                  $array[]="$dir/$file";
                          }
            }
             }
      }
   }
}
//定义数组$array
$array=array();
//执行函数
listFiles(".","php",$array);
//打印搜索结果
foreach($array as $value){
   echo "$value"."<br>\n";
}
?>

现在把这个结果和开头的一段程序结合起来,输入一个关键字,然后就会发现你的网站中的相关结果都被搜索出来了。我们现在在把它完善一下。
1,列出内容的标题

                          if(eregi("$keyword",$data)){
                  $array[]="$dir/$file";
                          }
改成
                          if(eregi("$keyword",$data)){
                                   if(eregi("<title>(.+)</title>",$data,$m)){
                        $title=$m["1"];
                                   }
                                   else{
                        $title="没有标题";
                                   }
                                   $array[]="$dir/$file $title";
                           }
原理就是,如果在文件内容中找到<title>xxx</title>,那么就把xxx取出来作为标题,如果找不到那么就把标题命名未”没有标题”.

2,只搜索网页的内容的主题部分。
做网页时一定会有很多html代码在里面,而这些都不是我们想要搜索的,所以要去除它们。我现在用正则表达式和strip_tags的配合,并不能把所有的都去掉。

            $data=fread(fopen("$dir/$file","r"),filesize("$dir/$file"));
            //不搜索自身
            if($file!=”search.php”){
              //是否匹配
                          if(eregi("$keyword",$data)){
改为
$data=fread(fopen("$dir/$file","r"),filesize("$dir/$file"));
           if(eregi("<body([^>]+)>(.+)</body>",$data,$b)){
                 $body=strip_tags($b["2"]);
                        }
                        else{
                 $body=strip_tags($data);
                        }
                        if($file!="search.php"){
                            if(eregi("$keyword",$body)){

3,标题上加链接
foreach($array as $value){
   echo "$value"."<br>\n";
}
改成
foreach($array as $value){
   //拆开
   list($filedir,$title)=split(“[ ]”,$value,”2”);
   //输出
   echo "<a href=$filedir>$value</a>"."<br>\n";
}
4防止超时
如果文件比较多,那么防止PHP执行时间超时是必要的。可以在文件头加上
set_time_limit(“600”);
以秒为单位,所以上面是设10分钟为限。

所以完整的程序就是
<?php
set_time_limit("600");
//获取搜索关键字
$keyword=trim($_POST["keyword"]);
//检查是否为空
if($keyword==""){
   echo"您要搜索的关键字不能为空";
   exit;//结束程序
}
function listFiles($dir,$keyword,&$array){
   $handle=opendir($dir);
   while(false!==($file=readdir($handle))){
          if($file!="."&&$file!=".."){
          if(is_dir("$dir/$file")){
             listFiles("$dir/$file",$keyword,$array);
          }
              else{
            $data=fread(fopen("$dir/$file","r"),filesize("$dir/$file"));
                        if(eregi("<body([^>]+)>(.+)</body>",$data,$b)){
                 $body=strip_tags($b["2"]);
                        }
                        else{
                 $body=strip_tags($data);
                        }
                        if($file!="search.php"){
                            if(eregi("$keyword",$body)){
                                   if(eregi("<title>(.+)</title>",$data,$m)){
                        $title=$m["1"];
                                   }
                                   else{
                        $title="没有标题";
                                   }
                                   $array[]="$dir/$file $title";
                            }
                        }
             }
      }
   }
}
$array=array();
listFiles(".","$keyword",$array);
foreach($array as $value){
   //拆开
   list($filedir,$title)=split("[ ]",$value,"2");
   //输出
   echo "<a href=$filedir target=_blank>$title </a>"."<br>\n";
}
?>

到此为止,你已经做好了自己的一个搜索引擎,你也可以通过修改内容处理部分来改进它,可以实现搜索标题,或者搜索内容的功能。也可以考虑分页。这些都留给你自己吧。

这里说明一下用preg_match代替eregi,会快很多。这里只是为了通俗易懂,所以使用了常用的eregi.

 

PHP 相关文章推荐
用PHP将数据导入到Foxmail
Oct 09 PHP
超小PHP小马小结(方便查找后门的朋友)
May 05 PHP
很让人受教的 提高php代码质量36计
Sep 05 PHP
基于HBase Thrift接口的一些使用问题及相关注意事项的详解
Jun 03 PHP
PHP5常用函数列表(分享)
Jun 07 PHP
PHP中使用imagick生成PSD文件缩略图教程
Jan 26 PHP
php浏览历史记录的方法
Mar 10 PHP
大家在抢红包,程序员在研究红包算法
Aug 31 PHP
详解PHP的Yii框架中自带的前端资源包的使用
Mar 31 PHP
ECSHOP完美解决Deprecated: preg_replace()报错的问题
May 17 PHP
PHP面向对象之领域模型+数据映射器实例(分析)
Jun 21 PHP
php设计模式之中介者模式分析【星际争霸游戏案例】
Mar 23 PHP
用libTemplate实现静态网页的生成
Oct 09 #PHP
php注入实例
Oct 09 #PHP
967 个函式
Oct 09 #PHP
如何给phpadmin一个保护
Oct 09 #PHP
Search Engine Friendly的URL设计
Oct 09 #PHP
PHPlet在Windows下的安装
Oct 09 #PHP
一棵php的类树(支持无限分类)
Oct 09 #PHP
You might like
迅速确定php多维数组的深度的方法
2014/01/07 PHP
浅谈PHP中静态方法和非静态方法的相互调用
2016/10/04 PHP
jquery 简单图片导航插件jquery.imgNav.js
2010/03/17 Javascript
JavaScript 匿名函数(anonymous function)与闭包(closure)
2011/10/04 Javascript
JavaScript高级程序设计 阅读笔记(四) ECMAScript中的类型转换
2012/02/27 Javascript
网页下载文件期间如何防止用户对网页进行其他操作
2014/06/27 Javascript
JS实现仿京东淘宝竖排二级导航
2014/12/08 Javascript
JavaScript判断一个字符串是否包含指定子字符串的方法
2015/03/18 Javascript
基于JQuery实现的跑马灯效果(文字无缝向上翻动)
2016/12/02 Javascript
js图片轮播手动切换特效
2017/01/12 Javascript
AngularJS ng-repeat指令中使用track by子语句解决重复数据遍历错误问题
2017/01/21 Javascript
微信小程序实现下拉刷新和轮播图效果
2017/11/21 Javascript
javascript中的replace函数(带注释demo)
2018/01/07 Javascript
原生JavaScript实现remove()和recover()功能示例
2018/07/24 Javascript
Vue.js 实现数据展示全部和收起功能
2018/09/05 Javascript
微信小程序购物车、父子组件传值及calc的注意事项总结
2018/11/14 Javascript
Vue指令指令大全
2019/02/09 Javascript
少女风vue组件库的制作全过程
2019/05/15 Javascript
了解重排与重绘
2019/05/29 Javascript
在pycharm中开发vue的方法步骤
2020/03/04 Javascript
[01:14:55]EG vs Spirit Supermajor 败者组 BO3 第三场 6.4
2018/06/05 DOTA
利用Python读取文件的四种不同方法比对
2017/05/18 Python
Python基于递归算法实现的走迷宫问题
2017/08/04 Python
flask框架jinja2模板与模板继承实例分析
2019/08/01 Python
python实现将range()函数生成的数字存储在一个列表中
2020/04/02 Python
美国折扣宠物药房:Total Pet Supply
2018/05/27 全球购物
美国肌肉和力量商店:Muscle & Strength
2019/06/22 全球购物
伦敦新晋轻奢耳饰潮牌:Tada & Toy
2020/05/25 全球购物
线程的基本概念、线程的基本状态以及状态之间的关系
2012/10/26 面试题
五年级数学教学反思
2014/02/11 职场文书
会员卡清退活动总结
2014/08/27 职场文书
大学生实习证明范本
2014/09/19 职场文书
单位授权委托书范本
2014/09/26 职场文书
2015年教师节慰问信
2015/03/23 职场文书
项目经理助理岗位职责
2015/04/13 职场文书
2015年度团总支工作总结
2015/04/23 职场文书