PHP Conference Japan 2024

Memcache::set

(PECL memcache >= 0.2.0)

Memcache::set在伺服器儲存資料

描述

Memcache::set(
    string $key,
    mixed $var,
    int $flag = ?,
    int $expire = ?
): bool

Memcache::set() 在 memcached 伺服器上使用 key 儲存項目 var。參數 expire 是以秒為單位的過期時間。如果它是 0,則該項目永遠不會過期(但 memcached 伺服器不保證此項目會一直儲存,它可能會從快取中刪除,以便為其他項目騰出空間)。如果要使用即時壓縮(使用 zlib),可以使用 MEMCACHE_COMPRESSED 常數作為 flag 值。

注意:

請記住,資源變數(即檔案和連線描述符)無法儲存在快取中,因為它們無法在序列化狀態中充分表示。

您也可以使用 memcache_set() 函數。

參數

key

將與項目關聯的鍵。

var

要儲存的變數。字串和整數會原樣儲存,其他類型會序列化後儲存。

flag

使用 MEMCACHE_COMPRESSED 來儲存壓縮的項目(使用 zlib)。

expire

項目的過期時間。如果它等於零,則該項目永遠不會過期。您也可以使用 Unix 時間戳記或從目前時間開始的秒數,但在後一種情況下,秒數不得超過 2592000(30 天)。

回傳值

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

範例

範例 #1 Memcache::set() 範例

<?php
/* 程序式 API */

/* 連線到 memcached 伺服器 */
$memcache_obj = memcache_connect('memcache_host', 11211);

/*
使用鍵 'var_key' 設定項目值
使用 0 作為 flag 值,不使用壓縮
過期時間為 30 秒
*/
memcache_set($memcache_obj, 'var_key', 'some variable', 0, 30);

echo
memcache_get($memcache_obj, 'var_key');

?>

範例 #2 Memcache::set() 範例

<?php
/* 物件導向 API */

$memcache_obj = new Memcache;

/* 連線到 memcached 伺服器 */
$memcache_obj->connect('memcache_host', 11211);

/*
使用即時壓縮設定鍵 'var_key' 的項目值
過期時間為 50 秒
*/
$memcache_obj->set('var_key', 'some really big variable', MEMCACHE_COMPRESSED, 50);

echo
$memcache_obj->get('var_key');

?>

另請參閱

新增註解

使用者提供的註解 9 則註解

Sc00bz
17 年前
這只是關於 memcache 的兩個小問題,可能不太清楚,關於鍵和資料大小的限制,以及 memcache 協定中 flag 的作用。

* 最大鍵大小為 250,任何更大的鍵都會被截斷。資料也有一個 (1MB - 42 位元組) 的限制。

* 在 memcache 協定中,有一個 16 位元,較新版本中為 32 位元的 flag,您可以將其設定為任何您想要的值,因為 memcache 不會對 flag 進行任何操作。php api 不允許您取得 flag,因為 php 使用 flag 來進行 php 自己的用途,例如 "MEMCACHE_COMPRESSED",我決定測試它是否正在執行某些操作,因為它不是 memcache 協定的一部分。

<?php
$memcache
= new Memcache();
$memcache->connect("127.0.0.1", 11211);

// 由於 memcache 會將鍵值截斷至 250 位元組,因此 get "250 個 a" 和 "251 個 a" 都會在快取中找到該鍵值
echo "*** 截斷鍵值測試 ***<br>";
echo
"設定 251: " . ($memcache->set(str_repeat("a", 251), "value", 0, 1) ? "t" : "f") . "<br>";

echo
"取得 249: " . (($ret = $memcache->get(str_repeat("a", 249))) !== false ? "'$ret'" : "f") . "<br>";
echo
"取得 250: " . (($ret = $memcache->get(str_repeat("a", 250))) !== false ? "'$ret'" : "f") . "<br>";
echo
"取得 251: " . (($ret = $memcache->get(str_repeat("a", 251))) !== false ? "'$ret'" : "f") . "<br>";
echo
"刪除: " . ($memcache->delete(str_repeat("a", 250)) ? "t" : "f") . "<br><br>";

echo
"*** 壓縮值測試 ***<br>";
echo
"設定 1024*1024-42: " . ($memcache->set("test", str_repeat("a", 1024*1024-42), 0, 1) ? "t" : "f") . "<br>";
echo
"設定 1024*1024-41: " . ($memcache->set("test", str_repeat("a", 1024*1024-41), 0, 1) ? "t" : "f") . "<br>";
echo
"設定 1024*1024 壓縮: " . ($memcache->set("test", str_repeat("a", 1024*1024), MEMCACHE_COMPRESSED, 1) ? "t" : "f") . "<br>";
echo
"刪除: " . ($memcache->delete("test") ? "t" : "f") . "<br>";
$memcache->close();
?>

輸出
*** 截斷鍵值測試 ***
設定 251: t
取得 249: f
取得 250: 'value'
取得 251: 'value'
刪除: t

*** 壓縮值測試 ***
設定 1024*1024-42: t
設定 1024*1024-41: f
設定 1024*1024 壓縮: t
刪除: t
wbonde at yakabod dot com
13 年前
最大到期時間(無需像 0 秒那樣在必要時擔心刪除)為 2,592,000 秒(30 天)。

指定高於該值的到期時間將返回 false,但不會引發錯誤,因此很容易忽略。
argyleblanket
16 年前
對於同一個鍵值,多次使用 set 似乎會產生非預期的結果 - 它不會像 "replace" 那樣運作,而是似乎為同一個鍵值 "設定" 多個值。"get" 可能會返回任何值。

這是在多伺服器設定上測試的 - 如果您只有一台伺服器,行為可能會有所不同。

補救方法是結合使用 replace 和 set

<?php
$result
= $memcache->replace( $key, $var );
if(
$result == false )
{
$result = $memcache->set( $key, $var );
}
?>
Stephen from veedow.com
16 年前
我發現在儲存少量數據(例如整數)時使用 MEMCACHE_COMPRESSED 標誌時遇到了問題。

例如。

<?php
Memcache
::set('integer', 123456, MEMCACHE_COMPRESSED);
// 會返回 true

Memcache::get('integer');
// 會返回 false
?>

當我刪除小數值的 MEMCACHE_COMPRESSED 標誌時,這個問題就消失了。
duerra at nospam dot yahoo dot com
14 年前
如果您有興趣使用壓縮,請注意,至少對於 PHP 版本 5.3.2 和 Memcache 版本 3.0.4,當檢索其值為數值或布林類型的鍵值時,PHP 會拋出以下通知

訊息:MemcachePool::get(): 無法解壓縮數據

解決這個問題的方法是在設定或將其新增到 Memcache 之前測試您的變數類型,甚至將其轉換為字串。

<?php
$key
= 'mc_key';
$value = 12345;
$compress = is_bool($value) || is_int($value) || is_float($value) ? false : MEMCACHE_COMPRESSED;

$mc= new Memcache;
$mc->connect('localhost', 11211);
$mc->set($key, $value, $compress);

echo
$mc->get($key);

// 另一種方法是轉換變數
$value = is_scalar($value) ? (string)$value : $value;
$mc->set($key, $value, MEMCACHE_COMPRESSED);
?>
winmutt
5 年前
我測試的結果表明,這裡關於 replace 和 set 的說明已不再有效。您可以在同一個鍵值上多次呼叫 set,並可靠地取得最後寫入的值。我用 3 個 memcache 節點測試了 10000 個以上的鍵值。
jcastromail at yahoo dot es
7 年前
如果您收到下則訊息

"flags 陣列的最低兩個位元組保留給 pecl/memcache 內部使用"

然後嘗試下一個操作
a) 嘗試使用 Memcached 而不是 Memcache。
b) 切換壓縮值
$memcache->set($key,$value,MEMCACHE_COMPRESSED)

$memcache->set($key,$value,0)
effeesse gmail com
14 年前
如果您想快取即時建立的影像,您可以執行

<?php
ob_start
();
imagepng($image);
$memcache->set("my_image", ob_get_contents(), false, $cache_time);
ob_end_clean();
?>

然後您可以將快取的影像作為簡單的變數存取
<?php $my_image = $memcache->get("my_image"); ?>

因此,簡而言之,您必須緩衝輸出
aamthor at advertzoom dot de
12 年前
修正一些事情

最大過期時間:RTFM,這裡有寫。

最大資料量:只要您的伺服器能承受,幾乎沒有限制。

速度和節奏
嗯,那是另一回事。我們有一些資料紀錄,由於應用程式的原因必須保存在記憶體中。由於資料量很大且不常變動,我們考慮將其快取到 memcache 中,而不是每次都從資料庫中檢索。

這不是一般建議,也不是任何品質聲明,但我們對序列化的陣列 (50 MB) 進行了一些測試,包括壓縮和未壓縮的陣列。結果發現在我們的特定情況下,memcache 比資料庫 (mySql) 慢得多。

一般來說,無法預測 memcache 在某些情況下的行為,但始終需要在開始將東西部署到實際系統之前進行一些測試和基準測試。

儘管有上述測試,我們仍然使用 memcache 來快取會話,而不是檔案系統,因為還有其他一些事情要考慮,而且資料量始終很小(幾 KB)。
To Top