ファイナンス、情報通信技術のスキル・アグリゲーション・サイト
PHP で MQTT クライアントを作成します。ブローカーには、Mosquitto を使用していますので、php-mqtt/client ライブラリを利用しました。
「PHP で MQTT クライアント(Mosquitto-PHP)」で使用している Mosquitto-PHP ライブラリは、PHP 8.3 まではインストール可能でしたが、それ以降のバージョン PHP 8.4、PHP 8.5 ではインストールに失敗します。そこで、php-mqtt/client ライブラリに移行しました。
まず、PHP の依存管理ツールである Composer のインストール方法と、MQTT クライアントライブラリ php-mqtt/client の導入方法、さらに簡単な使用例を紹介します。
さらに、php-mqtt/client を使った以下の応用例を示します。
Composer は PHP の標準的なパッケージ管理ツールです。以下の手順でインストールできます。
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
sudo mv composer.phar /usr/local/bin/composer
これで composer コマンドがシステム全体で利用できます。
Composer を使って MQTT クライアントライブラリをインストールします。
mkdir mqtt-test
cd mqtt-test
composer require php-mqtt/client
これで vendor/ ディレクトリにライブラリが追加され、
autoload.php を読み込むことで利用できるようになります。
以下は、MQTT ブローカーに接続してメッセージを送信する最小構成の例です。
<?php
require __DIR__ . '/vendor/autoload.php';
use PhpMqtt\Client\MqttClient;
use PhpMqtt\Client\ConnectionSettings;
$server = 'localhost'; // MQTT ブローカーのホスト
$port = 1883; // ポート
$clientId = 'php-mqtt-publisher';
$connectionSettings = (new ConnectionSettings)
->setUsername(null)
->setPassword(null)
->setKeepAliveInterval(60);
$client = new MqttClient($server, $port, $clientId);
$client->connect($connectionSettings, true);
$client->publish('test/topic', 'Hello MQTT from PHP!', 0);
$client->disconnect();
<?php
require __DIR__ . '/vendor/autoload.php';
use PhpMqtt\Client\MqttClient;
use PhpMqtt\Client\ConnectionSettings;
$server = 'localhost';
$port = 1883;
$clientId = 'php-mqtt-subscriber';
$connectionSettings = (new ConnectionSettings)
->setKeepAliveInterval(60);
$client = new MqttClient($server, $port, $clientId);
$client->connect($connectionSettings, true);
$client->subscribe('test/topic', function ($topic, $message) {
echo "Received on {$topic}: {$message}\n";
}, 0);
$client->loop(true); // 無限ループで待機
これで PHP から MQTT ブローカーに接続し、 メッセージの送受信ができるようになります。
QoS(Quality of Service)は MQTT の配信品質レベルです。代表的には以下の 3 つがあります。
<?php
require __DIR__ . '/vendor/autoload.php';
use PhpMqtt\Client\MqttClient;
use PhpMqtt\Client\ConnectionSettings;
$server = 'localhost';
$port = 1883;
$clientId = 'php-mqtt-publisher-qos1';
$connectionSettings = (new ConnectionSettings)
->setKeepAliveInterval(60);
$client = new MqttClient($server, $port, $clientId);
$client->connect($connectionSettings, true);
// QoS 1 で publish
$topic = 'demo/qos';
$message = 'Message with QoS 1';
$client->publish($topic, $message, 1, false);
$client->disconnect();
<?php
require __DIR__ . '/vendor/autoload.php';
use PhpMqtt\Client\MqttClient;
use PhpMqtt\Client\ConnectionSettings;
$server = 'localhost';
$port = 1883;
$clientId = 'php-mqtt-subscriber-qos2';
$connectionSettings = (new ConnectionSettings)
->setKeepAliveInterval(60);
$client = new MqttClient($server, $port, $clientId);
$client->connect($connectionSettings, true);
// QoS 2 で subscribe
$client->subscribe('demo/qos', function (string $topic, string $message) {
echo "Received on {$topic} (QoS2): {$message}\n";
}, 2);
$client->loop(true);
MQTT ブローカー側でユーザー認証が有効な場合、ConnectionSettings に
ユーザー名とパスワードを設定します。
<?php
require __DIR__ . '/vendor/autoload.php';
use PhpMqtt\Client\MqttClient;
use PhpMqtt\Client\ConnectionSettings;
$server = 'mqtt.example.com';
$port = 1883;
$clientId = 'php-mqtt-auth-publisher';
$username = 'myuser';
$password = 'mypassword';
$connectionSettings = (new ConnectionSettings)
->setUsername($username)
->setPassword($password)
->setKeepAliveInterval(60);
$client = new MqttClient($server, $port, $clientId);
$client->connect($connectionSettings, true);
$client->publish('secure/topic', 'Authenticated message', 1, false);
$client->disconnect();
<?php
require __DIR__ . '/vendor/autoload.php';
use PhpMqtt\Client\MqttClient;
use PhpMqtt\Client\ConnectionSettings;
$server = 'mqtt.example.com';
$port = 1883;
$clientId = 'php-mqtt-auth-subscriber';
$username = 'myuser';
$password = 'mypassword';
$connectionSettings = (new ConnectionSettings)
->setUsername($username)
->setPassword($password)
->setKeepAliveInterval(60);
$client = new MqttClient($server, $port, $clientId);
$client->connect($connectionSettings, true);
$client->subscribe('secure/topic', function (string $topic, string $message) {
echo "Received (auth): {$topic} => {$message}\n";
}, 1);
$client->loop(true);
TLS を使うことで、MQTT 通信を暗号化できます。多くのブローカーでは ポート 8883 が TLS 用に使われます。
ブローカーが正式な CA で署名された証明書を使っている場合の、最小構成の例です。
<?php
require __DIR__ . '/vendor/autoload.php';
use PhpMqtt\Client\MqttClient;
use PhpMqtt\Client\ConnectionSettings;
$server = 'mqtts.example.com'; // TLS 対応ブローカー
$port = 8883; // TLS ポート
$clientId = 'php-mqtt-tls-client';
$connectionSettings = (new ConnectionSettings)
->setUseTls(true) // TLS を有効化
->setTlsVerifyPeer(true) // 証明書の検証を有効
->setTlsVerifyPeerName(true) // ホスト名検証を有効
->setKeepAliveInterval(60);
$client = new MqttClient($server, $port, $clientId);
$client->connect($connectionSettings, true);
$client->publish('tls/topic', 'Hello over TLS', 1, false);
$client->disconnect();
自己署名証明書を使う場合は、検証方法を緩めたり、独自 CA を指定します。
<?php
require __DIR__ . '/vendor/autoload.php';
use PhpMqtt\Client\MqttClient;
use PhpMqtt\Client\ConnectionSettings;
$server = 'mqtts.local';
$port = 8883;
$clientId = 'php-mqtt-tls-selfsigned';
$connectionSettings = (new ConnectionSettings)
->setUseTls(true)
// 自己署名証明書を許可
->setTlsSelfSignedAllowed(true)
// 必要に応じて CA ファイルやパスを指定
->setTlsCertificateAuthorityFile('/path/to/ca.crt')
// ホスト名検証を無効にする場合(開発用途など)
->setTlsVerifyPeerName(false)
->setKeepAliveInterval(60);
$client = new MqttClient($server, $port, $clientId);
$client->connect($connectionSettings, true);
$client->subscribe('tls/selfsigned', function (string $topic, string $message) {
echo "TLS (self-signed) {$topic}: {$message}\n";
}, 1);
$client->loop(true);
ブローカーがクライアント証明書による認証を要求する場合は、 クライアント証明書と秘密鍵を設定します。
<?php
require __DIR__ . '/vendor/autoload.php';
use PhpMqtt\Client\MqttClient;
use PhpMqtt\Client\ConnectionSettings;
$server = 'mqtts.example.com';
$port = 8883;
$clientId = 'php-mqtt-tls-mutual';
$connectionSettings = (new ConnectionSettings)
->setUseTls(true)
->setTlsVerifyPeer(true)
->setTlsVerifyPeerName(true)
->setTlsCertificateAuthorityFile('/path/to/ca.crt')
// クライアント証明書と秘密鍵
->setTlsClientCertificateFile('/path/to/client.crt')
->setTlsClientCertificateKeyFile('/path/to/client.key')
// 鍵にパスフレーズがある場合
// ->setTlsClientCertificateKeyPassphrase('secret-passphrase')
->setKeepAliveInterval(60);
$client = new MqttClient($server, $port, $clientId);
$client->connect($connectionSettings, true);
$client->publish('tls/mutual', 'Mutual TLS message', 1, false);
$client->disconnect();