發佈日期:

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

Views: 8

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

📖 故事的開頭…

最近電腦開機一段時間後,發現記憶體使用了近 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: 5

為什麼您的 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: 6

【頂層邏輯】數位資產的隱形門衛: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: 0

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: 3

添加到 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: 6

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

備份記錄表
備份記錄表

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

發佈日期:

PHP_AUTH_USER_PHP_AUTH_PW

Views: 0

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

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

發佈日期:

PHP的short_open_tag

Views: 0

【開發思維】從繁瑣到精簡:善用 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: 3

【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() 函式同一時間只能在一個腳位產生聲音。

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

發佈日期:

安裝 .NET Framework 是有順序的

Views: 2

.NET Framework 4 可以與舊版的 .NET Framework 並存安裝在單一電腦上。 如果先前已在電腦上啟用 IIS,.NET Framework 的安裝程序就會自動在 IIS 註冊 ASP.NET 4。 不過,如果在啟用 IIS 之前安裝 .NET Framework 4,您必須執行 ASP.NET IIS 註冊工具,才能在 IIS 註冊 .NET Framework,並建立使用 .NET Framework 4 的應用程式集區。

錯誤範例動作:先安裝了.NET Framework4.0 => 安裝IIS角色又裝了.NET Framework 3.5,然後網站就出現:

無法從組件 ‘System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’ 載入型別 ‘System.ServiceModel.Activation.HttpModule’。

解決步驟如下:
1.開啟命令提示字元視窗。
2.然後指定作業路徑至C:\Windows\Microsoft.NET\Framework\v4.0.30319。
3.輸入【aspnet_regiis -i】後按ENTER。
4.再到IIS重新啟動 (iisreset)!

相關連結:
ASP.NET IIS 註冊工具(Aspnet_regiis.exe)