|   | php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
| 
  [2010-06-16 08:45 UTC] alexander dot krause at ed-solutions dot de
 Description:
------------
The normal php-memcache extension allows the use of unix domain sockets.
However these don't work with the pecl-memcached.
Reproduce code:
---------------
$m=new Memcached();
$m->addServer(
	'/tmp/memcached.sock',
	0
);
$m->set('int', 99);
echo $m->getResultMessage();
//HOSTNAME LOOKUP FAILURE
Expected result:
----------------
SUCCESS
Actual result:
--------------
HOSTNAME LOOKUP FAILURE
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             | |||||||||||||||||||||||||||||||||||||
|  Copyright © 2001-2025 The PHP Group All rights reserved. | Last updated: Fri Oct 31 10:00:02 2025 UTC | 
If any body interesting i have add my support for various connetions types to memcached server. I change prototype of addServer method, now it's like this: addServer(<server decl>), <server decl> = string || array If <server decl> is string its have follow format (in pcre manner): udp:host:port(( |:)<weight>)* - for udp host:port(( |:)<weight>)* - for tcp /path_to_memcached_sock(( |:)<weight>)* - for unix socket If <server decl> is array its have follow members: array( "type" => MEMCACHED_CONNECTION_TCP | MEMCACHED_CONNECTION_UDP | MEMCACHED_CONNECTION_UNIX_SOCKET, "host" => <host>, "port" => <port, ignore if type == MEMCACHED_CONNECTION_UNIX_SOCKET>, "weight" => <weight>) addServers, have similar declaration, except, its accept a list of <server decl> Session save_path have follow declaration (string): save_path=<server decl>(,<server decl>)* diff -r 4140351daad9 php_memcached.c --- a/php_memcached.c Fri Oct 15 22:20:56 2010 +0400 +++ b/php_memcached.c Mon Oct 18 14:36:41 2010 +0400 @@ -204,6 +204,173 @@ static memcached_return php_memc_do_stats_callback(memcached_st *ptr, memcached_server_instance_st instance, void *in_context); static memcached_return php_memc_do_version_callback(memcached_st *ptr, memcached_server_instance_st instance, void *in_context); +/**************************************** + php_memcached_servers_add_string +****************************************/ +#define HUGE_STRING_LEN 8196 + +memcached_return php_memcached_servers_add_string(memcached_st *memc_sess, char* buffer) +{ + memcached_return status; + char *ptr, *ptr2; + in_port_t port = 0; + uint32_t weight = 0; + + if(strstr(buffer, "udp:")) + { + ptr= index(&buffer[4], ':'); + + if (ptr) + { + ptr[0]= 0; + ptr++; + + port= (in_port_t) strtoul(ptr, (char **)NULL, 10); + }; + + ptr2= index(ptr, ' '); + + if (! ptr2) + ptr2= index(ptr, ':'); + + if (ptr2) + { + ptr2++; + weight = (uint32_t) strtoul(ptr2, (char **)NULL, 10); + }; + + status = memcached_server_add_udp_with_weight(memc_sess, buffer, port, weight); + } + else if(strchr(buffer, '/') == buffer) + { + ptr2= index(buffer, ' '); + + if (! ptr2) + ptr2= index(buffer, ':'); + + if (ptr2) + { + ptr2[0] = 0; + ptr2++; + weight = (uint32_t) strtoul(ptr2, (char **)NULL, 10); + }; + + status = memcached_server_add_unix_socket_with_weight(memc_sess, buffer, weight); + } + else if(index(buffer, ':')) + { + ptr= index(buffer, ':'); + + if (ptr) + { + ptr[0]= 0; + ptr++; + + port= (in_port_t) strtoul(ptr, (char **)NULL, 10); + }; + + ptr2= index(ptr, ' '); + + if (! ptr2) + ptr2= index(ptr, ':'); + + if (ptr2) + { + ptr2++; + weight = (uint32_t) strtoul(ptr2, (char **)NULL, 10); + }; + + status = memcached_server_add_with_weight(memc_sess, buffer, port, weight); + }; + + return status; +}; + +int php_memcached_servers_add(memcached_st *memc, zval** entry TSRMLS_DC) +{ + int retval = 0; + memcached_return status; + + if(Z_TYPE_PP(entry) == IS_STRING) + { + char buffer[HUGE_STRING_LEN]; + size_t length= Z_STRLEN_PP(entry); + memcpy(buffer, Z_STRVAL_PP(entry), length); + buffer[length]= 0; + + status = php_memcached_servers_add_string(memc, buffer); + + if (php_memc_handle_error(status TSRMLS_CC) < 0){ + retval = 1; + }; + } + else if(Z_TYPE_PP(entry) == IS_ARRAY) + { + zval **z_host, **z_port, **z_weight, **z_type = NULL; + + if(zend_hash_find(Z_ARRVAL_PP(entry), "type", sizeof("type"), (void **)&z_type) == FAILURE) + { + retval = 4; + } + else if(zend_hash_find(Z_ARRVAL_PP(entry), "host", sizeof("host"), (void **)&z_host) == FAILURE) + { + retval = 2; + } + else + { + convert_to_long_ex(z_type); + + if(Z_LVAL_PP(z_type) != MEMCACHED_CONNECTION_UNIX_SOCKET) + { + if (zend_hash_find(Z_ARRVAL_PP(entry), "port", sizeof("port"), (void **)&z_port) == FAILURE) + { + retval = 3; + } + else + { + convert_to_long_ex(z_port); + }; + }; + }; + + if(!retval) + { + uint32_t weight = 0; + convert_to_string_ex(z_host); + + + if(zend_hash_find(Z_ARRVAL_PP(entry), "weight", sizeof("weight"), (void **)&z_weight) == SUCCESS){ + convert_to_long_ex(z_weight); + weight = Z_LVAL_PP(z_weight); + }; + + switch(Z_LVAL_PP(z_type)){ + case MEMCACHED_CONNECTION_TCP: + status = memcached_server_add_with_weight(memc, Z_STRVAL_PP(z_host), Z_LVAL_PP(z_port), weight); + break; + + case MEMCACHED_CONNECTION_UDP: + status = memcached_server_add_udp_with_weight(memc, Z_STRVAL_PP(z_host), Z_LVAL_PP(z_port), weight); + break; + + case MEMCACHED_CONNECTION_UNIX_SOCKET: + status = memcached_server_add_unix_socket_with_weight(memc, Z_STRVAL_PP(z_host), weight); + break; + }; + + if (php_memc_handle_error(status TSRMLS_CC) != 0) { + retval = 1; + }; + }; + } + else + { + retval = 1; + }; + + return retval; +}; + /**************************************** Method implementations @@ -1374,24 +1541,20 @@ Adds the given memcache server to the list */ PHP_METHOD(Memcached, addServer) { - char *host; - int host_len; - long port, weight = 0; - memcached_return status; + zval *server; MEMC_METHOD_INIT_VARS; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l", &host, &host_len, - &port, &weight) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &server) == FAILURE) { return; } MEMC_METHOD_FETCH_OBJECT; MEMC_G(rescode) = MEMCACHED_SUCCESS; - status = memcached_server_add_with_weight(i_obj->memc, host, port, weight); - if (php_memc_handle_error(status TSRMLS_CC) < 0) { + if(php_memcached_servers_add(i_obj->memc, &server) != 0) + { RETURN_FALSE; - } + }; RETURN_TRUE; } @@ -1403,10 +1566,7 @@ { zval *servers; zval **entry; - zval **z_host, **z_port, **z_weight = NULL; - uint32_t weight = 0; - int entry_size, i = 0; - memcached_server_st *list = NULL; + int i = 0; memcached_return status; MEMC_METHOD_INIT_VARS; @@ -1421,61 +1581,25 @@ zend_hash_get_current_data(Z_ARRVAL_P(servers), (void **)&entry) == SUCCESS; zend_hash_move_forward(Z_ARRVAL_P(servers)), i++) { - if (Z_TYPE_PP(entry) != IS_ARRAY) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "server list entry #%d is not an array", i+1); - continue; - } - - entry_size = zend_hash_num_elements(Z_ARRVAL_PP(entry)); - - if (entry_size > 1) { - zend_hash_internal_pointer_reset(Z_ARRVAL_PP(entry)); - - /* Check that we have a host */ - if (zend_hash_get_current_data(Z_ARRVAL_PP(entry), (void **)&z_host) == FAILURE) { + switch(php_memcached_servers_add(i_obj->memc, entry TSRMLS_CC)) + { + case 1: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not add entry #%d to the server list", i+1); + break; + + case 2: php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not get server host for entry #%d", i+1); - continue; - } - - /* Check that we have a port */ - if (zend_hash_move_forward(Z_ARRVAL_PP(entry)) == FAILURE || - zend_hash_get_current_data(Z_ARRVAL_PP(entry), (void **)&z_port) == FAILURE) { + break; + + case 3: php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not get server port for entry #%d", i+1); - continue; - } - - convert_to_string_ex(z_host); - convert_to_long_ex(z_port); - - weight = 0; - if (entry_size > 2) { - /* Try to get weight */ - if (zend_hash_move_forward(Z_ARRVAL_PP(entry)) == FAILURE || - zend_hash_get_current_data(Z_ARRVAL_PP(entry), (void **)&z_weight) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not get server weight for entry #%d", i+1); - } - - convert_to_long_ex(z_weight); - weight = Z_LVAL_PP(z_weight); - } - - list = memcached_server_list_append_with_weight(list, Z_STRVAL_PP(z_host), - Z_LVAL_PP(z_port), weight, &status); - - if (php_memc_handle_error(status TSRMLS_CC) == 0) { - continue; - } - } - - /* catch-all for all errors */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not add entry #%d to the server list", i+1); - } - - status = memcached_server_push(i_obj->memc, list); - memcached_server_list_free(list); - if (php_memc_handle_error(status TSRMLS_CC) < 0) { - RETURN_FALSE; - } + break; + + case 4: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not get server type for entry #%d", i+1); + break; + }; + }; RETURN_TRUE; } @@ -2448,24 +2572,49 @@ PS_OPEN_FUNC(memcached) { memcached_st *memc_sess = PS_GET_MOD_DATA(); - memcached_server_st *servers; - memcached_return status; - - servers = memcached_servers_parse((char *)save_path); - if (servers) { - memc_sess = memcached_create(NULL); - if (memc_sess) { - status = memcached_server_push(memc_sess, servers); - if (status == MEMCACHED_SUCCESS) { - PS_SET_MOD_DATA(memc_sess); - return SUCCESS; + memc_sess = memcached_create(NULL); + + if (memc_sess) + { + const char *begin_ptr; + const char *end_ptr; + char *string; + memcached_return status; + end_ptr= (char *)save_path + strlen(save_path); + + for (begin_ptr= (char *)save_path, string= index((char *)save_path, ','); + begin_ptr != end_ptr; + string= index(begin_ptr, ',')) + { + char buffer[HUGE_STRING_LEN]; + + if (string) + { + memcpy(buffer, begin_ptr, (size_t) (string - begin_ptr)); + buffer[(unsigned int)(string - begin_ptr)]= 0; + begin_ptr= string+1; } - } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not allocate libmemcached structure"); - } - } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to parse session.save_path"); + else + { + size_t length= strlen(begin_ptr); + memcpy(buffer, begin_ptr, length); + buffer[length]= 0; + begin_ptr= end_ptr; + }; + + status = php_memcached_servers_add_string(memc_sess, buffer); + + if (isspace(*begin_ptr)) + begin_ptr++; + }; + + PS_SET_MOD_DATA(memc_sess); + return SUCCESS; } + else + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not allocate libmemcached structure"); + }; PS_SET_MOD_DATA(NULL); return FAILURE; @@ -2998,6 +3147,19 @@ php_session_register_module(ps_memcached_ptr); #endif + /* CONST_MEMC_START */ + REGISTER_LONG_CONSTANT("MEMCACHED_CONNECTION_UDP", + MEMCACHED_CONNECTION_UDP, + CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("MEMCACHED_CONNECTION_TCP", + MEMCACHED_CONNECTION_TCP, + CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("MEMCACHED_CONNECTION_UNIX_SOCKET", + MEMCACHED_CONNECTION_UNIX_SOCKET, + CONST_CS | CONST_PERSISTENT); + return SUCCESS; } /* }}} */