首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

WebSphere sMash 中 Java 與 PHP 整合實戰:打造 Lucene 全文搜尋引擎

     編輯:Java 相關知識

前言

WebSphere sMash(Project Zero)提供 Java Bridge,讓 PHP 腳本直接呼叫 Java 類別、存取欄位、處理例外與型別轉換。本文以 Apache Lucene 為例,示範用 PHP 撰寫索引與搜尋功能,並效能比較 Java Bridge、純 Java、Zend Search Lucene 三種實作。

核心功能展示

1. 建立並呼叫 Java 物件

<?php
$file = new Java("java.io.File", __FILE__, FALSE);
var_dump($file);
var_dump($file->isDirectory());
?>

輸出 Java 物件資訊與方法呼叫結果。

2. 使用 Java 集合類別

$map = new Java("java.util.HashMap");
$map->put("title", "Java Bridge!");
$array = array(1,2,3,4,5);
$map->put("stuff", $array);  // PHP 陣列自動轉為 Java Map
var_dump($map->get("stuff")); // 取回自動轉為 PHP 陣列

3. 迭代 Java 集合

$list = new Java("java.util.ArrayList");
$list->add("Java Bridge!");
$list->add(new Java("java.util.Date", 70, 9, 4));
$list->add(array(1,2,3,4,5));
$iter = $list->iterator();
while ($iter->hasNext() == TRUE) {
    var_dump($iter->next()); echo "<br/>";
}

4. 存取靜態方法與欄位

$sys = new JavaClass("java.lang.System");
echo "Current time: " . $sys->currentTimeMillis() . "<br/>";

$intClass = new JavaClass("java.lang.Integer");
var_dump($intClass->MIN_VALUE);

5. 捕獲 Java 例外

try {
    $sys = new JavaClass("java.lang.System");
    $sys->getProperty(FALSE);  // 錯誤參數型別
} catch (JavaException $e) {
    echo "Cause: " . $e->getCause();
}

6. 型別轉換對照表

Java 型別PHP 型別備註
nullnull
Integer/intint
Double/doubledouble
Boolean/booleanbool
Byte/byteint
Character/charint
Short/shortint
Long/longint
Float/floatdouble
byte[]string
Stringstring使用執行期編碼
Maparray遞迴轉換巢狀 Map
Object[]array
其他Java Bridge Wrapper通用 PHP 物件包裝

實戰:PHP + Lucene 建立搜尋引擎

環境準備

  1. 下載 lucene-2.2.0.tar.gz,解壓取出 lucene-core-2.2.0.jar、lucene-demos-2.2.0.jar。
  2. 建立 sMash PHP 專案 Lucene,將 JAR 放入 lib/ 目錄。
  3. 右鍵專案 WebSphere sMash Tools → Resolve 載入類別路徑。

索引頁面 index.php

表單輸入目錄與副檔名,送出後遞迴索引符合條件檔案:

function index_directory($path, $extension) {
    $analyser = new Java("org.apache.lucene.analysis.SimpleAnalyzer");
    $policy = new Java("org.apache.lucene.index.KeepOnlyLastCommitDeletionPolicy");
    $dir = new JavaClass("org.apache.lucene.store.FSDirectory")
            ->getDirectory(new Java("java.io.File", INDEX_DIRECTORY, FALSE));
    $writer = new Java("org.apache.lucene.index.IndexWriter",
            $dir, TRUE, $analyser, TRUE, $policy);
    $writer->setUseCompoundFile(FALSE);
    $start = microtime(true);
    recursive_index_directory($writer, $path, $extension);
    $writer->setMaxFieldLength(1000000);
    $writer->optimize();
    $writer->close();
    echo "Indexed " . $writer->docCount() . " docs in " . (microtime(true)-$start) . "s";
}

function recursive_index_directory($writer, $path, $ext) {
    $handle = opendir($path);
    while (($item = readdir($handle)) !== FALSE) {
        if ($item=='.' || $item=='..') continue;
        $full = "$path/$item";
        if (is_dir($full)) recursive_index_directory($writer, $full, $ext);
        elseif (substr(strtolower($full), -strlen($ext)) === $ext)
            index_file($writer, $full);
    }
    closedir($handle);
}

function index_file($writer, $path) {
    try {
        $doc = new JavaClass("org.apache.lucene.demo.FileDocument")
                ->Document(new Java("java.io.File", $path, FALSE));
        $writer->addDocument($doc);
    } catch (JavaException $e) { echo "Skip non-UTF8: $path"; }
}

搜尋頁面 search.php

function search_index($indexDir, $queryStr) {
    $searcher = new Java("org.apache.lucene.search.IndexSearcher",
            new JavaClass("org.apache.lucene.store.FSDirectory")
                ->getDirectory(new Java("java.io.File", $indexDir, FALSE)));
    $parser = new Java("org.apache.lucene.queryParser.QueryParser",
            "contents", new Java("org.apache.lucene.analysis.SimpleAnalyzer"));
    $query = $parser->parse($queryStr);
    $hits = $searcher->search($query);
    for ($i=0; $i<$hits->length(); $i++) {
        echo "$i) " . $hits->doc($i)->get("path") . "<br/>";
    }
    echo "Total hits: " . $hits->length();
}

效能比較(索引 PHP 5.3 測試腳本 *.phpt)

技術耗時 (秒)
WebSphere sMash Java Bridge9
純 Java Lucene8
Zend Search Lucene (PHP)200

Java Bridge 僅比純 Java 慢 ~12%,證明 PHP 執行期與 JVM 互動開銷極低。Zend 純 PHP 實作雖慢但無需 Java 環境,適合純 PHP 專案。

Java Bridge 限制與進階技巧

  • 多載方法選擇:預設依參數個數匹配,若同參數個數多載會取第一個。新版 JavaSignature 可指定參數型別精確選擇多載:
$sig = new JavaSignature(JAVA_STRING);
$str = new Java("java.lang.String", $sig, "Hello World!");
var_dump($str->toLowerCase());
  • 方法名稱大小寫敏感:PHP 不分大小寫,Java Bridge 強制大小寫匹配。
  • 靜態成員需透過 JavaClass:無法直接用類名存取。
  • 集合迭代冗長:未整合 PHP foreach,需手動 iterator() + while。

結語

Java Bridge 讓 PHP 專案以極低成本重用成熟 Java 函式庫(Lucene、POI、iText 等)。效能接近原生 Java,開發效率兼具 PHP 簡潔與 Java 強大生態。建議在需要高效能演算法、現有 Java 資產重用的場景採用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved