Skip to content

Zeroplex 生活隨筆

軟體開發、伺服器和生活瑣事

小 縮小字型大小。 中 重設字型大小。 大 放大字型大小。

標籤: 資訊學習

PHP 的小故事

Posted on 2025 年 8 月 25 日2025 年 8 月 25 日 By 日落 在〈PHP 的小故事〉中尚無留言

我接觸 PHP 蠻久了,大概從 5.1 還是 5.2 開始用到現在 8.4,避開了聽說很雷的 PHP 4,看著 PHP 引進新的功能,到現在社群開發出各種神奇的工具。

回顧過去一些事情,我覺得很重要的事情,不只可以了解 PHP 是什麼樣子程式語言,或許也可以協助判斷其他程式語言是否適合在你手上的專案使用。


就我所知,PHP 4 到 5 主要是支援物件導向,開始可以使用 class 來設計自己所需的功能,不用擔心 function name 和其他人的衝突。在這個時候,大家可以各自在網路上下載別人寫好的類別來使用,例如那個時候「藍色小舖」就有很多工程師分享自己實做的功能,例如 MySQL driver 之類的。

一些大型的專案仍保有這類的程式,像是 dolibarr ERP 的 /htdocs/core/class 目錄下,就有多個作者實做的 class。

在這個時候,功能比較複雜的專案可能會遇到類似的問題,我想要 require 新的 class 時,發現該 class 也有 require 其他的 class,如 dolibarr 的 fileupload.class.php:

<?php

/* Copyright (C) 2011-2022	Regis Houssin			
 * ....
 */

require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';


/**
 *	This class is used to manage file upload using ajax
 */
class FileUpload
{

在 FileUpload 中需要使用到 files 和 images 這二個類別。

若現有的專案,剛好有這二個類別時,會遇到類別名稱衝突,導致 require 失敗,導致 FileUpload 沒有辦法使用。這個問題其實和更早期 PHP 的狀況相同,大家各自實做自己的 function、和別人分享 function,卻又怕遇到相同的 function 名稱導致衝突。

為了解決 dependency (相依性、依賴關係) 問題,PHP 5.3 開始支援 namespace。

透過 namespace 功能,大家為 class 和 function 設定各自的 namespace,如:

<?php

namesace Zeroplex;

class FileUpload {
}

雖然 class 名稱相同,但只要在不同的 namespace 就不會導致衝突。


再故事往下之前提一下 autoload 功能,當 require 寫到手軟時,就開始有人開始想各種偷懶的方法了。

PHP 的 autoload 功能,允許使用者在建議物件時,針對自訂的邏輯,決定要做什麼事。所以這讓帶來幾個好處:

  • 只要先定好規則,就可以透過類別名稱,找到需要 require 的檔案
  • 透過 autoload,在需要使用時再 require 檔案

當這個功能合併使用時,就獲得合併技能「要使用時在 require」,不僅可以讓程式碼可讀性增加,也可以減少 disk I/O、記憶體使用量。

例如我透過 spl_autoload_register() 先定義好 require 規則:

<?php

spl_autoload_register(function ($className) {
    $classInfo = explode('/', $className);
    $namespace = $classInfo[0];
    $className = $classInfo[1];

    echo "namespace: " . $namespace . "\n";
    echo "class name: " . $className . "\n";

    require __DIR__ . "/library/" . $namespace . "/" . $className . ".php";
}

上述設定會自動將 Zeroplex/FileUploader 拆解成 namespace 和檔案名稱並 require,執行程式時會在 new 階段透過 autoloader 來決定要去哪裡 require 檔案:

<?php

$uploader = new Zeroplex\FileUploader();
namespace: Zeroplex
class name: FileUploader

在百家爭鳴寫 library 時,還會遇到一個問題:A 和 B library 都需要用到 C library,但 A library 中任何版本的 C library 都可,而 B library 則需要 C library 的最新版。這樣開發程式時,就還需要考慮到底要使用 C library 的哪一個版本。

於是 composer 就出現了。composer 是 dependency management,會自動尋找專案中各 library 可正確運作的版本。


時間往後走一段時間, 來到 PHP 7。

PHP 7 做的最大改變,是大幅改寫直譯器,讓效能大幅提升,而且不只是快一點點而已,是快了 100%。以前為了讓 PHP 程式跑得更快,Facebook 開發了 hhvm,現在用不到了。

若想知道為什麼效能可以快這麼多,可以參考 Nikita Popov (PHP 核心工程師之一) 的簡報:PHP 7 – What changed internally?。或是聽他的演講:

除了效能以外,PHP 在此時也慢慢的提供一些資料型態的定義、檢查功能,像是在撰寫 function 時可以定義 argument 的資料型態 (type hint),除了 scalar type 也開始支援使用者自訂 class 的支援。

這些支援,讓原本是 dynamic typing 的 PHP 可以多一些檢查,程式的可讀性和穩定性上都有改善。


PHP 7 到 8 我打算很不負責任得什麼都不說直接跳過 XD

這邊列出一些有趣的專案:

  • 在 awesome-php 上有很多有趣的專案
  • 如果覺得 PHP 效能不佳,可以試試看 Swoole 以及 Phalcon,這二個 framework 使用 C/C++ 實作,在 phpize 與 PHP 串接。
  • 其實有了 interface,不只有 C/C++,連 Rust 也可以開發 PHP extension
  • PHP 沒有 non-blocking I/O?其實也有,實作方法換一下即可 ReactPHP

Tags:PHP, 資訊學習

(AI 奈米量子科技之 LLM 什麼的) Meilisearch 簡介

Posted on 2024 年 10 月 24 日 By 日落 在〈(AI 奈米量子科技之 LLM 什麼的) Meilisearch 簡介〉中尚無留言

標題不知道寫什麼好,反正外掛說 SEO 100 分 …..

在開始聊 Meilisearch 之前,我想先來聊一下全文檢索。

MySQL 的搜尋

MySQL 搜尋功能都是精確搜尋,也就是搜尋的關鍵字一定會出現。例如:

SELECT title
FROM news
WHERE news_content like '%逢甲夜市%'

以上的語法,搜尋結果中一定會包含「逢甲夜市」四個字。

但若我需要模糊搜尋,搜尋「逢甲」或是「夜市」,該怎麼辦?

這個時候要改用 MySQL 的全文檢索功能。

MySQL 全文檢索 (Full Text Indexing)

需要被全文檢索的欄位,必須先建立 fulltext 的索引:

create index full_text_idx_news
on news (news_content) using full_text

搜尋時就可以使用全文檢索語法:

SELECT title
FROM meilisearch_index_urls
WHERE match(news_content) AGAINST ("逢甲夜市")

這時「逢甲夜市」、「逢甲」、「夜市」應該都有機會被列出來,但是準確度並不高。

中文斷詞

以英語系的語言,要將詞彙區分出來較為容易,因為每個詞中間都有空白:

This is night market

很明顯可以分成四個詞:

  • this
  • is
  • night
  • market

中文就沒有這麼方便了,以「這是夜市」來說,這句話中一個空白都沒有,只能依照字詞長度做分割:

  • 這是夜市 (4-grams)
  • 這是夜 (3-grams)
  • 是夜市 (3-grams)
  • ….

將所有排列組合全部列出以後,再用其他文章出現的字詞,將常用詞會出現的機率 (詞頻) 將機率大的列出。

這裡介紹中研院花了數年開發出來的中文斷詞系統 (CKIP),他不但能將詞彙列出,甚至還可以便辭性與外來語:

要成精準的分中文字詞,需要先有一個語料庫,才能較準確的搜尋與分析。而這次要介紹的 Meilisearch,就有支援不同語言的分析,所以在全文件檢索上的精確度高上許多。

Meilisearch

Meilisearch 是一個使用 Rust 開發的全文檢索引擎,有以下特點:

  • 搜尋速度快
  • 隨打即找
  • 支援多國語言 (你不需要另外裝套件啦)
  • RESTfulf API,不管什麼語言、工具都很容易串接
  • 由於是 Rust 開發,只要複製 binary 下來即可執行,不需要額外的安裝步驟

安裝

先開啟 Meilisearch Github 官方網站中的 release 頁面,先抓穩定板 (這裡以 v1.10.3 為主),在下方「assets」選擇適合你的 binary 檔下載。

meilisearch binary after downloaded

剛下載的 binary 沒有執行權限,使用 chmod 給他執行全賢執行權限:

chmod +x meilisearch-linux-amd64

安裝到這裡,就算是結束了。

啟動 Meilisearch

預設的啟動方式,就是直接行 Meilisearch:

Meilisearch 啟動畫面

啟動後除了可以看到他們 logo 以外,往下一些還可以看到他建立了一個目錄 ./data.ms 作為資料除存使用,這邊主要儲存索引黨。

Meilisearch 使用 RESTful API,所以參考官方文件,透過 curl 便可確定是否已經能正常運作:

使用 curl 出較 Meilisearch API

這邊使用 GET /indexes 來要求 Meilisearch 列出所有的 indexes,剛安裝好的當然沒什麼東西,所以 results 是空的沒錯。

新增 documents

Meilisearch 的資料為 document,不是資料表,所以資料只要標明欄位名稱、內容,級可以被建立索引,且前後的 document 其使欄位不同也可以被接受。

這裡準備一個範例 document:

[
    {
        "id": 1,
        "name": "日升",
        "phone": "0987654321",
        "tag": ["programming", "photograing", "readding"]
    },
    {
        "id": 2,
        "name": "日落",
        "tag": ["programming", "PHP", "back-end", "docker"]
    }
]

然後按照 Meilisearch add documents 的說明新增資料:

新增 documents 以後的 result

這邊 Meilisearch 並不會告訴你是否成功,因為所有的動作都會先進度工作佇列,再慢慢處理。

執行後拿到的 tasekUid 是「0」,我們可以再使用這個 ID 去查詢執行狀態:

curl -X GET 'http:///localhost:7700/tasks/0'

task 這邊回有很詳細的狀態,像是成功或失敗,開始時間、結束時間等等。

操作沒有很複雜,看一下 Meiliserch 官方文件差不多都可以解決。


我這邊建立索引的新聞內容,目前放在自家網站 Zeroplex 的新聞搜尋工具,大家可以拿一些奇怪的中文字去搜尋看,Meilisearch 全文檢索功能在中文處理上效果不錯

上述新聞搜尋工具,目前為以下項目做全文檢索:

    • 新聞標題
    • 新聞內容

    搜尋會回傳的內容有:

    • 新聞標題
    • 日期
    • URL

    目前使用狀況大致如下:

    • document 數量約 140 萬筆
    • 索引大小約 28 GB

    目前使用的狀況:

    • 查詢的速度很快,只要搜尋的文字很短速度就很快;但若關鍵字較長也會讓搜尋時間變長
    • 中文的支援很棒,不會出現很奇怪的斷字詞
    • 建立索引的速度慢
      • 在 v1.4.x 時,為一個 document 建立索引可以會花上 1 分鐘以上,且這一分鐘會附加滿滿的 disk I/O
      • 升級到 v1.9.x 以後,建立索引的速度快很多,disk I/O 的量沒有像以前那麼誇張
      • 如果第一次使用,建議直接從最新版開始使用

    以下是我在 KaLUG 分享時使用的簡報,歡迎大家參考:

    Tags:Meilisearch, 分享, 資訊學習

    雲端除存服務的費用

    Posted on 2024 年 3 月 5 日2024 年 3 月 5 日 By 日落 在〈雲端除存服務的費用〉中尚無留言

    剛好有一些資料打算封存,所以嘗試各種雲端除存服務。

    以儲存空間計費 (忽略資料傳輸費用) 的話,由貴到便宜分別是:

    1. AWS S3
    2. Google Cloud Storage
    3. BackBlaze B2

    原本以為 BackBlaze 沒有亞洲資料中心,傳輸速度會很慢,但一直都有維持在 5 MB/s 以上,還算不錯。

    Azure 還沒研究,等下一輪吧

    Tags:AWS, BackBlaze, GCP, 資訊學習

    Meilisearch 建立索引遇到的瓶頸

    Posted on 2024 年 2 月 12 日2024 年 2 月 13 日 By 日落 在〈Meilisearch 建立索引遇到的瓶頸〉中尚無留言

    Meilisearch 是一個以 Rust 開發的全文搜尋引擎 (full-text search engine),主打簡單好用、搜尋和回應速度都很快,另外預設就支援多國語言,不需要特別調整設定或安裝擴充套件即可使用。

    覺得有趣,去年拿來當作 site project 的一部分研究。當索引檔大小漸漸增加,也開始發現一些問題。

    觀察了一下運作的狀況:

    • 索引大小約 1 GB 時,使用 1 thread + 1 GB RAM,新增資料約 3 秒
    • 索引大小在 5 GB 時,使用 4 thread + 2 GB RAM,新增資料至少 15 秒起跳

    在索引檔大小增加以後,增加 threading 和 RAM 對執行效率並沒有顯著的效果,瓶頸看起來是卡在 disk I/O。

    手上 VPS 觀察到的 I/O 最大約 200 MB/s,應該就是極限了:

    dstat 觀察到最大的 disk I/O 約 200 MB/s
    dstat 觀察到最大的 disk I/O 約 200 MB/s

    Meilisearch 並不是不能用,這邊還是簡單列幾個優缺點。

    優點:

    • 就一個執行檔而已,不用下參數就可以正常運作
    • 走 RESTful API,curl 就可以操作。因為簡單,所以幾乎這種程式語言已都有 API 可用。
    • document based data,不需要事先定義 field / column (我覺得這也可以算是一個缺點)
    • 隨時調整 searchable / sortable / displayable doument field
    • 內建 dump & snapshot

    缺點:

    • 覺得算是一個迭代速度蠻快的專案,所以文件沒有很完整 (或說明不好找)
    • 透過 master key 和 API key 來限制使用、操作,略顯不足
    • 部份覺得蠻重要的功能尚在開發中,例如透過 rank 來排序之類的
    • 查詢功能、查詢結果列表有一些限制,但可以透過其他功能來避免 (known limitations)

    Meilisearch 的社群蠻活躍的,歡迎大家參與討論 -> Meilisearch Roadmap

    Tags:資訊學習

    自訂等待的動畫示意符號

    Posted on 2024 年 2 月 8 日2024 年 2 月 8 日 By 日落 在〈自訂等待的動畫示意符號〉中尚無留言

    這邊用 PHP 實作,可以自己改成其他程式語言。

    主要是使用 \r 來回到行首,然後使用新的文字蓋過原有的文字,就可以出現簡單的圖形變換效果:

    $symbol = ['\\', '|', '/', '-'];
    
    $count = 0;
    echo "\n";
    while(1) {
        echo "\rpending ..." . $symbol[$count % 4] ;
    
        $count++;
        sleep(1);
    }

    不知道有沒有什麼其他符號看起來比較清楚的? O_Oa

    Tags:程式設計, 資訊學習

    文章分頁

    1 2 ... 52 下一頁

    其他

    關於我  (About me)

      文章 RSS Feed

      留言 RSS Feed

    Apache AWS Bash C/C++ Docker FreeBSD GCP Git Google Java JavaScript Laravel Linux Microsoft MSSQL MySQL Nginx PHP PHPUnit PostgreSQL Python Qt Ubuntu Unix Vim Web Windows WordPress XD 作業系統 分享 好站推薦 專題 攝影 新奇搞笑 新聞 旅遊 生活雜記 程式設計 網路架站 網頁設計 資訊學習 資訊安全 遊戲 音樂


    創用 CC 授權條款
    本著作係採用創用 CC 姓名標示-相同方式分享 4.0 國際 授權條款授權.