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() 将项目 varkey 一起存储在 memcached 服务器上。参数 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' 的项目的 value
使用 0 作为 flag 值,不使用压缩
过期时间为 30 秒
*/
memcache_set($memcache_obj, 'var_key', 'some variable', 0, 30);

echo
memcache_get($memcache_obj, 'var_key');

?>

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

<?php
/* OO API */

$memcache_obj = new Memcache;

/* 连接到 memcached 服务器 */
$memcache_obj->connect('memcache_host', 11211);

/*
设置键为 'var_key' 的项目的 value,使用动态压缩
过期时间为 50 秒
*/
$memcache_obj->set('var_key', 'some really big variable', MEMCACHE_COMPRESSED, 50);

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

?>

参见

添加注释

用户贡献的注释 9 条注释

11
Sc00bz
17 年前
这只是关于 memcache 的两件小事,可能不太清楚,即键和数据大小的限制以及 memcache 协议中标志的行为。

* 键的最大大小为 250,更大的键会被截断。数据也有 (1MB - 42 字节) 的限制。

* 在 memcache 协议中,有一个 16 位(较新版本为 32 位)标志,您可以将其设置为任何值,因为 memcache 不会对标志执行任何操作。php api 不会让您获取标志,因为 php 使用标志用于 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
8
wbonde at yakabod dot com
13 年前
最大过期时间(无需像 0 秒那样担心必要的删除)是 2,592,000 秒(30 天)。

指定超过该时间的过期值将返回 false,但不会抛出错误,因此很容易错过。
9
argyleblanket
16 年前
对同一个键多次使用 set 似乎会产生意外的结果——它不像“替换”,而是似乎对同一个键“设置”多个值。“get”可能会返回任何值。

这在多服务器设置上进行了测试——如果您只有一台服务器,行为可能不同。

补救措施是结合使用 replace 和 set

<?php
$result
= $memcache->replace( $key, $var );
if(
$result == false )
{
$result = $memcache->set( $key, $var );
}
?>
3
Stephen from veedow.com
16 年前
我在使用 MEMCACHE_COMPRESSED 标志存储少量数据(例如整数)时遇到了问题。

例如。

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

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

当我为较小的值删除 MEMCACHE_COMPRESSED 标志时,这个问题消失了。
2
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);
?>
0
winmutt
5 年前
关于 replace 和 set 的说明在我的测试中不再有效。您可以对同一个键多次调用 set,并可靠地获取最后写入的值。我在 3 个 memcache 节点上对超过 10000 个键进行了测试。
0
jcastromail at yahoo dot es
7 年前
如果您收到以下消息

"标志数组的最低两位字节保留供 pecl/memcache 内部使用"

然后尝试以下操作
a) 尝试使用 Memcached 代替 Memcache。
b) 切换压缩值
$memcache->set($key,$value,MEMCACHE_COMPRESSED)

$memcache->set($key,$value,0)
-1
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"); ?>

所以,简而言之,您必须缓冲输出
-4
aamthor at advertzoom dot de
12 年前
纠正一些事情

最大过期时间:RTFM,这里写着。

最大数据量:只要您的服务器能够承受,几乎是无限的。

速度和节奏
嗯,这是另一回事。我们有一些数据记录,由于应用程序的原因,必须将其保存在内存中。由于数据量很大并且变化不频繁,我们考虑将其缓存到 memcache 中,而不是每次都从数据库 (DB) 中检索。

这不是一个普遍适用的建议,也不是任何质量声明,但我们对序列化数组(50 MB)进行了压缩和未压缩的测试,结果表明,在我们的特定场景中,memcache 比数据库 (MySQL) 慢得多。

一般来说,无法预测 memcache 在某些场景下的行为,但在开始将内容部署到生产系统之前,始终需要进行一些测试和基准测试。

尽管进行了上述测试,我们仍然使用 memcache 进行会话缓存而不是文件系统,因为还需要考虑其他一些因素,并且数据量始终很小(几 KB)。
To Top