PHP 真的是一種非常方便的語言,其支援的龐大函式庫,可以讓人很輕鬆自在的使用許多實用的函數。其中常用的 nl2br()htmlspecialchars() 在 HTML 顯示的時候很常使用,但是 JavaScript 就沒有提供類似方便使用的函數了;因為某些原因要在前端使用這二個函數,稍微 google 了一下馬上發現有前輩已經寫出來囉!在此作個紀錄並分享給有需要的人:(來源:Replace newlines with BR (platform safe)Javascript 的 htmlspecialchars function 與 htmlspecialchars_decode function,感謝網路上的前輩們^^)
// javascript 版本的 nl2br
var nl2br = function (string) {
string = escape(string);
if (string.indexOf('%0D%0A') > -1) {
var re_nlchar = /%0D%0A/g ;
} else if (string.indexOf('%0A') > -1) {
var re_nlchar = /%0A/g ;
} else if (string.indexOf('%0D') > -1) {
var re_nlchar = /%0D/g ;
}
return unescape(string.replace(re_nlchar, '<br />'));
}

// javascript 版本的 htmlspecialchars
var htmlspecialchars = function (string, quote_style) {
string = string.toString();

string = string.replace(/&/g, '&amp;');
string = string.replace(/</g, '&lt;');
string = string.replace(/>/g, '&gt;');

if (quote_style == 'ENT_QUOTES') {
string = string.replace(/"/g, '&quot;');
string = string.replace(/\'/g, '&#039;');
} else if (quote_style != 'ENT_NOQUOTES') {
string = string.replace(/"/g, '&quot;');
}

return string;
}
文章標籤

danielhuang030 發表在 痞客邦 留言(0) 人氣()

一般在使用 ZendFrameworkZend_Db_Table_Rowset fetchAll() 時,都是需要 Rowset 裡面全部的資料;不過偶爾有會有只需要單筆資料列的情況,這個時候就可以藉助 current() 或是 getRow() 取得單筆資料列。

current() 很單純,就是目前 Rowset 中指向的資料列,通常在沒有指定指標的情況下,就是該 Rowset 中的第一筆資料:
$table = new Table();
$select = $table->select();
$rowset = $table->fetchAll($select);
$row = $rowset->current();
// 這裡的 $row 就會是 $rowset 的第一筆資料列。
getRow() 就比較有彈性,它可以指定取得第幾個資料列,並決定是不是要將指標移至該資料列(預設為不指定)。
getRow($position, $seek = false) 
// $position 設定取得第幾列資料(從 0 開始)
// $seek 設定是否要將指標移至該資料列(預設為不指定)
用法如下:
$table = new Table();
$select = $table->select();
$rowset = $table->fetchAll($select);
$row = $rowset->getRow(1);
// 這裡的 $row 就會是 $rowset 的第二筆資料列。
要比較注意的是 $seek 的使用時機,是否有需要移動指標,就看程式的需求囉;使用後呈現的資料,如以下的例子:
$table = new Table();
$select = $table->select();
$rowset = $table->fetchAll($select);
$row = $rowset->current();
// 這裡的 $row 就會是 $rowset 的第一筆資料列。

$row = $rowset->getRow(1);
// 這裡的 $row 就會是 $rowset 的第二筆資料列($seek 預設為 false,故指標不移動)。

$row = $rowset->current();
// 這裡的 $row 還是 $rowset 的第一筆資料列。

$row = $rowset->getRow(1, true);
// 這裡的 $row 就會是 $rowset 的第二筆資料列($seek 設為 true,故指標移動)。

$row = $rowset->current();
// 這裡的 $row 就會變成是 $rowset 的第二筆資料列。
大概就是這樣;在這邊做個紀錄,感謝 Jace 解惑^^
文章標籤

danielhuang030 發表在 痞客邦 留言(0) 人氣()

在撰寫網頁程式的時候,除了程式的撰寫以外,最花時間的部分大概就是版型的套用吧。有經驗的網頁美工設計師會利用 CSS 進行網站版面的配置,CSS 的運用對網頁程式設計師來說會比較親切;但是對大部分習慣以 Dreamwaver 為開發工具的網頁美工設計師來說,表格 table 的運用似乎比較心應手。雖然說如果一個簡單的網頁設計要從無到有,我也會比較傾向使用表格;但是對於複雜的網頁樣板來說,巢狀的表格真的是會讓人眼花撩亂啊...(噗)

其實以上都是閒聊...(汗)今天碰到的問題是在 Firefox 上看版面沒有問題,但是 IE 上卻發生表格被圖片撐開的情況。在全是表格的網頁上,被撐開的圖片斷層殘破不堪,實在非常有礙觀瞻;雖然大家都知道 IE 對網頁標準支援非常的不完全(wiki 寫的很含蓄:「只是有一些排版錯誤」),不過對於大部分的人來說,IE 幾乎就是瀏覽器的代名詞,所以既然有問題就還是得解決...

因為小弟經驗不足,找了半天還是找不出解決方法~後來經由 Abu 的幫忙,總算是用 CSS 解決問題囉!會發生圖片斷層的原因主要是因為圖片大小超過表單的大小,雖然我明明就把表格的高度與圖片的高度設定的一模一樣,但是好樣的 IE 就是會判斷錯誤,造成圖片斷層的問題。這個時候只要在 <img> 中加入 CSS:

<img style="float: left;" src="/sample.jpg" alt="測試圖片"/>

原本歪七扭八,七零八落的圖片就能完全契合於表格中囉!真是比吃滷肉飯還簡單哩~謝謝 Abu!
文章標籤

danielhuang030 發表在 痞客邦 留言(4) 人氣()

在多重下拉式選單的應用中,常常也會遇到已經有預設值的時候,這時候該怎麼辦呢?其實前陣子我也遇過這個問題,當初還花了一點時間尋找 jQuery的cascade 是不是有提供參數讓我輕鬆預設;不過拜完 Google 大神之後似乎是沒有什麼線索;所以最後我採用了一個很笨的方法,在頁面讀取完畢時如果有預設值的話,就直接丟一個 Ajax 取得第二層的選項。以下是實作的程式碼:(目前我只實作到二階層)

index.php:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.cascade.js"></script>
<script type="text/javascript" src="jquery.cascade.ext.js"></script>
<script type="text/javascript" src="jquery.templating.js"></script>
</head>
<body>
第一項 <select id="myParentSelect">
<option value="">請選擇</option>
<?php
    // 資料庫設定
    $host_sql = "localhost";
    $username_sql = "username";
    $password_sql = "password";

    // 預設值設定
    $defaultParentId = '3';
    $defaultChildId = '13';


    $link = mysql_connect($host_sql, $username_sql, $password_sql) or die("無法連結資料庫");
    mysql_select_db('target', $link);
    mysql_query("SET NAMES UTF8");

    $query = "SELECT id, name FROM table where lv = 1";
    $result = mysql_query($query, $link);
    while ($row = mysql_fetch_assoc($result)) {
        echo '<option value="' . $row["id"] . '">' . $row["name"] . '</option>' . "\n";
    }

?>
</select>

<!-- 設定一個隱藏的欄位紀錄預設值 -->
<input type="hidden" name="defaultParentId" value="<?php echo $defaultParentId; ?>" />
<input type="hidden" name="defaultChildId" value="<?php echo $defaultChildId; ?>" />

 
第二項 <select id="myChildSelect">
<option value="">請選擇</option>
</select>

<script type="text/javascript">

// 如果已有預設值,即時送出 Ajax 呼叫
function getSelectedList(defaultParentId, defaultFirstChildId) {
    $.ajax({
        type: "get",
        url:  'action.php',
        data: { act: 'default', val: defaultParentId, child: defaultFirstChildId },
        dataType: "json",
        success: function (json) {
            $('select#myChildSelect').append(json.data);
        }
    });
};


$(function () {

    // 檢查是否有預設值
    if ($('input[name=defaultParentId]').val()) {
        getSelectedList ($('input[name=defaultParentId]').val(), $('input[name=defaultChildId]').val());
    }


    // 第一階層對應第二階層
    $('#myChildSelect').cascade('#myParentSelect', {
    ajax: {
        type: "post",
        url:  'action.php',
        data: { act: 'first', val: $('#myParentSelect').val() },
        dataType: "json",
    },
    template: function(item) { return "<option value='" + item.Value + "'>" + item.Text + "</option>"; },
    match: function(selectedValue) { return this.When == selectedValue; }
    });
});
</script>
</body>
</html>

action.php:

<?php

// 資料庫設定
$host_sql = "localhost";
$username_sql = "username";
$password_sql = "password";

$link = mysql_connect($host_sql, $username_sql, $password_sql) or die("無法連結資料庫");
mysql_select_db('target', $link);
mysql_query("SET NAMES UTF8");

if (!empty($_GET['act'])) {
    $action = $_GET['act'];
}

if (!empty($_GET['val'])) {
    $parentId = $_GET['val'];
}

if (!empty($_GET['child'])) {
    $childId = $_GET['child'];
}


switch ($action) {
    case 'first':
        $list = array();
        $query = "SELECT id, name FROM table where lv = 2 AND parentid= $parentId";
        $result = mysql_query($query, $link);
        while ($row = mysql_fetch_assoc($result)) {
            $arr = array ('When' => $parentId, 'Value' => $row["ID"], 'Text' => $row["NAME"]);
            $list[] = $arr;

        }
        break;
    case 'default':
    default :
        $list = '';
        $query = "SELECT id, name FROM table where lv = 2 AND parentid= $parentId";
        $result = mysql_query($query, $link);
        while ($row = mysql_fetch_assoc($result)) {
            $list .= '<option value="' . $row["ID"] . '"';
            if ($childId == $row["ID"]) {
                $list .= ' selected="selected"';
            }
            $list .= '>' . $row["NAME"] . '</option>';
        }
        $list = array('data' => $list);

        break;
}

echo json_encode($list);

第二階層的選項,其實是用字串硬湊出來的,所以程式碼看起來還蠻醜的,請見諒。基本上用的概念只是在頁面讀取完畢以後直接送出 Ajax 而已,是蠻笨的方法;不過也不失為解決問題的一種方法啦!如果有其他適合的解法,有希望高手們能提供一下嚕!謝謝^^
文章標籤

danielhuang030 發表在 痞客邦 留言(0) 人氣()

一般網頁上圖片的展示,很難讓人不聯想到 Lightbox;這個 Prototype 的燈箱特效。無奈現在公司使用的 jQuery 與 Lightbox 犯沖~沒辦法讓基於 Prototype 寫成的這個外掛直接引用。雖然如此,這麼經典的覽圖介面 jQuery 怎麼會放過呢?所以,jQuery lightBox plugin 就因此誕生了!

基本上官方網站已經講的非常清楚了,使用方法也跟 Lightbox 非常類似;不過更方便,也更有彈性。只要在需引用的網頁中載入:

<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.lightbox-0.5.js"></script>
<link rel="stylesheet" type="text/css" href="css/jquery.lightbox-0.5.css" media="screen" />

之後,寫一隻小小的 JavaScript 於頁面中:

<script type="text/javascript">
$(function() {
    $('a[@rel*=lightbox]').lightBox();
});
</script>

就可以完全相容 Lightbox 的使用環境,無痛移植。此外,jQuery lightBox plugin 提供很多可以自訂的參數,自由度提高許多!
文章標籤

danielhuang030 發表在 痞客邦 留言(1) 人氣()

昨天Jace傳授密技!原本 Ajax 回傳值我是用字串硬湊出來的,不過有密技可以用比較簡單易懂的方式呈現回傳資料,那就是PHP的json_encode!它會把陣列資料轉變成 json 的格式(其實原本 jQuery 吃的格式就是 json ),所以就不用辛苦的自己湊字串啦!提供第二種方法囉~修改過的地方用紅色標記:

index.php:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.cascade.js"></script>
<script type="text/javascript" src="jquery.cascade.ext.js"></script>
<script type="text/javascript" src="jquery.templating.js"></script>
</head>
<body>
第一項 <select id="myParentSelect">
<option value="">請選擇</option>
<?php
    // 資料庫設定
    $host_sql = "localhost";
    $username_sql = "username";
    $password_sql = "password";

    $link = mysql_connect($host_sql, $username_sql, $password_sql) or die("無法連結資料庫");
    mysql_select_db('target', $link);
    mysql_query("SET NAMES UTF8");

    $query = "SELECT id, name FROM table where lv = 1";
    $result = mysql_query($query, $link);
    while ($row = mysql_fetch_assoc($result)) {
        echo '<option value="' . $row["id"] . '">' . $row["name"] . '</option>' . "\n";
    }

?>
</select> 
第二項 <select id="myFirstChildSelect">
<option value="">請選擇</option>
</select>
第三項 <select id="mySecondChildSelect">
<option value="">請選擇</option>
</select>

<script type="text/javascript">
$(function () {

    // 第一階層對應第二階層
    $('#myFirstChildSelect').cascade('#myParentSelect', {
    ajax: {
        type: "post",
        url:  'action.php',
        data: { act: 'first', val: $('#myParentSelect').val() },
        dataType: "json"
    },
    template: function(item) { return "<option value='" + item.Value + "'>" + item.Text + "</option>"; },
    match: function(selectedValue) { return this.When == selectedValue; }
    });

    // 第二階層對應第三階層
    $('#mySecondChildSelect').cascade('#myFirstChildSelect', {
    ajax: {
        type: "post",
        url:  'action.php',
        data: { act: 'second', val: $('#myFirstChildSelect').val() },
        dataType: "json"
    },
    template: function(item) { return "<option value='" + item.Value + "'>" + item.Text + "</option>"; },
    match: function(selectedValue) { return this.When == selectedValue; }
    });
});
</script>
</body>
</html>

action.php:

<?php

// 資料庫設定
$host_sql = "localhost";
$username_sql = "username";
$password_sql = "password";

$link = mysql_connect($host_sql, $username_sql, $password_sql) or die("無法連結資料庫");
mysql_select_db('target', $link);
mysql_query("SET NAMES UTF8");

if (!empty($_GET['act'])) {
    $action = $_GET['act'];
}

if (!empty($_GET['val'])) {
    $parentId = $_GET['val'];
}

$list = array();

switch ($action) {
    case 'first':
        $query = "SELECT id, name FROM table where lv = 2 AND parentid= $parentId";
        $result = mysql_query($query, $link);
        while ($row = mysql_fetch_assoc($result)) {
            $arr = array ('When' => $parentId, 'Value' => $row["ID"], 'Text' => $row["NAME"]);
            $list[] = $arr;

        }
        break;
    case 'second':
    default :
        $query = "SELECT id, name FROM table where lv = 3 AND parentid = $parentId";
        $result = mysql_query($query, $link);
        while ($row = mysql_fetch_assoc($result)) {
            $arr = array ('When' => $parentId, 'Value' => $row["ID"], 'Text' => $row["NAME"]);
            $list[] = $arr;

        }
        break;
}

echo json_encode($list);

哈,這樣就清楚多了呢!當然昨天用字串組的方式也可以囉,其所達到的效果是一樣的啦!提供另一種思考方向^^
文章標籤

danielhuang030 發表在 痞客邦 留言(6) 人氣()

P.S 2009-04-09 update:有更輕鬆簡單的方法,詳見[AJAX] jQuery的多重下拉式選單應用:Select box manipulation

關於Ajax,我想最棒的地方就是可以於背景呼叫資料庫傳值吧~多重下拉式選單就是一項非常棒的Ajax應用;前幾天Jace丟過來一個國外的網址:jQuery.cascade : Cascading values from forms,這篇文章主要是在說明jQuery的cascade,而它就是用來實現多重下拉式選單的功能。

花了一點時間實作了一下,發現非常簡單就能實現!以前我也作過類似的功能,可是花了我非常多的時間...jQuery把它包裝起來,讓一切變的簡單多了;以下是簡單的範例,給有需要的人參考吧:範例是三階層的關聯式多重下拉式選單,分為index.php(呈現頁)、action.php(Ajax後端資料處理頁)、以及jQuery的cascade

index.php:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.cascade.js"></script>
<script type="text/javascript" src="jquery.cascade.ext.js"></script>
<script type="text/javascript" src="jquery.templating.js"></script>
</head>
<body>
第一項 <select id="myParentSelect">
<option value="">請選擇</option>
<?php
    // 資料庫設定
    $host_sql = "localhost";
    $username_sql = "username";
    $password_sql = "password";

    $link = mysql_connect($host_sql, $username_sql, $password_sql) or die("無法連結資料庫");
    mysql_select_db('target', $link);
    mysql_query("SET NAMES UTF8");

    $query = "SELECT id, name FROM table where lv = 1";
    $result = mysql_query($query, $link);
    while ($row = mysql_fetch_assoc($result)) {
        echo '<option value="' . $row["id"] . '">' . $row["name"] . '</option>' . "\n";
    }

?>
</select> 
第二項 <select id="myFirstChildSelect">
<option value="">請選擇</option>
</select>
第三項 <select id="mySecondChildSelect">
<option value="">請選擇</option>
</select>

<script type="text/javascript">
$(function () {

    // 第一階層對應第二階層
    $('#myFirstChildSelect').cascade('#myParentSelect', {
    ajax: {
        type: "post",
        url:  'action.php',
        data: { act: 'first', val: $('#myParentSelect').val() }
    },
    template: function(item) { return "<option value='" + item.Value + "'>" + item.Text + "</option>"; },
    match: function(selectedValue) { return this.When == selectedValue; }
    });

    // 第二階層對應第三階層
    $('#mySecondChildSelect').cascade('#myFirstChildSelect', {
    ajax: {
        type: "post",
        url:  'action.php',
        data: { act: 'second', val: $('#myFirstChildSelect').val() }
    },
    template: function(item) { return "<option value='" + item.Value + "'>" + item.Text + "</option>"; },
    match: function(selectedValue) { return this.When == selectedValue; }
    });
});
</script>
</body>
</html>

action.php:

<?php

// 資料庫設定
$host_sql = "localhost";
$username_sql = "username";
$password_sql = "password";

$link = mysql_connect($host_sql, $username_sql, $password_sql) or die("無法連結資料庫");
mysql_select_db('target', $link);
mysql_query("SET NAMES UTF8");

if (!empty($_GET['act'])) {
    $action = $_GET['act'];
}

if (!empty($_GET['val'])) {
    $parentId = $_GET['val'];
}

$list = '[';

switch ($action) {
    case 'first':
        $query = "SELECT id, name FROM table where lv = 2 AND parentid= $parentId";
        $result = mysql_query($query, $link);
        while ($row = mysql_fetch_assoc($result)) {
            $list .= '{\'When\':\'' . $parentId . '\',\'Value\':\'' . $row["id"] . '\',\'Text\':\'' . $row["name"] . '\'},';
        }
        break;
    case 'second':
    default :
        $query = "SELECT id, name FROM table where lv = 3 AND parentid = $parentId";
        $result = mysql_query($query, $link);
        while ($row = mysql_fetch_assoc($result)) {
            $list .= '{\'When\':\'' . $parentId . '\',\'Value\':\'' . $row["id"] . '\',\'Text\':\'' . $row["name"] . '\'},';
        }
        break;
}

$list .= ']';
echo $list;

實作的重點是在資料的格式:

list = [{'When':'A1','Value':'W','Text':'SubchildA1a'},
          {'When':'A1','Value':'X','Text':'SubchildA1b'},
         ];

其中When代表上一階層的值,Value是此一階層的值,Test則是下拉式選單顯示的文字;要特別注意JavaScript是大小寫敏感的!實作這個範例途中,曾經被大小寫拖了一段時間...後來才發現~所以這地方要特別注意!希望大家都能輕鬆寫出關聯資料庫的多重下拉式選單囉^^
文章標籤

danielhuang030 發表在 痞客邦 留言(36) 人氣()

這二年在Web界引起軒然大波的Ajax,雖然說穿了其內涵不過就是JavaScript的應用,以往也有前輩在許多年前就已經運用這項技術了~然而,在Ajax這個名詞出來以後,這項技術的發展,同時帶動許多著名framework的出現:PrototypeYUI以及目前我們公司使用的jQuery等;在這些好用的框架下,許多以往必須經由繁複程式碼才得以實現的功能,都可以利用函數呼叫的方式輕鬆呈現。

也就因為Ajax的大流行,這幾年有愈來愈多人想把所有本來在單機上執行的桌面程式,全部搬到Web上。桌面程式與網頁程式最大的差別就在,桌面程式與資料庫的連線是一直存在的,但是網頁程式則因為先天上http設計的關係,必須是建立在「客戶端發出請求,伺服端才得以回應」的條件下,才得以與資料庫建立連線;當然,神奇如Ajax也受此制約。這造成了一個問題,如果客戶端想要與伺服端同步更新資料,那應該怎麼辦呢?最常見的方式是Polling,也就是每隔一段時間由客戶端送出請求,看伺服端是否有新的資料回應;只要Polling的間隔時間夠短,客戶端就會有即時更新的錯覺。然而如果資料沒有更新,一來一往無謂的訊息傳送不但浪費頻寬,對伺服端也容易造成龐大負擔。

而Server Push就在需要即時更新資料的需求下出現,早期CGI的網路聊天室就是利用這種方式;如果再結合Ajax,則可以做到背景更新頁面的即時處理。Dojo的作者 Alex Russell 在 2006-03-03 發表的 Comet: Low Latency Data for the Browser,首次提出「Comet」這個新名詞!關於Comet詳細的介紹,可以參考Lighty RoR的文章:Comet For Ruby on Rails and Mongrel淺談 Comet PUSH Server 架構

我覺得,此理論的實現,確實可以讓桌面程式網頁化更輕鬆愉快!但是,目前似乎並沒有特別受到Web界的注意...所以,一切還是等網路前輩們的努力推廣吧~小輩的我就先暫時觀望吧^^|||
文章標籤

danielhuang030 發表在 痞客邦 留言(0) 人氣()

最近在練習中有用到搜尋的功能。一般對MySQL資料庫作搜尋,常用的做法是針對資料表中的特定欄位,用「%」LIKE的方式去尋找。然而這樣的做法常伴隨著許多限制,使用者必須先選定所要輸入的資料欄位,再對其進行搜尋;習慣了Google搜尋所帶來的便利,最理想的方式是只有一個輸入格,且可以在此輸入格中任意輸入,即可對整個資料庫進行搜尋。在MySQL中稱為Full-Text(全文檢索);然而拜完Google大神以後,網路上前輩們幾乎是一面倒的否定全文檢索。最主要的原因是因為它不支持中文!

全文檢索的做法,即是對資料庫裡的資料進行「分詞」的索引處理,有了索引,搜尋起來自然有效率的多;然而中文字不同於英文,一個句子中單獨一個中文字就可能有它的意思,另一個最大的分別在於中文句子可不像英文句子由單字與「空格」組成;建立索引時的「分詞」的動作,就是以空格進行判斷!

全文檢索的問題在網路上一直存在著,但是前輩們似乎都沒有非常完美的解答;甚至有人直接勸退提問者:「全文檢索的功能,是可以讓你寫好幾篇博士論文的研究!」如此可見,Google雲端運算的強大。既然資料庫端無解,我就從PHP的方向著手吧~Google的確是大神,讓我找到了Zend Framework就有分詞的函式Zend Search Lucene;而且原本這個功能其實也不支持中文,萬能的Google大神還幫我找到了支持中文的解決方法!

PHP製作中文全文搜尋不求人中,作者巨細靡遺的說明了資料夾配置、原始程式碼,還非常貼心的提供範例程式的下載。在如何讓Zend_Search_Lucene支持中文分詞中,作者改良了分詞用的類別,讓中文分詞的動作更加準確!既然有如此完整的範例,我當然是馬上適用在練習中啦!

目前練習所利用的開發框架,是Jace一手打造的Wacow Framework。結合Zend FrameworkSmarty,以及許多在專案製作時常會用到的工具,是公司目前專案開發的主力,也是我目前需要熟練的工具。我把建立索引的功能放在首頁,這樣只要有人進入首頁就會觸發建立索引(當然這樣做的代價是每次進首頁的速度都會被拖慢)。因為自動載入類別的關係,在建立索引時不需再額外include或require,程式碼如下:

IndexController.php(部分節錄)

// 建立分詞索引
// 關閉 Notice 錯誤提醒
error_reporting(E_ALL ^ E_NOTICE);
// 資料是 utf8 為編碼的這句為重點。如果你是 utf8 的話必需加入,否則資料會錯誤;另Phpbean是需要另外建立的中文分詞的類別
Zend_Search_Lucene_Analysis_Analyzer::setDefault(new Phpbean());
if (function_exists("set_time_limit") && ! get_cfg_var('safe_mode')) {
set_time_limit(0);
}
$index = new Zend_Search_Lucene('index', true);
$itemTable = new Items();
$itemRowset = $itemTable->fetchAll();
foreach ($itemRowset as $itemRow) {
$url = '/gime/item/detail/id/' . $itemRow->id; // 建立連結
$itemName = $itemRow->name; // 抓出物品名稱
$description = $itemRow->description; // 抓出物品敘述
//儲存網頁的位置以在搜尋結果中連結.
$doc = new Zend_Search_Lucene_Document(); // 建立新的索引文件
$doc->addField(Zend_Search_Lucene_Field::UnIndexed('url', strtolower($url)));
$doc->addField(Zend_Search_Lucene_Field::Text('name', strtolower($itemName), 'utf-8'));
$doc->addField(Zend_Search_Lucene_Field::Text('contents', strtolower($description), 'utf-8'));
$index->addDocument($doc); //把索引文件加到索引中
}
$index->commit(); //提交,及保存索引

Phpbean.php

文章標籤

danielhuang030 發表在 痞客邦 留言(3) 人氣()

這幾天承蒙Jace的諄諄教誨,當初一知半解的物件導向現在總算是有些概念了!

承接上篇的繼承,多型是敘述繼承的狀態,解釋繼承的概念:由於子類別繼承於相同的父類別,因此由子類別建立的物件當然也繼承父類別的方法。而這種「不同物件卻有相同方法」的狀態,即是多型。

抽象類別,依照我的理解可以解釋為一個不能被New(建立)的父類別;當多個類別擁有許多共通的實體變數與方法時,就可以被獨立抽離出來成為一個抽象類別的概念。另外還有抽象方法,代表該方法不能被實作,但繼承該類別的子類別,此方法一定要被實作執行。

介面(interface)則類似抽象,但介面沒有實體變數,只有方法,而且該方法不能被實作(抽象方法),而是經由繼承(implements)自該介面的類別實作,且一定要被執行。

關於抽象與介面,Jace有非常簡潔的說明...不過這太簡潔了吧,不懂的人應該還是不懂?(還有另外一個關於「介面」的說明...)
文章標籤

danielhuang030 發表在 痞客邦 留言(0) 人氣()

Close

您尚未登入,將以訪客身份留言。亦可以上方服務帳號登入留言

請輸入暱稱 ( 最多顯示 6 個中文字元 )

請輸入標題 ( 最多顯示 9 個中文字元 )

請輸入內容 ( 最多 140 個中文字元 )

reload

請輸入左方認證碼:

看不懂,換張圖

請輸入驗證碼