發佈日期:

LibreOffice Calc 智慧列高調整巨集

Views: 3

🚀 SmartHeight Pro:讓 Excel/Calc 表格排版瞬間整齊

一鍵批次微調,告別高矮不一的混亂報表!

還在手動拉動每一列的高度嗎?當表格內容過多,導致自動換行後的列高顯得雜亂無章時,此範例程式是您的最佳救星。這款專為 LibreOffice/OpenOffice 打造的智慧腳本,能精準鎖定範圍,自動將列高優化至最完美的視覺比例。


✨ 核心亮點

  • ⚡ 智慧自動進位:程式會自動偵測現有高度並執行「百位數進位」邏輯,確保每一列都能獲得充足的顯示空間,視覺效果更趨統一。
  • 🛡️ 專業保底高度:內建 0.8cm (800 twips) 最低高度限制,防止列高縮過頭,確保報表文字在列印或閱讀時永不被遮蓋。
  • 📍 視覺化精準定位:獨家「跳轉追蹤」功能!在輸入起始與結束列號時,畫面會自動滾動至目標位置,讓你邊看邊設,絕不出錯。
  • 🔄 記憶常用參數:具備智慧記憶功能,自動帶入上次設定的列號範圍,重複作業僅需連按 Enter 即可完成。
  • ✅ 視覺回饋提示:執行成功後按鈕將閃爍綠燈,給予最直覺的操作確認,不再疑惑程式是否有在跑。

🛠️ 強大功能

  • 批次處理:支援自定義任意範圍,無論是 10 列還是 1000 列,瞬間處理完畢。
  • 跳轉輔助:在設定過程中自動導航,解決長表格翻找列號的痛苦。
  • 零侵入性:只針對有高度的顯示列進行優化,自動避開已隱藏的列位。
  • 簡易整合:輕鬆掛載於現有工具列或按鈕,隨開隨用。

💻 程式源碼 (Basic)

請將以下代碼複製並貼上至您的 LibreOffice/OpenOffice 巨集編輯器中:

Global g_sLastStart As String
Global g_sLastEnd As String

Sub AdjustHeightByInput
    Dim oDoc As Object
    Dim oSheet As Object
    Dim oForm As Object
    Dim oButton As Object
    Dim sStart As String, sEnd As String
    Dim nStart As Long, nEnd As Long
    Dim i As Long
    Dim currH As Long, newH As Long
    
    oDoc = ThisComponent
    oSheet = oDoc.CurrentController.ActiveSheet
    
    oForm = oSheet.DrawPage.Forms.getByIndex(0)
    oButton = oForm.getByName("CommandButton 1") 

    If g_sLastStart = "" Then g_sLastStart = "11"
    JumpToRow(oDoc, oSheet, CLng(g_sLastStart))
    
    sStart = InputBox("起始列號:", "設定範圍 (1/2)", g_sLastStart)
    If sStart = "" Then Exit Sub
    g_sLastStart = sStart

    If g_sLastEnd = "" Then g_sLastEnd = "19"
    JumpToRow(oDoc, oSheet, CLng(g_sLastEnd))
    
    sEnd = InputBox("結束列號:", "設定範圍 (2/2)", g_sLastEnd)
    If sEnd = "" Then Exit Sub
    g_sLastEnd = sEnd
    
    nStart = CLng(sStart) - 1
    nEnd = CLng(sEnd) - 1
    
    For i = nStart To nEnd
        currH = oSheet.Rows.getByIndex(i).Height
        If currH > 0 Then
            If (currH Mod 100 <> 0) Then
                newH = (Int(currH / 100) + 1) * 100
            Else
                newH = currH
            End If
            If newH < 800 Then newH = 800
            oSheet.Rows.getByIndex(i).Height = newH
        End If
    Next i
    
    oButton.BackgroundColor = RGB(144, 238, 144)
    Wait 800 
    oButton.BackgroundColor = RGB(240, 240, 240)
End Sub

Sub JumpToRow(oDoc, oSheet, nRow)
    Dim oCell As Object
    On Error Resume Next
    oCell = oSheet.getCellByPosition(0, nRow - 1)
    oDoc.CurrentController.select(oCell)
End Sub

💡 適用場景

  • 財務報表:確保所有數據列高度一致,視覺更專業。
  • 產品清單:自動調整因說明文字長度不一造成的排版混亂。
  • 列印前校對:統一高度標準,避免列印出來高低落差過大。

🎯 想提升您的工作效率嗎?立即將此巨集導入您的 Calc 環境!

發佈日期:

電腦越用越慢?分享 PowerShell 腳本,一鍵偵測記憶體與句柄洩漏

Views: 45

🔍 記憶體去哪了?忠碁科技專用診斷工具,教你揪出消失的實體記憶體!

📖 故事的開頭…

最近電腦開機一段時間後,發現記憶體使用了近 90%,但打開工作管理員把所有進程(Processes)的記憶體加總,卻怎麼也湊不到那個數字。

忠碁為了提供相關資訊給其它智慧工具分析,並找出到底是哪個神祕黑洞吃掉了資源,忠碁參考了 網路技術文章 的分析邏輯,編寫了這支「Windows 記憶體耗盡診斷腳本」。它不只看表面數據,更能深入內核層級(Kernel)去偵測那些連工作管理員都抓不到的記憶體佔用。


💡 為什麼你需要這支腳本?(亮點分析)

一般的系統工具只能看到應用程式的佔用,但當你遇到核心層級的問題時,往往無能為力。忠碁科技 在處理企業級系統維護時,常遇到以下「記憶體黑洞」:

  • 驅動程式洩漏 (Driver Leak):非分頁池(Non-Paged Pool)異常飆高,通常是網卡或顯卡驅動作怪。
  • 網路驅動 NDU 衝突:Windows 內置監控導致的記憶體洩漏。
  • 句柄洩漏 (Handle Leak):程式碼沒寫好,瘋狂索取控制權而不歸還。
  • IO 瓶頸:大量修改中頁面(Modified Page)堆積。

✨ 本程式 5 大核心亮點:

  • 🚀 自動權限提升:內建管理員權限請求邏輯,確保獲取內核敏感數據。
  • 🧩 隱形佔用精確計算 ($gap):自動對比系統總量與進程總量,直接算出被核心、快取吃掉的差距(Gap)。
  • 🚨 智慧診斷與預警:
    • 非分頁池預警:自動判別是否超過 1GB/2GB 臨界點,並篩選出可能的第三方驅動。
    • 句柄監控:當單一進程 Handle 超過 10,000 個(例如特定印表機驅動異常),立即觸發警告。
  • 📊 專業級數據報告:執行完畢自動生成 Memory_Report.txt 與 Memory_Summary.txt,格式美觀,方便傳給 忠碁 的技術人員進行深度分析。
  • 🛠️ 實戰派建議:不僅發現問題,更會依據結果引導你使用 poolmon.exe 或 RAMMap 等進階工具。

📝 腳本源碼分享(PowerShell)

請將以下代碼複製並另存為 Memory_Diagnosis.ps1 後執行:

# --- 1. 自動提升權限 ---
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
if (-not $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Write-Host ">>> 權限不足,正在請求管理員權限..."
    $argList = "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`""
    try { Start-Process powershell.exe -ArgumentList $argList -Verb RunAs; exit } catch { exit }
}

# --- 2. 路徑設定 ---
$reportPath = "$PSScriptRoot\Memory_Report.txt"
$summaryPath = "$PSScriptRoot\Memory_Summary.txt"
$report = New-Object System.Collections.Generic.List[string]

Write-Host ""
Write-Host "===== 記憶體耗盡診斷 (使用率分析) ====="
Write-Host ""

try {
    # ========== 1. 基礎記憶體數據 ==========
    $os = Get-CimInstance Win32_OperatingSystem
    if ($null -eq $os) { throw "無法取得 Win32_OperatingSystem 資訊" }

    $totalKB = $os.TotalVisibleMemorySize
    $freeKB = $os.FreePhysicalMemory
    $usedKB = $totalKB - $freeKB
    $totalGB = [math]::round($totalKB / 1MB, 2)
    $freeGB = [math]::round($freeKB / 1MB, 2)
    $usedGB = [math]::round($usedKB / 1MB, 2)
    $usagePercent = [math]::round(($usedKB / $totalKB) * 100, 2)
    $bootTime = $os.LastBootUpTime
    $uptime = (Get-Date) - $bootTime

    $report.Add("[1] 系統基本資訊")
    $report.Add("    開機時間  : $bootTime")
    $report.Add("    運行時間  : $($uptime.Days)天 $($uptime.Hours)時 $($uptime.Minutes)分")
    $report.Add("    總記憶體  : $totalGB GB")
    $report.Add("    已用記憶體: $usedGB GB")
    $report.Add("    可用記憶體: $freeGB GB")
    $report.Add("    總體佔用率: $usagePercent %")
    $report.Add("")

    # ========== 2. 核心層級記憶體分類 ==========
    $memPerf = Get-CimInstance Win32_PerfFormattedData_PerfOS_Memory -ErrorAction SilentlyContinue
    if ($null -eq $memPerf) {
        $report.Add("[2] 核心層級記憶體分類 - 警告: 無法讀取效能計數器")
        $nonPagedMB = 0
        $pagedMB = 0
        $cacheMB = 0
        $standbyMB = 0
        $modifiedMB = 0
    } else {
        $nonPagedMB = [math]::round($memPerf.PoolNonpagedBytes / 1MB, 2)
        $pagedMB = [math]::round($memPerf.PoolPagedBytes / 1MB, 2)
        $cacheMB = [math]::round($memPerf.CacheBytes / 1MB, 2)
        $standbyMB = [math]::round($memPerf.StandbyCacheCoreBytes / 1MB, 2)
        $modifiedMB = [math]::round($memPerf.ModifiedPageListBytes / 1MB, 2)

        $report.Add("[2] 核心層級記憶體分類 (找出隱形耗用)")
        $report.Add("    非分頁池 (NonPaged) : $nonPagedMB MB (超過 1000MB 需注意)")
        $report.Add("    分頁池 (Paged)      : $pagedMB MB")
        $report.Add("    系統快取 (Cache)    : $cacheMB MB")
        $report.Add("    待命記憶體 (Standby): $standbyMB MB")
        $report.Add("    修改中頁面 (Modified): $modifiedMB MB")
    }
    $report.Add("")

    # ========== 3. 非分頁池異常診斷 (記憶體洩漏) ==========
    if ($nonPagedMB -gt 2000) {
        $report.Add("[3a] 嚴重警告:非分頁池高達 $nonPagedMB MB (正常值 < 1GB)")
        $report.Add("    這表示驅動程式或核心模組有嚴重記憶體洩漏!")
        $report.Add("")
        
        $drivers = Get-CimInstance Win32_SystemDriver | Where-Object { $_.State -eq "Running" -and $_.PathName -notlike "*\\system32\\drivers\\*" }
        $report.Add("    正在執行的第三方驅動程式 (前20個,可能是元兇):")
        $drivers | Select-Object -First 20 | ForEach-Object {
            $report.Add("        - $($_.Name) : $($_.PathName)")
        }
        if ($drivers.Count -gt 20) {
            $report.Add("        ... 共 $($drivers.Count) 個,已省略 $($drivers.Count - 20) 個")
        }
        $report.Add("")
    }

    # ========== 4. 虛擬記憶體與分頁檔 ==========
    $pageFile = Get-CimInstance Win32_PageFileUsage
    $pageTotalGB = if ($pageFile) { [math]::round($pageFile.AllocatedBaseSize / 1024, 2) } else { 0 }
    $pageUsedGB = if ($pageFile) { [math]::round($pageFile.CurrentUsage / 1024, 2) } else { 0 }
    
    $report.Add("[4] 虛擬記憶體與分頁檔")
    $report.Add("    分頁檔總大小 : $pageTotalGB GB")
    $report.Add("    分頁檔已用   : $pageUsedGB GB")
    $report.Add("    提交總量 (Commit) : $([math]::round($os.TotalAllocatedBaseSize / 1KB / 1024, 2)) GB")
    $report.Add("    提交限制 (Limit)  : $([math]::round($os.TotalVirtualMemorySize / 1MB, 2)) GB")
    $report.Add("")

    # ========== 5. NDU 網路驅動檢查 ==========
    $report.Add("[5] 網路驅動程式與 NDU 狀態")
    
    $ndu = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Ndu" -ErrorAction SilentlyContinue
    $nduStart = if ($ndu) { $ndu.Start } else { "未找到" }
    $report.Add("    NDU 服務啟動類型 : $nduStart (4為禁用,建議設為4)")
    
    $netDrivers = Get-CimInstance Win32_PnPSignedDriver | Where-Object { 
        $_.DeviceName -match "Killer|Realtek|Intel.*Ethernet|Broadcom|VMware|VirtualBox|Hyper-V" -and $_.IsRunning 
    }
    foreach ($net in $netDrivers) {
        $report.Add("    網卡驅動 : $($net.DeviceName) | 版本 : $($net.DriverVersion)")
    }
    $report.Add("")

    # ========== 6. 進程記憶體排行 ==========
    $report.Add("[6] 進程記憶體排行 (WorkingSet - 前 20 名)")
    $report.Add("    名稱                      | 數量 | WorkingSet | 私用記憶體 | 句柄數")
    $report.Add("    ----------------------------------------------------------------")
    
    $processes = Get-Process | Group-Object Name | ForEach-Object {
        $wsSum = ($_.Group | Measure-Object WorkingSet -Sum).Sum
        $pmSum = ($_.Group | Measure-Object PrivateMemorySize -Sum).Sum
        $hdSum = ($_.Group | Measure-Object HandleCount -Sum).Sum
        [PSCustomObject]@{
            Name = $_.Name
            Count = $_.Count
            WorkingSet_MB = [math]::Round($wsSum / 1MB, 2)
            Private_MB = [math]::Round($pmSum / 1MB, 2)
            Handles = $hdSum
        }
    } | Sort-Object WorkingSet_MB -Descending
    
    $processes | Select-Object -First 20 | ForEach-Object {
        $report.Add("    $($_.Name.PadRight(25)) | $($_.Count.ToString().PadLeft(4)) | $($_.WorkingSet_MB.ToString().PadLeft(8)) MB | $($_.Private_MB.ToString().PadLeft(8)) MB | $($_.Handles)")
    }
    
    $totalProcessWS = [math]::Round(($processes | Measure-Object WorkingSet_MB -Sum).Sum, 2)
    $gap = [math]::Round($usedGB * 1024 - $totalProcessWS, 2)
    
    $report.Add("")
    $report.Add("    所有進程 WorkingSet 總和 : $totalProcessWS MB")
    $report.Add("    與系統回報已使用量差距 : $gap MB (這個差距就是核心/驅動/快取吃掉的部分)")
    $report.Add("")

    # ========== 7. Handle 句柄排行 ==========
    $report.Add("[7] 進程句柄排行 (Handles - 前 10 名)")
    $report.Add("    (句柄數異常增加通常代表程式即將耗盡資源)")
    $processes | Sort-Object Handles -Descending | Select-Object -First 10 | ForEach-Object {
        $report.Add("    $($_.Name.PadRight(25)) | 句柄數 (Handles): $($_.Handles)")
    }
    $report.Add("")

    # ========== 8. 句柄洩漏診斷 ==========
    $topHandle = $processes | Sort-Object Handles -Descending | Select-Object -First 1
    $highHandleProcesses = $processes | Where-Object { $_.Handles -gt 10000 } | Sort-Object Handles -Descending
    
    if ($highHandleProcesses.Count -gt 0) {
        $report.Add("[3b] 嚴重警告:發現進程句柄洩漏!")
        foreach ($proc in $highHandleProcesses) {
            $report.Add("    🚨 $($proc.Name) 句柄數高達 $($proc.Handles) (正常值 < 5000)")
        }
        $report.Add("    這可能導致系統資源耗盡,建議採取以下措施:")
        $report.Add("    1. 立即重開機釋放被佔用的句柄")
        $report.Add("    2. 更新或移除對應的驅動程式/軟體")
        $report.Add("    3. 如果是印表機驅動(jcprinter),請更新或解除安裝")
        $report.Add("")
    } elseif ($topHandle.Handles -gt 5000) {
        $report.Add("[3c] 注意:發現句柄數偏高")
        $report.Add("    $($topHandle.Name) 句柄數為 $($topHandle.Handles) (正常值 < 5000)")
        $report.Add("    建議重開機或檢查是否有程式記憶體洩漏")
        $report.Add("")
    }

    # ========== 9. 修改中頁面異常診斷 ==========
    if ($modifiedMB -gt 10000) {
        $report.Add("[3d] 警告:修改中頁面過高 ($modifiedMB MB)")
        $report.Add("    這表示有大量記憶體正在等待寫入分頁檔")
        $report.Add("    建議增加分頁檔大小或檢查磁碟IO效能")
        $report.Add("")
    }

    # ========== 10. 記憶體趨勢警告 ==========
    if ($uptime.TotalHours -gt 48 -and $nonPagedMB -gt 1500) {
        $report.Add("[8] 系統已運行超過 2 天且非分頁池過高 -> 強烈懷疑驅動程式洩漏!")
        $report.Add("")
    }

    # ========== 寫入檔案 ==========
    $report | Out-File -FilePath $reportPath -Encoding utf8
    $processes | Sort-Object WorkingSet_MB -Descending | ForEach-Object {
        "$($_.Name.PadRight(25)) | $($_.Count.ToString().PadLeft(4)) | $($_.WorkingSet_MB.ToString().PadLeft(8)) MB | $($_.Private_MB.ToString().PadLeft(8)) MB | $($_.Handles)"
    } | Out-File -FilePath $summaryPath -Encoding utf8

    Write-Host "分析完成。"
} catch {
    Write-Host "錯誤: $($_.Exception.Message)"
}

🚀 如何使用?

  1. 將上述代碼另存為 Memory_Diagnosis.ps1
  2. 在該檔案上點擊右鍵,選擇「使用 PowerShell 執行」。
  3. 腳本會自動請求權限,並在幾秒內掃描全機狀態。
  4. 執行完成後,請查閱同資料夾下的報告檔案。

💬 結語

在技術服務的領域,數據就是真相。忠碁科技有限公司 始終致力於透過自動化與精準診斷,協助客戶排除最棘手的系統瓶頸。

這支腳本就像是電腦的 X 光機,能幫你把記憶體黑洞照得一清二楚。如果你也深受「記憶體莫名失蹤」所苦,這份邏輯精鍊而成的工具,絕對是你最好的幫手!

💡 小提醒:若診斷報告顯示 [3b] 嚴重警告:發現進程句柄洩漏,且來源是印表機相關驅動,請務必按照報告中的建議更新或重新安裝驅動程式。

發佈日期:

不需要驗證碼!教你用「蜜罐技術」阻擋 99% 機器人攻擊

Views: 18

為什麼您的 WordPress 需要「隱形防禦」?

每分鐘都有數以萬計的自動化腳本在嘗試入侵 WordPress 網站。傳統的圖形驗證碼雖然有效,卻嚴重損害了使用者的登入體驗。
忠碁科技 設計了一套非侵入式的網站 WP-LOGIN 防護機制,透過「行為特徵」來辨識人類與機器,讓您的登入頁面保持潔淨卻固若金湯。


核心防禦邏輯:三重防線

  1. 時間差驗證:利用人類輸入資料的基本生理限制,阻擋瞬間提交的自動腳本。
  2. 蜜罐陷阱 (Honeypot):在表單中埋入「人類看不見、機器人必填」的虛擬欄位。
  3. 環境偵測:透過 JavaScript 動態注入驗證碼,確認操作者具備真實瀏覽器的運行環境。

實作範例:將代碼加入您的 functions.php

請注意:為了確保防禦效果,建議您將代碼中標註為 “your_custom_name” 的部分,自行修改為隨機的英文字串。


// 1. 時間差驗證:記錄使用者開啟頁面的時間
add_action('login_form', 'tj_add_timestamp');
function tj_add_timestamp() {
    echo '<input type="hidden" name="login_start_ts" value="' . esc_attr(time()) . '" />';
}

// 2. 蜜罐陷阱:建立一個只有機器人才會填寫的欄位
add_action('login_form', 'tj_add_honeypot_field');
function tj_add_honeypot_field() {
    // 透過 CSS 讓人類使用者完全看不到此欄位
    echo '<div style="position:absolute; left:-9999px; top:-9999px;" aria-hidden="true">';
    echo '<label>請勿填寫此欄位</label>';
    echo '<input type="text" name="fax_number_custom" tabindex="-1" value="" autocomplete="off" />';
    echo '</div>';
}

// 3. 後端驗證邏輯
add_filter('authenticate', 'tj_check_login_security', 20, 3);
function tj_check_login_security($user, $username, $password) {
    if (!isset($_POST['wp-submit'])) return $user;

    // 檢查提交速度是否過快(小於 3 秒判定為機器人)
    if (isset($_POST['login_start_ts']) && (time() - intval($_POST['login_start_ts']) < 3)) {
         return new WP_Error('too_fast', '登入程序異常,請稍候再試。');
    }

    // 檢查蜜罐欄位是否有被填充
    if (!empty($_POST['fax_number_custom'])) {
         error_log("機器人攻擊攔截自: " . $_SERVER['REMOTE_ADDR']);
         return new WP_Error('bot_detected', '驗證錯誤,請重新整理頁面。');
    }

    return $user;
}

忠碁科技的專業堅持

在上述實作中,我們特別加入了 tabindex="-1"aria-hidden="true"
這是為了確保在保護安全的同時,不影響使用螢幕閱讀器的視障使用者。
真正的技術力,不僅在於防禦的深度,更在於對每一位使用者的尊重。

如果您希望針對網站進行更高階的安全佈署,歡迎聯繫忠碁科技,讓我們為您的數位資產保駕護航,這種深度客製化的防禦機制,展現了與僅依賴『現成外掛』完全不同的技術底蘊與專業層次。這不僅是防護,更是技術的藝術。

發佈日期:

PHP讀取IP2Location.BIN數據庫精準示範

Views: 9

【頂層邏輯】數位資產的隱形門衛:IP2Location 數據庫的精準控管術

在數位資產的領域,真正的贏家不在於追求花哨的技術,而在於對「邊界」的絕對掌控。

如果您經營的是高淨值電商、私域流量平台,或是需要嚴格合規的金融服務,您一定明白:隨意開放的存取,就是利潤的缺口。透過這段精煉的 PHP 底層邏輯,我們能實現在不依賴任何第三方雲端服務(避免數據資產外洩)的前提下,自主掌握訪客的國別主權。

為什麼系統不使用 API?

  • 數據主權:您的訪客軌跡不應成為第三方服務商的數據養分。
  • 極致穩定:排除外部服務商斷線或調漲資費的風險。
  • 毫秒級決策:在本地端完成判斷,確保高端用戶的流暢體驗。

私有化部署示範:極簡且安全的讀取邏輯

這段原始程式碼體現了「不拖泥帶水」的執行效率,將防禦機制直接植入核心。

// 使用 __DIR__ 取得 php 所在目錄 (即 public_html 的上一層)
        $libFile = __DIR__ . '/public_html/IP2Location/src/Database.php';
        $dbFile  = __DIR__ . '/public_html/IP2Location/data/IP2LOCATION-LITE-DB1.BIN';
        
        if (file_exists($libFile)) {
            require_once($libFile);
            
            try {
                if (!file_exists($dbFile)) {
                    throw new Exception("DB Missing");
                }
                // 不要用 use,直接寫完整類別名稱避免 500 錯誤
                $db = new \IP2Location\Database($dbFile, \IP2Location\Database::FILE_IO);
                $records = $db->lookup($v_ip, \IP2Location\Database::ALL);
                $country = ($records) ? strtoupper($records['countryCode']) : 'UNKNOWN';
            } catch (Exception $e) {
                $country = 'ERROR';
                die("資料庫錯誤: " . $e->getMessage() . " 路徑為: " . $dbFile);
            }
            
        } else {
            // 如果連 Library 都找不到,可能是路徑寫錯
            $country = 'LIB_NOT_FOUND';
        }

教學解析:魔鬼就在細節裡

1. 空間布局:絕對路徑的思維

程式碼採用 __DIR__ 起手,這反映了一種「確定性」。經營事業不容許「模糊空間」,透過絕對路徑精準鎖定 public_html 的層級,確保資產庫在伺服器遷移時依然能固若金湯。

2. 風控機制:拒絕 500 錯誤的底氣

程式特別註解「不要用 use,直接寫完整類別名稱」。這是一種風險避險策略。在複雜的生產環境中,減少依賴全域聲明,能有效避免因類別衝突導致的系統崩潰(500 錯誤),這正是追求系統 99.99% 在線率的關鍵。

3. 效率優先:即時的決策回傳

透過 Database::FILE_IO 模式,系統能以最輕量的方式完成讀取,並將結果轉換為標準大寫國家代碼(strtoupper)。這讓後續的商業決策(如:跳轉、阻擋或推送特定廣告)能夠在瞬間完成。

結語:資產的增長來自於對風險的精準控制。透過手動整合 IP2Location LITE 數據庫,您不僅優化了系統效能,更是在數位邊界築起了一道牢不可破的圍籬。

「掌控數據的人,才能掌握未來的利潤。」

發佈日期:

LINE Notify

Views: 3

Notify 是 Line 官方推出的專門用來推送訊息的一個服務,使用起來非常簡單,甚至不需要安裝什麼套件,只需要能夠送出 URL 請求即可。

申請方式很簡單,登入到 LINE Notify 功能頁面後,點選「發行權杖」即可。

權杖名稱及要通知的聊天室(產生一串 Token 複製起來)。

然後~ 可以使用 Shell Script 及 curl 來實作。


# 簡單範例參考:
TODAY=`date +%m/%d_%H:%M`
xmessage="$TODAY 服務器CHECK異常"
xx="message="$xmessage
curl -H "Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" -d "$xx" https://notify-api.line.me/api/notify
發佈日期:

Code Snippets 筆記

Views: 6

添加到 header.php
add_action( ‘wp_head’, function () { ?>
//
<?php } );


添加到footer.php
add_action( ‘wp_footer’, function () { ?>

<?php } );


添加CSS
add_action( ‘wp_head’, function () { ?>
//<style>
// write your CSS code here
//</style><?php } );


add_shortcode( ‘ending’, function () {
//php code
} );


add_action( ‘after_setup_theme’, function() {
//php code
});


加入你的 wp-config.php 檔案
define (‘EMPTY_TRASH_DAYS’, 7);清空回收桶
define (‘EMPTY_TRASH_DAYS’, 0);停用回收桶
define( ‘WP_POST_REVISIONS’, 3 );減少文章版本
define( ‘WP_POST_REVISIONS’, false );停用文章版本功能
define( ‘AUTOSAVE_INTERVAL’, 60 ); // 秒自動儲存你的文章和頁面
define( ‘WP_DEBUG’, true );開啟 PHP 除錯工具
define( ‘SCRIPT_DEBUG’, true ); 開啟 CSS 和 JavaScript 除錯工具
define(‘WP_SITEURL’, ‘http://www.chungg.com’);指定網站網址
define(‘WP_HOME’, ‘http://www.chungg.com/wordpress’);指定 WordPress 網址(安裝目錄)
define( ‘WP_CACHE’, true );啟用 WP 快取
define( ‘WP_ALLOW_MULTISITE’, true );啟用 WordPress 多網站
define( ‘NOBLOGREDIRECT’, ‘http://www.chungg.com’ );重新導向不存在的子網域和子目錄
define( ‘WP_ALLOW_REPAIR’, true );啟用內建資料庫最佳化功能
define( ‘AUTOMATIC_UPDATER_DISABLED’, true );停用所有自動更新
define( ‘WP_AUTO_UPDATE_CORE’, false );停用所有核心更新
define( ‘WP_AUTO_UPDATE_CORE’, true );啟用所有核心更新,包括跨版本更新及主要更新
define( ‘WP_AUTO_UPDATE_CORE’, ‘minor’ );啟用核心更新,但只針對安全性更新(預設)
define( ‘WP_MEMORY_LIMIT’, ’96M’ );為網站設定記憶體限制
define( ‘WP_MAX_MEMORY_LIMIT’, ‘128M’ );為控制台設定記憶體限制
define( ‘FORCE_SSL_ADMIN’, true );強制 SSL 模式登入
define( ‘DISALLOW_FILE_EDIT’, true );停用外掛和佈景主題編輯器
define( ‘DISALLOW_FILE_MODS’, true );停用外掛和佈景主題編輯器,加上外掛和佈景主題更新,所以如果你啟用這項設定,就不用再額外加入 DISALLOW_FILE_EDIT。
define( ‘IMAGE_EDIT_OVERWRITE’, true );清理圖片編輯
define( ‘DISALLOW_UNFILTERED_HTML’, true );禁止編審和系統管理員使用未篩選的 HTML

將 wp-content 目錄移動到其他路徑
define( ‘WP_CONTENT_DIR’, dirname(__FILE__) . ‘/new/wp-content’ );
或define( ‘WP_CONTENT_URL’, ‘https://www.chungg.com/new/wp-content’ );
重新命名你的 wp-content 目錄:define (‘WP_CONTENT_FOLDERNAME’, ‘newfoldername’);並非 100% 可行,因為很多 WordPress 外掛開發者已將 “wp-content” 路徑寫死在外掛的程式碼裡。


加入佈景主題的 functions.php 檔

將作者頁面鏈結重新導向「關於」頁面
add_filter( ‘author_link’, ‘my_author_link’ );
function my_author_link() {
return home_url( ‘about’ );
}

當搜尋結果只有一篇文章時自動連到文章
add_action(‘template_redirect’, ‘redirect_single_post’);
function redirect_single_post() {
if (is_search()) {
global $wp_query;
if ($wp_query->post_count == 1 && $wp_query->max_num_pages == 1) {
wp_redirect( get_permalink( $wp_query->posts[‘0’]->ID ) );
exit;
}
}
}

將頁面從 WordPress 搜尋結果排除
function filter_search($query) {
if ($query->is_search) {
$query->set(‘post_type’, ‘post’);
}
return $query;
}
add_filter(‘pre_get_posts’, ‘filter_search’);

從你的迴響表單移除網址欄位
function remove_comment_fields($fields) {
unset($fields[‘url’]);
return $fields;
}
add_filter(‘comment_form_default_fields’,’remove_comment_fields’);

為迴響內容設定最少字數限制
add_filter( ‘preprocess_comment’, ‘minimal_comment_length’ );
function minimal_comment_length( $commentdata ) {
$minimalCommentLength = 20;
if ( strlen( trim( $commentdata[‘comment_content’] ) ) < $minimalCommentLength ){
wp_die( ‘所有留言必須大於 ‘ . $minimalCommentLength . ‘ 個字元長度。’ );
}
return $commentdata;
}


●註冊時加一個驗證輸入欄位,防止一些垃圾人。
add_action( 'register_form', 'add_security_question' );
function add_security_question() { ?>

add_action( 'register_post', 'add_security_question_validate', 10, 3 );
function add_security_question_validate( $sanitized_user_login, $user_email, $errors) {
// 如果没有回答
if (!isset($_POST[ 'user_proof' ]) || empty($_POST[ 'user_proof' ])) {
return $errors->add( 'proofempty', '❌ 錯誤: 您沒有回答「這個網站是那個公司的」?。' );

// 如果答案不正確
} elseif ( strtolower( $_POST[ 'user_proof' ] ) != '忠碁' ) {
return $errors->add( 'prooffail', '❌ 錯誤: 您的回答不正確喔!。');
}
}

發佈日期:

備份記錄檢查表

Views: 11

本司用 Robocopy 為備機機制時,可搭配Apache2 + PHP 做一個備份檢查表,讓每日檢查人員簡單的得知是否有備份及其它資訊。

備份記錄表
備份記錄表

(1).依不同備份專案名下拉選擇 例如:會計備份、工程備份、外部備份、主機2
(2).專案名下拉選擇項目數量
(3).Prev 往前一個月的記錄
(4).Next 往後一個月的記錄
(5).本月 回到本月記錄
(6).日期有綠背景色就代表有找到備份記錄檔,但,不代表就有備份仍要依 目錄/檔案 這二行的數字再做參考
(7).可點選檔名後方的日期把原始LOG記錄檔下載下來

發佈日期:

PHP_AUTH_USER_PHP_AUTH_PW

Views: 2

$_SERVER[‘PHP_AUTH_USER’] 及 $_SERVER[‘PHP_AUTH_PW’] 空值,無法用! 怎麼輸入都無效時

在目錄下建一個.htaccess檔,內容如下:
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* – [e=HTTP_AUTHORIZATION:%1]

發佈日期:

PHP的short_open_tag

Views: 2

【開發思維】從繁瑣到精簡:善用 short_open_tag 優化你的代碼視覺美學

在追求極致性能的開發路上,身為程式碼設計師,我們不僅在乎邏輯的嚴謹,更在乎「程式碼的可讀性與節奏感」

為什麼你該關注這個小調整?

PHP 的 short_open_tag 設定,雖然只是一個開關,卻能直接影響視圖層(View)的代碼乾淨程度。當我們將其從預設的 Off 調整為 On 時,你將解鎖更具現代感的開發語法。

視覺對比:從冗長到優雅

  • 傳統寫法(標準模式):
    繁瑣的聲明,在大量嵌入變數的 HTML 中會造成視覺混亂。
    <?php echo $data; ?>
  • 精簡寫法(啟用 Short Open Tag):
    像設計一樣純粹,直觀呈現資料核心。
    <?=$data;?>

設計思維:為什麼這很重要?

  1. 降低視覺噪音:當一個樣板檔(Template)需要頻繁渲染變數時,減少重複的 php echo 字眼,能讓開發者更專注於資料結構而非語法標記。
  2. 提升掃視效率:簡潔的符號有助於在數百行代碼中快速定位邏輯與變數,縮短維護時的認知負荷。
  3. 累積的力量:單次節省的字元或許微不足道,但在大型專案中,成千上萬次的簡化將構成更清爽、更具一致性的程式碼美學。

技術小提醒:
欲啟用此功能,請至 PHP 官方文件 參考 php.ini 設定說明。請注意,若您的專案需頻繁更換伺服器環境或開發標準套件,建議先確認環境相容性,以確保這份優雅能持續延續。


想了解如何在現有專案中快速掃描並重構這些語法標籤嗎?

發佈日期:

【Arduino】不用模組純代碼實現方波驅動蜂鳴器

Views: 5

【Arduino 知識分享】擺脫模組束縛:純代碼實現 Pin 8 方波驅動蜂鳴器

在 Arduino 的專案開發中,許多初學者習慣購買現成的「蜂鳴器模組」。雖然模組方便,但若能直接透過單片機的 I/O 腳位精確控制方波(Square Wave),不僅能減少硬體體積,更能讓你深入理解頻率與音調的物理關係。

今天我們分享如何透過 Arduino Pin 8 直接輸出方波,在不使用外部驅動模組的情況下,控制一個無源蜂鳴器(Passive Buzzer)發出聲音。

💡 核心知識點

  • 無源蜂鳴器 vs 有源蜂鳴器:有源蜂鳴器通電即響,而無源蜂鳴器需要給予特定頻率的「方波」訊號才能震動發聲。
  • 方波輸出(tone 函式):Arduino 內建的 tone() 函式可以產生指定頻率的方波,其原理是快速切換高低電平(HIGH/LOW)來模擬音調。
  • 硬體精簡:僅需 Arduino 開發板與一個蜂鳴器,正極接 Pin 8,負極接 GND 即可完成實驗。

💻 Arduino.ino 完整範例程式碼

本範例展示如何循環輸出一個 1kHz(1000Hz)的音頻訊號。

/*
 * 專案名稱:Arduino Pin 8 方波驅動蜂鳴器範例
 * 功能說明:不使用外部模組,直接透過代碼控制無源蜂鳴器發聲
 */

const int buzzerPin = 8; // 定義蜂鳴器連接在數位腳位 8

void setup() {
  // 將 Pin 8 設置為輸出模式
  pinMode(buzzerPin, OUTPUT);
}

void loop() {
  // 1. 使用內建 tone 函式:頻率 1000 Hz (1kHz),持續 500 毫秒
  tone(buzzerPin, 1000); 
  delay(500); 

  // 2. 停止輸出 500 毫秒
  noTone(buzzerPin);
  delay(500);

  /* 
   * [進階知識] 也可以手動用 digitalWrite 模擬方波:
   * digitalWrite(buzzerPin, HIGH);
   * delayMicroseconds(500); // 1000Hz 的半週期約為 500us
   * digitalWrite(buzzerPin, LOW);
   * delayMicroseconds(500);
   */
}

🛠️ 實作小貼士

  1. 限流保護:為了保護 Arduino 腳位,建議在蜂鳴器正極串聯一個 220Ω ~ 1kΩ 的電阻。
  2. 音調調整:修改 tone(buzzerPin, 頻率) 中的頻率數值,例如 262Hz 為中央 C(Do),440Hz 為標準 A 音(La)。
  3. 多腳位限制:請注意,tone() 函式同一時間只能在一個腳位產生聲音。

這種類型的知識分享對您的有幫助嗎?如果您需要特定的旋律代碼或是進階的硬體接線圖說明,歡迎隨時告知!