PHP 8.4.0 RC4 available for testing

Memcached::__construct

(PECL memcached >= 0.1.0)

Memcached::__construct创建 Memcached 实例

说明

public Memcached::__construct(?string $persistent_id = null, ?callable $callback = null, ?string $connection_str = null)

创建 Memcached 实例表示连接到 Memcached 服务端。

警告

本函数还未编写文档,仅有参数列表。

参数

persistent_id

默认情况下,在请求结束后会销毁 Memcached 实例。但可以在创建时通过 persistent_id 为每个实例指定唯一的 ID,在请求间共享实例。所有通过相同的 persistent_id 值创建的实例共享同一个连接。

callback

connection_str

示例

示例 #1 创建 Memcached 对象

<?php
/* 创建一个普通的对象 */
$m = new Memcached();
echo
get_class($m);

/* 创建持久化对象 */
$m2 = new Memcached('story_pool');
$m3 = new Memcached('story_pool');

/* 现在$m2和$m3共享相同的连接 */
?>

添加备注

用户贡献的备注 7 notes

up
21
tschundler at gmail dot com
15 years ago
When using persistent connections, it is important to not re-add servers.

This is what you do not want to do:
<?php
$mc
= new Memcached('mc');
$mc->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
$mc->addServers(array(
array(
'mc1.example.com',11211),
array(
'mc2.example.com',11211),
));
?>
Every time the page is loaded those servers will be appended to the list resulting in many simultaneous open connections to the same server. The addServer/addServers functions to not check for existing references to the specified servers.

A better approach is something like:
<?php
$mc
= new Memcached('mc');
$mc->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
if (!
count($mc->getServerList())) {
$mc->addServers(array(
array(
'mc1.example.com',11211),
array(
'mc2.example.com',11211),
));
}
?>
up
6
clancy hood at gmail dot com
13 years ago
If you're wanting to get started with Memcached on a relatively small project but need some scalability then it can make sense to allow $persistent_id to also denote both a key prefix and a server set which you define yourself. This keeps both key separation and allocation of data sets to certain server(s) incredibly simple throughout the project's life, without hampering any of your options.

<?php

// Here is the array which we will add to in the future
$GLOBALS['memcached-sets'] = array (
'_' => array (
array(
'localhost', 11211)
)
);

define('DEFAULT_MEMCACHED_SET', '_');

function
mcache( $persistent_id=DEFAULT_MEMCACHED_SET ) {

// one instantiation per-connection per-request
static $memcached_instances = array();

if(
array_key_exists($persistent_id, $memcached_instances)) {
$instance = $memcached_instances[$persistent_id];
}else{
$instance = new Memcached($persistent_id);
$instance->setOption(Memcached::OPT_PREFIX_KEY, $persistent_id);
$instance->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true); // advisable option

// Add servers if no connections listed. Get server set by $persistent_id or use default set.
// In a production environment with multiple server sets you may wish to prevent typos from silently adding data
// to the default pool, in which case return an error on no match instead of defaulting
if( !count($instance->getServerList()) ) {
$servers = array_key_exists($persistent_id, $GLOBALS['memcached-sets'])
?
$GLOBALS['memcached-sets'][$persistent_id]
:
$GLOBALS['memcached-sets'][DEFAULT_MEMCACHED_SET];
$instance->addServers($servers);
}

$memcached_instances[$persistent_id] = $instance;
}
return
$instance;
}

// simple example
mcache()->set('foo', 'bar');
mcache('myset')->set('foo', 'baz');

var_dump(mcache()->get('foo'), mcache('myset')->get('foo'));

?>

string(3) "bar"
string(3) "baz"

Just remember to keep your $persistent_ids short as they infringe upon your maximum key length. Happy coding! :)
up
2
Tobias
13 years ago
Note that with this Memcached interface, if one or more underlying memcached daemons are down, suffering high network latency (over 1 second by default), or have crashed, then there still will be no warning, no error, no notice. Everything will appear to work correctly, you just won't get proper results back.
up
2
Tobias
13 years ago
Not positive, but it seems like the __construct() creates an instance of Memcache() class that lives (and stays alive) in at least the child Apache procs, if not the main Apache proc.

This (seems to) mean that Memcache daemons added to the server "pool" (via ->addServers() ) stay remembered.

This is why you do not want to call ->addServers() every time your script runs, because ->addServers() does not check for dups and will add hundreds or thousands of connections to the memcached daemon proc from the Apache proc(s).

One side effect is that any other scripts (even across different website domains) can also add to your server "pool" (if they know the server pool name, or if they can get it from the memcached daemon itself (not sure if/how this is possible), or if you or your team has coded several sites using the same server pool (i.e., new Memcached( 'same-server-pool-name' ) ). This may present a security hole.
up
1
enknamel AT gmail DOT com
12 years ago
This was causing me to tear my hair out since I listened to the comments posted here.

If you enable persistence, the options you set will persist as well AND certain options if you set them with persistence enabled WILL CLOSE ALL YOUR PERSISTED CONNECTIONS. This is a part of libmemcached that the memcached extensions is built against. You can verify this by running strace.

So this is what you should do:

<?php

$mem
= new Memcached($myPoolId);

if(empty(
$mem->getServerList())) {
//This code block will only execute if we are setting up a new EG(persistent_list) entry
$mem->setOption(Memcached::OPT_RECV_TIMEOUT, 1000);
$mem->setOption(Memcached::OPT_SEND_TIMEOUT, 3000);
$mem->setOption(Memcached::OPT_TCP_NODELAY, true);
$mem->setOption(Memcached::OPT_PREFIX_KEY, "md_");
$mem->addServer($myMemcahceIp, $myMemcachePort);
}

?>
up
-2
kangzjnet at gmail dot com
11 years ago
To enable automatic failover, you have to set OPT_REMOVE_FAILED_SERVERS option, which is supported by php-memcached 2.0.0b2 or above.

Here is the example,
<?php
$memcache
= new Memcached ( 'a_mem_pool' );
$ss = $memcache->getServerList ();
if (empty (
$ss )) {
$memcache->setOption(Memcached::OPT_RECV_TIMEOUT, 1000);
$memcache->setOption(Memcached::OPT_SEND_TIMEOUT, 1000);
$memcache->setOption(Memcached::OPT_TCP_NODELAY, true);
$memcache->setOption(Memcached::OPT_SERVER_FAILURE_LIMIT, 50);
$memcache->setOption(Memcached::OPT_CONNECT_TIMEOUT, 500);
$memcache->setOption(Memcached::OPT_RETRY_TIMEOUT, 300);
$memcache->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
$memcache->setOption(Memcached::OPT_REMOVE_FAILED_SERVERS, true);
$memcache->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
$memcache->addServer ( '10.10.1.75', 11211, 1 );
$memcache->addServer ( '10.10.1.76', 11211, 1 );
$memcache->addServer ( '10.10.1.77', 11211, 1 );
}
?>
up
-1
jeroen at 4worx dot com
14 years ago
Using multiple memcached instances with options in combination with persistent connections might be confusing:

<?php

$a
= new Memcached('memcached_pool');
$a->setOption(Memcached::OPT_COMPRESSION, false);

$b = new Memcached('memcached_pool');
$b->setOption(Memcached::OPT_COMPRESSION, true);

$a->add('key', 'some data');

?>

You might think that connection $a will store everything uncompressed, but this is not the case.
The persistent connection options are changed by the second object creation.
To Top