[太麻烦了]用PHP调用Lucene包来实现全文检索
| December 17, 2006 18:18 | root | Via 本站原创
/*转贴请保留以下信息*/
作者:张杰
URL:http://spaces.msn.com/memb...
http://www.phpboom.com/
由于工作需要,需要使用PHP实现对网站内大量数量进行全文检索,
而且目前最流行的全文检索的搜索引擎库就是Lucene了,
它是Apache Jakarta的一个子项目,并且提供了简单实用的API,
用这些API,就可以对任何基本文本的数据(包括数据库)进行全文检索。
因为PHP本身就支持调用外部Java类,所以先用Java写了一个类,
这个类通过调用Lucene的API,实现了两个方法:
* public String createIndex(String indexDir_path,String dataDir_path)
* public String searchword(String ss,String index_path)
其中createIndex是创建索引方法,
传入了两个参数分别是indexDir_path(索引文件的目录),dataDir_path(被索引的文件目录),返回被索引的文件列表字符串,
另一个是searchword,通过传入的关键字参数(ss)对索引进行检索,index_path就是索引文件的目录。返回所有检索到的文件。
这里是源代码,很简单,大家可以参考一下:TxtFileIndexer.java
而PHP程序就调用这两个方法,实现对Lucene的调用,从而达到全文检索的目的。
PHP的调用方法如下:
先创建一个我们写的TxtFileIndexer类的实例,
$tf = new Java('TestLucene.TxtFileIndexer');
然后就按正常PHP类的调用方法的方式进行调用,首先创建索引:
$data_path = "F:/test/php_lucene/htdocs/data/manual"; //定义被索引内容的目录
$index_path = "F:/test/php_lucene/htdocs/data/search"; //定义生成的索引文件存放目录
$s = $tf->createIndex($index_path,$data_path); //调用Java类的方法
print $s; //打印返回的结果
这次再试试检索:
$index_path = "F:/test/php_lucene/htdocs/data/search"; //定义生成的索引文件存放目录
$s = $tf->searchword("here is keyword for search",$index_path);
print $s;
另外要注意Java类的路径,可以在PHP里设置
java_require("F:/test/php_lucene/htdocs/lib/"); //这是个例子,我的类和Lucene都放到这个目录下
这样就可以了,是不是很简单。
PHP源代码:test.php
接下来我把环境配置说一下,
首先需要有Java SDK,是必须的,我使用的是1.4.2版的,其它版本应该也没问题。
PHP5,试过PHP4,应该可以。
由于PHP5带的Java扩展没调通,并且以前用过调用Java效率很低,很慢,所以使用了 Php/Java Bridge 这个项目。
1.下载JavaBridge
URL:http://sourceforge.net/pro...
目前版本是
php-java-bridge_3.0.8_j2ee.zip
解包后把
JavaBridge\WEB-INF\cgi\java-x86-windows.dll
JavaBridge\WEB-INF\lib\JavaBridge.jar
复制到 c:\php\ext 目录下,并把
java-x86-windows.dll 改名为 php_java.dll
2.修改php.ini(例)
extension=php_java.dll
[Java]
java.class.path = "C:\php\ext\JavaBridge.jar;F:\test\php_lucene\htdocs"
java.java_home = "C:\j2sdk1.4.2_10"
java.library.path = "c:\php\ext;F:\test\php_lucene\htdocs"
3.重启Apache即可。
4.可以找一些文件进行索引
在test.php里可以修改索引文件和数据文件的路径。
TxtFileIndexer.java的37行限制了只索引html后缀的文件,有需要也可以修改。
根据目前的情况(JavaBridge支持Linux和Freebsd),完全可以在
linux或freebsd/apache2/php4/lucene/JavaBridge
环境下运行。
本文章可能会随时更新,另外这里可以访问:
用PHP调用Lucene包来实现全文检索
我的MSN是 z33
欢迎技术探讨:)
[Java问题]关于包的概念的实践理解。。。。
| December 14, 2006 19:17 | root | Via 本站原创
package test;
public class Vector{
public Vector(){
System.out.println(
"my.Vector");
}
}
在C:\DOC下有一个TEST目录,生成Vector.class 。Vector.java和Vector.class都置于TEST
目录内。
然后我再编译下面的语句:
import test.*;
public class LibTest{
public static void main(String[] args){
Vector v=new Vector();
}
}
则出现如现错误:
C:\DOC\TEST javac LibTest.java
LibTest.java:5: cannot access Vector
bad class file: .\Vector.class
class file contains wrong class: test.Vector
Please remove or make sure it appears in the correct subdirectory of the classpa
th.
Vector l=new Vector();
^
1 error
然而我把import test.*;改为import.Vector;则能成功编译。望各位大虾帮忙解决。
在CLASSPATH中加上.;.代表当前目录,如果不加,编译器在编译LibTest.java时,找test包就不会在当前目录内找,因为找不到,加上就可以了。
加上也不行啊。早就加了。就是不行。
classpath=.;C:\DOC
本人解决方法:
注意目录结构
作为package, test.java 应放C;\doc\test目录中
Libtest.java放在c:\doc下,
classpath设为".;c:\doc\;"
然后
1. c:\doc>javac test\*.java
2. c:\doc>javac *.java
3. c:\doc>java Libtest //ok
D:\Javawork\jt>javac LibTest.java
LibTest.java:4: cannot access Vector
bad class file: .\Vector.java
file does not contain class Vector
Please remove or make sure it appears in the correct subdirectory of the classpa
th.
Vector v = new Vector();
^
1 error
(你的文件没有问题,主要是你的classpath里面有了test目录的java文件。。。)
出现这个问题,你要注意各个文件放的目录,千万不要在不同的目录里面里面有重复的文件。。。。
千万要注意编译顺序啊。。。
不知道说清楚了没有。。。。。要是看到我操作就好了。,。
[Ajax代码]用PHP实现简单的无刷新搜索
| December 14, 2006 11:17 | root | Via 本站原创

testme.html
code:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />
<title>
ajax
</title>
<script language="javascript">
function createRequest(){
if(typeof XMLHttpRequest!="undefined") {
return new XMLHttpRequest();
}else if(typeof ActiveXObject!="undefined"){
var xmlHttp_ver = false;
var xmlHttp_vers = ["MSXML2.XmlHttp.5.0","MSXML2.XmlHttp.4.0","MSXML2.XmlHttp.3.0","MSXML2.XmlHttp","Microsoft.XmlHttp"];
if(!xmlHttp_ver){
for(var i=0;i<xmlHttp_vers.length;i++){
try{
new ActiveXObject(xmlHttp_vers[i]);
xmlHttp_ver = xmlHttp_vers[i];
break;
}catch(oError){;}
}
}
if(xmlHttp_ver){
return new ActiveXObject(xmlHttp_ver);
}else{
throw new Error("Could not create XML HTTP Request.");
}
}else{
throw new Error("Your browser doesn't support an XML HTTP Request.");
}
}
var xmlHttp;
function sendPostRequest()
{
xmlHttp = createRequest();
var shownum=document.getElementById("shownum").value;// html页面中一个id为shownum的input表单
var url = "http://localhost/phpwork/p...要发送到的URL
var queryString = "shownum" + "=" + shownum;
//向服务端发送请求
xmlHttp.open("post", url, true);//这里的第三个参数为true为异步方式处理
xmlHttp.onreadystatechange = showData;//异步方式处理,当状态改变时会调用onreadystatechange属性指定的回调函数showData
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");//这一句是用post方法发送的时候必须写的
xmlHttp.send(queryString);//发送你构建成的数据,如果为“get”方法时,这里可以写成xmlHttp.send(NULL);
}
function showData()
{
var msg=document.getElementById("status");
//第4步
if(xmlHttp.readyState==4)
{
if(xmlHttp.status==200)
{
//只有当readyState为4并且status为200时,才表示符合要求
//下面这一句话,就相当于上面说的第5步,处理返回的结果
msg.innerHTML = xmlHttp.responseText;
}
}
else
{
switch(xmlHttp.readyState)
{
case 0:
msg.innerHTML="未初始化...";
break;
case 1:
msg.innerHTML="加载中...";
break;
case 2:
msg.innerHTML="连接完成...";
break;
case 3:
msg.innerHTML="交换数据...";
break;
default:
break;
}
}
}
</script>
</head>
<body>
<div>要发送的数据:<input name="shownum" type="text" id="shownum" value="root">
<input type="button" name="search" value="发送" onClick="sendPostRequest()">
(输入root,xdy108)</div>
<div id="status"></div>
</body>
</html>
phpajaxtest.php
code:
<?php require_once('Connections/conn.php'); ?>
<?php
$colname_Recordset1 = "-1";
if (isset($_POST['shownum'])) {
$colname_Recordset1 = (get_magic_quotes_gpc()) ? $_POST['shownum'] : addslashes($_POST['shownum']);
}
mysql_select_db($database_conn, $conn);
$query_Recordset1 = sprintf("SELECT `Host`, `User`, Password, Select_priv FROM `user` WHERE `User` = '%s'", $colname_Recordset1);
$Recordset1 = mysql_query($query_Recordset1, $conn) or die(mysql_error());
$row_Recordset1 = mysql_fetch_assoc($Recordset1);
$totalRows_Recordset1 = mysql_num_rows($Recordset1);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml...
<html xmlns="http://www.w3.org/1999/xht...
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>无标题文档</title>
</head>
<body>
<table border="1">
<tr>
<td>Host</td>
<td>User</td>
<td>Password</td>
<td>Select_priv</td>
</tr>
<?php do { ?>
<tr>
<td><?php echo $row_Recordset1['Host']; ?></td>
<td><?php echo $row_Recordset1['User']; ?></td>
<td><?php echo $row_Recordset1['Password']; ?></td>
<td><?php echo $row_Recordset1['Select_priv']; ?></td>
</tr>
<?php } while ($row_Recordset1 = mysql_fetch_assoc($Recordset1)); ?>
</table>
</body>
</html>
<?php
mysql_free_result($Recordset1);
?>
conn.php
code:
<?php
# FileName="Connection_php_mysql.htm"
# Type="MYSQL"
# HTTP="true"
$hostname_conn = "localhost";
$database_conn = "mysql";
$username_conn = "root";
$password_conn = "12345";
$conn = mysql_pconnect($hostname_conn, $username_conn, $password_conn) or trigger_error(mysql_error(),E_USER_ERROR);
?>
user.sql
code:
# phpMyAdmin SQL Dump
# version 2.5.7
# http://www.phpmyadmin.net
#
# 主机: localhost
# 生成日期: 2006 年 12 月 13 日 05:58
# 服务器版本: 5.0.19
# PHP 版本: 5.1.2
#
# 数据库 : `mysql`
#
# --------------------------------------------------------
#
# 表的结构 `user`
#
CREATE TABLE `user` (
`Host` char(60) collate utf8_bin NOT NULL default '',
`User` char(16) collate utf8_bin NOT NULL default '',
`Password` char(41) character set latin1 collate latin1_bin NOT NULL default '',
`Select_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Insert_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Update_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Delete_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Create_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Drop_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Reload_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Shutdown_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Process_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`File_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Grant_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`References_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Index_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Alter_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Show_db_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Super_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Create_tmp_table_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Lock_tables_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Execute_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Repl_slave_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Repl_client_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Create_view_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Show_view_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Create_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Alter_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Create_user_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`ssl_type` enum('','ANY','X509','SPECIFIED') character set utf8 NOT NULL default '',
`ssl_cipher` blob NOT NULL,
`x509_issuer` blob NOT NULL,
`x509_subject` blob NOT NULL,
`max_questions` int(11) unsigned NOT NULL default '0',
`max_updates` int(11) unsigned NOT NULL default '0',
`max_connections` int(11) unsigned NOT NULL default '0',
`max_user_connections` int(11) unsigned NOT NULL default '0',
PRIMARY KEY (`Host`,`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges';
#
# 导出表中的数据 `user`
#
INSERT INTO `user` VALUES ('localhost', 'root', '*00A51F3F48415C7D4E8908980D443C29C69B60C9', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', '', '', '', 0, 0, 0, 0);
INSERT INTO `user` VALUES ('localhost', 'xdy108', '001002', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', '', '', '', '', 0, 0, 0, 0);
发现输入xdy108,root的时候能无刷新返回,否则如xdy,ro等就会无返回结果,其原因是用了:WHERE `User` = '%s'", $colname_Recordset1);没有用like.
如下图:
[Mysql_java]用桥连的方法即JDBC:ODBC连接mysql
| December 14, 2006 10:55 | root | Via 本站原创
code:
import java.sql.*;
public class MysqlConn {
static{
try {
Class .forName("sun.jdbc.odbc.JdbcOdbcDriver");
System.out.print("Sucess loading JDBC_ODBC Bridge Drive...");
}
catch (Exception e){
System.out.print("Erro loading JDBC-ODBC Bridge Driver...\n");
e.printStackTrace();
}
}
public static void main(String[] args) {
try{
Connection con1=DriverManager.getConnection("jdbc:odbc:choa_samples","root","12345");
}
catch(SQLException e){
e.printStackTrace();
}
}
}
[网站出错]关于一个本站博客错误问题的深刻反思
| December 5, 2006 17:28 | root | Via 本站原创
Script: /blog/index.php
SQL: SELECT * FROM `boblog_blogs` WHERE `property`<>'3' ORDER BY `sticky`DESC, `pubtime` DESC LIMIT 0,
Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
Errno.: 1064
搞得我郁闷死了,竟然发现有人说是boblog_blogs的表出现错误,我把所有的表都修复了,然后还是不对,然后再用google搜索,然后我发现好像不行,访问不了,然后我就用baidu看了一下,发现使我感到很郁闷。。。
饭后想不通,然后继续baidu,最后我发现bo-blog里面有如下问题。。。
解决方法也很简单:
将安装包内install\copy下的mod_config文件上传覆盖FTP里/data目录下的同名文件即可恢复,(最好是将mod_config.php del掉然后呢,就弄ftp上去,我是这样弄得。。。)




