2024 日本 PHP 研討會

msg_send

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

msg_send傳送訊息到訊息佇列

說明

msg_send(
    SysvMessageQueue $queue,
    int $message_type,
    string|int|float|bool $message,
    bool $serialize = true,
    布林值 $blocking = true,
    整數 &$error_code = null
): 布林值

msg_send() 會將類型為 message_type(必須大於 0)的 message 發送到由 queue 指定的訊息佇列。

參數

queue

訊息佇列。

message_type

訊息的類型(必須大於 0)

message

訊息的內容。

注意事項:

如果 serialize 設定為 false,則 message 的類型必須為:字串整數浮點數布林值。否則會發出警告。

serialize

可選的 serialize 參數控制 message 的發送方式。 serialize 預設為 true,這表示 message 在發送到佇列之前會使用與 session 模組相同的機制進行序列化。這允許將複雜的陣列和物件發送到其他 PHP 腳本,或者如果您使用的是 WDDX 序列化器,則可以發送到任何與 WDDX 相容的客戶端。

blocking

如果訊息太大而無法放入佇列,您的腳本將會等待,直到另一個程序從佇列中讀取訊息並釋放足夠的空間來發送您的訊息。這稱為阻塞;您可以透過將可選的 blocking 參數設定為 false 來防止阻塞,在這種情況下,如果訊息對於佇列而言太大,msg_send() 將立即返回 false,並將可選的 error_code 設定為 MSG_EAGAIN,表示您應該稍後再嘗試發送訊息。

error_code

如果函式執行失敗,可選的 error_code 將會被設定為系統 errno 變數的值。

返回值

成功時返回 true,失敗時返回 false

成功完成後,訊息佇列資料結構將會更新如下:msg_lspid 設定為呼叫程序的程序 ID,msg_qnum 增加 1,msg_stime 設定為目前時間。

更新日誌

版本 說明
8.0.0 queue 現在需要一個 SysvMessageQueue 實例;以前需要的是 資源

參見

新增註釋

使用者貢獻的註釋 3 則註釋

qeekin at gmail dot com
10 年前
我建立了一個範例,示範如何透過訊息佇列與以 C 語言編寫的程式進行通訊。首先執行 C 程式(它會建立佇列),然後執行 PHP 腳本。

C 程式碼編譯方式: gcc -std=c99 -o test_queue test_queue.c

test_queue.c
/**
* 使用 PHP 和 C 程式使用 System V 訊息佇列的範例。
* 這是一個簡單的伺服器,它會建立訊息佇列並從中接收訊息。
* 基於 Beej's Guide to Unix IPC
* 作者:Jan Drazil, <qeekin at gmail dot com>
*/

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

/* 接收訊息的緩衝區結構 */
struct php_buf {
long mtype;
char msg[200];
};

int main(void)
{
struct php_buf buf;
int msqid;
key_t key;

/* 產生金鑰(/var/www/index.php 必須是可存取的檔案) */
if((key = ftok("/var/www/index.php", 'G')) == -1) {
perror("ftok");
exit(EXIT_FAILURE);
}

/* 建立訊息佇列 */
if((msqid = msgget(key, 0666 | IPC_CREAT)) == -1) {
perror("msgget");
exit(EXIT_FAILURE);
}

printf("準備從 PHP 接收字串!\n");

/* 接收訊息 */
if(msgrcv(msqid, &buf, sizeof(buf.msg)-1, 0, 0) == -1) {
perror("msgrcv");
exit(EXIT_FAILURE);
}

/* 消除區段錯誤 */
buf.msg[199] = '\0';

printf("從 PHP 接收: %s\n", buf.msg);

/* 銷毀訊息佇列 */
if(msgctl(msqid, IPC_RMID, NULL) == -1) {
perror("msgctl");
exit(EXIT_FAILURE);
}

return EXIT_SUCCESS;
}

test_queue.php
<?php
/**
* 使用 PHP 和 C 程式使用 System V 訊息佇列的範例。
* 這是一個簡單的伺服器,它會建立訊息佇列並從中接收訊息。
* 基於 Beej's Guide to Unix IPC
* 作者:Jan Drazil, <qeekin at gmail dot com>
*/

/* 產生金鑰,ftok 的參數必須與 test_msg.c 中的相同 */
if(($key = ftok("/var/www/index.php", "G")) == -1)
die(
"ftok");

if(!
msg_queue_exists($key))
die(
"訊息佇列不存在");

/* 連接到訊息佇列 */
if(($msqid = msg_get_queue($key)) === FALSE)
die(
"msg_get_queue");

echo
"正在將文字傳送到訊息佇列。\n";

/* 將訊息傳送到 C 程式 */
if(!msg_send($msqid, 12, "Hello from PHP!\0", false))
die(
"msg_send");

echo
"完成"
?>
Muffinman
12 年前
當發送非複雜訊息(serialize = false)到 C 語言程式時,您需要在字串末端加上空字元 (\0)。否則,如果前一個訊息比目前的訊息長,則前一個訊息的部分內容會被顯示出來。我在 comp.lang.php 上得到了一些好心人的幫助才發現這一點。雖然現在看起來很明顯,但我還是想在這裡分享一下。
michael dot NO dot SP dot AM dot cordover+php at gmail dot com
15 年前
經過大約一小時的除錯,我終於發現了未記錄的「PHP 警告:msg_send(): msgsnd failed: Invalid argument」($errorcode = 13)的含義。

當 $message 的大小大於 msg_qbytes 時,就會發生這種情況(關於如何確定和更改 msg_qbytes,請參閱 msg_stat_queue())。
To Top