在物聯網(IoT)的實作中,我們常常需要一個集中化的管理平台來即時查看感測器數據,或者遠端控制硬體設備(例如繼電器)。雖然市面上有很多現成的雲端物聯網平台(如 ThingSpeak 或 Adafruit IO),但如果您想擁有完全的控制權、自訂漂亮的版面,且不希望受到數據傳輸量的限制,自建平台是最佳選擇!
本教學將帶您利用最流行的 WordPress 網站系統,結合 MQTT 協定與 Node-Red 中介軟體,打造一個專屬的遠端物聯網監控與控制平台。
本文學習重點:
- WordPress 平台快速建置(使用 Docker Compose)
- 安裝 PHP 環境的 MQTT 函式庫(php-mqtt/client)
- 撰寫前端監控 MQTT 的 PHP 程式(配合 MQTT Lens 測試)
- 撰寫 WordPress 後端控制台監控外掛
- 配合 Node-Red 進行 MQTT 與資料庫的雙向串接
系統架構設計
在開始建置之前,讓我們先看一下系統的資料流向架構圖:

在這個架構中:
- 感測器/硬體設備:發布(Publish)感測數據到 MQTT Broker,並訂閱(Subscribe)控制指令主題。
- Node-Red:作為中介橋樑,隨時訂閱 MQTT 數據,並將其自動寫入 WordPress 資料庫(MySQL)中。
- WordPress 網站:
- 前端網頁/後端控制台:直接從 MySQL 讀取最新的感測器數據並顯示。
- 控制按鈕:按下按鈕時,透過
publish.php呼叫 PHP MQTT 客戶端,將控制訊號發布給 MQTT 經紀人(Broker),進而即時控制硬體繼電器。
一、WordPress 平台建置 (Docker Compose)
我推薦使用 Docker Compose 在 Portainer 上快速部署 WordPress 與 MySQL 資料庫。以下是建置 Stacks 的 YAML 設定檔:
version: '3.3'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: your_root_password
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress_user
MYSQL_PASSWORD: wordpress_password
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8080:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress_user
WORDPRESS_DB_PASSWORD: wordpress_password
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress_data:/var/www/html
volumes:
db_data:
wordpress_data:
Portainer 部署步驟:
- 進入 Portainer 管理介面,選擇 Stacks → Add stack。
- 填入 Stack 名稱(例如
wp-iot-site),並將上述的 YAML 內容貼入編輯器中。 - 依照您的需求,修改
WORDPRESS_DB_USER與相關密碼設定,接著點選下方 「Deploy the stack」 部署。


- 安裝完成後,可以使用 Nginx Proxy Manager 等反向代理工具設定域名(DNS),即可連線至您的域名開始設定 WordPress 初始安裝步驟。

二、安裝 PHP 環境的 MQTTClient
為了讓 WordPress 能夠發送和接收 MQTT 訊息,我們需要使用 PHP 的 MQTT 客戶端函式庫(這裡推薦使用 php-mqtt/client)。
- 進入 WordPress 容器的 Terminal 終端機模式(在 Portainer 中點擊網頁版 Console 圖示)。

- 按下 「Connect」 連接:

- 因為是全新的 Linux 環境,我們先安裝
vim與zip/unzip等基本工具:
apt-get update
apt-get install -y vim zip unzip
- 接著,切換到 WordPress 的外掛目錄
/wp-content/plugins/,建立一個名為mqttconn的自訂外掛資料夾:
cd /var/www/html/wp-content/plugins/
mkdir mqttconn
cd mqttconn
- 在該目錄下,我們要使用 Composer 來安裝
php-mqtt/client:
# 如果系統中沒有 Composer,可以快速下載並安裝
curl -sS https://getcomposer.org/installer | php
# 使用 composer 安裝 php-mqtt 函式庫
php composer.phar require php-mqtt/client

三、撰寫前端監控 PHP 程式
1. 安裝 PHP 代碼插入外掛
為了能在 WordPress 網頁中直接插入 PHP 程式碼,我們需要安裝一個安全的外掛:Insert PHP Code Snippet。這個外掛可以讓您將 PHP 程式碼打包成一個 Shortcode(短代碼),非常方便在一般頁面或區塊編輯器中使用。

2. 撰寫 MQTT 發送腳本 (publish.php)
在 /var/www/html/ 目錄下建立一個 publish.php 檔案,當使用者在網頁上點擊控制按鈕時,網頁會透過 Ajax 請求此檔案,向 MQTT Broker 發送控制指令:
<?php
// 引入 composer 自動載入檔
require_once __DIR__ . '/wp-content/plugins/mqttconn/vendor/autoload.php';
use PhpMqtt\Client\MqttClient;
use PhpMqtt\Client\ConnectionSettings;
// 取得 Ajax 傳入的參數值
$action = isset($_GET['action']) ? $_GET['action'] : '';
if ($action === 'on' || $action === 'off') {
$server = 'your_mqtt_broker_ip'; // MQTT Broker 的 IP 或是域名
$port = 1883; // 連接埠
$clientId = 'wp_web_client_' . rand(1, 1000);
$mqtt = new MqttClient($server, $port, $clientId);
$connectionSettings = (new ConnectionSettings())
->setKeepAliveInterval(60)
->setLastWillTopic('last/will')
->setLastWillMessage('client disconnected')
->setLastWillQualityOfService(1);
$mqtt->connect($connectionSettings, true);
// 將 action (on/off) 發布至指定的 MQTT 主題
$mqtt->publish('office/relay1', $action, 0);
$mqtt->disconnect();
echo json_encode(['status' => 'success', 'message' => 'Relay set to ' . $action]);
} else {
echo json_encode(['status' => 'error', 'message' => 'Invalid action']);
}

3. 在 Snippet 外掛中建立前端控制介面
打開 WordPress 後台的 PHP Code Snippets 面板,點擊「Add New PHP Code Snippet」,建立一個名為 mqtt_front_control 的片段,內容貼上以下 HTML/PHP/JS 混排程式:
<?php
global $wpdb;
// 自資料庫中取得最新的感測器數據(這裡以資料表 iot_sensor_data 為例)
$latest_data = $wpdb->get_row("SELECT * FROM iot_sensor_data ORDER BY id DESC LIMIT 1");
$temperature = $latest_data ? $latest_data->temperature : '--';
$humidity = $latest_data ? $latest_data->humidity : '--';
?>
<div style="background: #1e293b; color: #fff; padding: 2rem; border-radius: 12px; max-width: 500px; margin: 1.5rem auto; font-family: system-ui;">
<h3 style="margin-top: 0; color: #38bdf8; text-align: center;">遠端辦公室監控面板</h3>
<div style="display: flex; justify-content: space-around; margin: 1.5rem 0;">
<div style="text-align: center;">
<div style="font-size: 0.85rem; color: #94a3b8;">即時溫度</div>
<div style="font-size: 2.2rem; font-weight: bold; color: #f43f5e;" id="temp-val"><?php echo $temperature; ?> °C</div>
</div>
<div style="text-align: center;">
<div style="font-size: 0.85rem; color: #94a3b8;">即時濕度</div>
<div style="font-size: 2.2rem; font-weight: bold; color: #0ea5e9;" id="hum-val"><?php echo $humidity; ?> %</div>
</div>
</div>
<hr style="border-color: #334155; margin: 1.5rem 0;">
<h4 style="text-align: center; margin-bottom: 1rem;">電器遠端控制</h4>
<div style="display: flex; justify-content: center; gap: 1rem;">
<button onclick="controlRelay('on')" style="background: #22c55e; color: white; border: none; padding: 0.75rem 2rem; border-radius: 6px; font-weight: bold; cursor: pointer; transition: 0.2s;" onmouseover="this.style.opacity=0.9" onmouseout="this.style.opacity=1">開啟繼電器</button>
<button onclick="controlRelay('off')" style="background: #ef4444; color: white; border: none; padding: 0.75rem 2rem; border-radius: 6px; font-weight: bold; cursor: pointer; transition: 0.2s;" onmouseover="this.style.opacity=0.9" onmouseout="this.style.opacity=1">關閉繼電器</button>
</div>
<div id="control-status" style="text-align: center; margin-top: 1rem; font-size: 0.9rem; color: #94a3b8;"></div>
</div>
<script>
function controlRelay(action) {
const statusDiv = document.getElementById('control-status');
statusDiv.innerText = '傳送指令中...';
fetch('/publish.php?action=' + action)
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
statusDiv.innerHTML = '<span style="color: #22c55e;">指令傳送成功:繼電器已' + (action === 'on' ? '開啟' : '關閉') + '</span>';
} else {
statusDiv.innerHTML = '<span style="color: #ef4444;">錯誤: ' + data.message + '</span>';
}
})
.catch(err => {
statusDiv.innerHTML = '<span style="color: #ef4444;">連線失敗</span>';
console.error(err);
});
}
</script>

4. 插入短代碼到網頁中
儲存後,會獲得一個 Shortcode(例如 [xyz-ips snippet="mqtt-front-control"])。只要將其複製並貼在您希望顯示監控面板的 WordPress 頁面即可。

四、配合 Node-Red 進行後端自動化處理
為了讓資料庫的數據隨時保持最新,我們需要一個後端訂閱服務。雖然可以直接用 PHP 寫一個無窮迴圈的訂閱 daemon,但更推薦且最穩定的方式是搭配 Node-Red:
1. 建立資料表 (MySQL)
我們需要在 WordPress 所在的 MySQL 資料庫中,新增一個用於存放感測器數據的資料表:
CREATE TABLE `iot_sensor_data` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`temperature` float NOT NULL,
`humidity` float NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

2. Node-Red 架構設定
在 Docker 中快速啟動一個 Node-Red 容器,並在 Stacks 中設定它連線至同一個網絡環境下:

拉取以下節點建置資料流:
- MQTT in:訂閱感測器發布的 Topic(如
office/sensor)。 - Function:將接收到的 JSON 格式感測數據(含溫度與濕度),轉換為 MySQL 寫入語法:
var data = JSON.parse(msg.payload);
msg.topic = "INSERT INTO iot_sensor_data (temperature, humidity) VALUES (" + data.temp + ", " + data.hum + ");";
return msg;
- MySQL Node:執行該 SQL 指令,將數據寫入 WordPress 的資料庫中。

現在只要感測器每隔幾秒發送一次數值,Node-Red 就會即時自動寫入資料庫,WordPress 的前端監控頁面就能隨時讀取最新數值!
五、撰寫後端控制台監控外掛
如果您不想讓這些監控和控制功能對前台讀者公開,最佳的做法是將它們做成一個 WordPress 後端控制台(Dashboard)選單頁面。我們可以透過編寫一個簡單的自訂外掛來實現。
在剛才建立的 /wp-content/plugins/mqttconn/ 下,建立主外掛檔案 mqttconn.php:
<?php
/*
Plugin Name: MQTT Web Controller
Description: 專屬物聯網 MQTT 雙向監控與 Relay 控制後台外掛
Version: 1.0
Author: Terry Lee
*/
if (!defined('ABSPATH')) {
exit;
}
// 註冊控制台選單項目
add_action('admin_menu', 'mqtt_controller_menu');
function mqtt_controller_menu() {
add_menu_page(
'物聯網監控中心', // 瀏覽器標題
'物聯網監控', // 後台選單顯示文字
'manage_options', // 權限要求
'mqtt-monitor-page', // 網址 Slug
'mqtt_monitor_page_html', // 顯示內容的 Callback 函數
'dashicons-cloud', // 選單圖示
6 // 位置順序
);
}
function mqtt_monitor_page_html() {
global $wpdb;
$latest_data = $wpdb->get_row("SELECT * FROM iot_sensor_data ORDER BY id DESC LIMIT 1");
$temperature = $latest_data ? $latest_data->temperature : '--';
$humidity = $latest_data ? $latest_data->humidity : '--';
?>
<div class="wrap">
<h1>物聯網監控管理後台</h1>
<p>在這裡您可以即時監看辦公室的環境感測數據,並對連接的硬體設備送出控制指令。</p>
<div style="background: #fff; padding: 20px; border: 1px solid #ccd0d4; border-radius: 4px; max-width: 600px; margin-top: 20px;">
<h2>環境數據狀態 (MQTT)</h2>
<table class="form-table">
<tr>
<th>即時溫度</th>
<td><strong style="font-size: 24px; color: #d94f5c;"><?php echo $temperature; ?> °C</strong></td>
</tr>
<tr>
<th>即時濕度</th>
<td><strong style="font-size: 24px; color: #2b7bb9;"><?php echo $humidity; ?> %</strong></td>
</tr>
</table>
<hr>
<h2>遠端電器控制 (Relay 繼電器)</h2>
<p>點選下方按鈕,向 MQTT Topic <code>office/relay1</code> 發送控制指令:</p>
<div style="margin: 20px 0;">
<button onclick="controlRelay('on')" class="button button-primary button-large" style="background:#46b450; border-color:#46b450; text-shadow:none;">開啟繼電器</button>
<button onclick="controlRelay('off')" class="button button-secondary button-large" style="background:#dc3232; border-color:#dc3232; color:#fff; text-shadow:none; margin-left:10px;">關閉繼電器</button>
</div>
<div id="control-status" style="font-weight: bold; margin-top: 15px; color: #555;"></div>
</div>
</div>
<script>
function controlRelay(action) {
const statusDiv = document.getElementById('control-status');
statusDiv.innerText = '傳送 MQTT 指令中...';
jQuery.ajax({
url: '/publish.php',
data: { action: action },
dataType: 'json',
success: function(data) {
if (data.status === 'success') {
statusDiv.innerHTML = '<span style="color: #46b450;">✔ 指令傳送成功:繼電器已' + (action === 'on' ? '開啟' : '關閉') + '</span>';
} else {
statusDiv.innerHTML = '<span style="color: #dc3232;">❌ 錯誤: ' + data.message + '</span>';
}
},
error: function() {
statusDiv.innerHTML = '<span style="color: #dc3232;">❌ 伺服器通訊失敗</span>';
}
});
}
</script>
<?php
}


啟用與測試後台面板
- 進入 WordPress 後台,點選 「外掛」 列表,會看到我們剛才建立的 「MQTT Web Controller」 外掛。
- 點選 「啟用」。

- 啟用後,左側側邊欄會出現 「物聯網監控」 功能選單。點擊進去,即可看到專屬的後台監控與繼電器開關控制介面!

結論與展示影片
本篇文章說明了如何將一個普通的 WordPress 網站改造成功能強大的物聯網即時雙向監控與控制平台。透過 PHP-MQTT 函式庫可以主動發送控制訊號至硬體,而利用 Node-Red 監聽 MQTT 訂閱並寫入 MySQL,讓前台及後端網頁能即時查看環境中的溫濕度感測器數值。
您可以配合 Chrome / 擴充套件的 MQTT Lens 來模擬 publish/subscribe 發送和接收 MQTT 訊息進行測試。
如果您對本系統的建置需要更詳細的實作細節,我特別錄製了一段操作展示與設定說明的 YouTube 影片,歡迎觀看:
如果您在建置專屬 IoT 平台的過程中有任何問題,或者有特殊的物聯網需求,非常歡迎與我聯絡討論!



