Skip to content

Instantly share code, notes, and snippets.

@brianlmoon
Last active August 29, 2015 14:18
Show Gist options
  • Save brianlmoon/d0b3676e281510359e0c to your computer and use it in GitHub Desktop.
Save brianlmoon/d0b3676e281510359e0c to your computer and use it in GitHub Desktop.
Safest way to add servers using pecl-memcached and persistent connections.
<?php
// Let's assume this is coming from a config file somewhere
// that maybe we can't trust, or could allow for someone to
// accidently add the same host/port twice.
$servers = array(
array("host" => 'localhost', "port" => 11211, "weight" => 10),
array("host" => 'localhost', "port" => 11212, "weight" => 20)
);
$mc = new Memcached("test");
$current_servers = $mc->getServerList();
/**
* The pecl/memcached docs tell us:
*
* http://php.net/manual/en/memcached.addservers.php
*
* The same server may appear multiple times in the server pool, because no
* duplication checks are made. This is not advisable; instead, use the weight
* option to increase the selection weighting of this server.
*
* So, we will make a unique list based on host and port. Why don't we include
* weight? Well, first, if you are using weight, why would you add the same
* server more once? Second, getServerList() does not return weight, so two
* entries with the same host and port can not be differentiated.
*
*/
$unique_servers = array();
foreach($servers as $server_info) {
$key = $server_info["host"].":".$server_info["port"];
if(!empty($unique_servers[$key])){
trigger_error("Skipping duplicate memcached server $key. It is not advised to add the same server to the server list more than once. Use weight instead.", E_USER_NOTICE);
} else {
$unique_servers[$key] = $server_info;
}
}
// copy our unique values back into the server list
$servers = array_values($unique_servers);
// If there are no current servers, simply reset add the servers
if(empty($current_servers)){
$mc->addServers($servers);
} else {
// assume we don't need to reset the list
$reset = false;
if(count($servers) == count($current_servers)){
// if the lists are the same size, loop through the current
// list and remove ones that are in the unique list
foreach($current_servers as $cur_key => $cur_server_info) {
$key = $cur_server_info["host"].":".$cur_server_info["port"];
if(isset($unique_servers[$key])){
unset($current_servers[$cur_key]);
}
}
// if all the servers matched, we are good, if not, reset
if(count($current_servers) > 0){
$reset = true;
}
} else {
// reset if the count does not match
$reset = true;
}
if($reset){
// reset the list and add the proper list
$mc->resetServerList();
$mc->addServers($servers);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment