@@ -124,7 +124,7 @@ zend_module_entry memcache_module_entry = {
124124 memcache_functions ,
125125 PHP_MINIT (memcache ),
126126 PHP_MSHUTDOWN (memcache ),
127- NULL ,
127+ PHP_RINIT ( memcache ) ,
128128 NULL ,
129129 PHP_MINFO (memcache ),
130130 PHP_MEMCACHE_VERSION ,
@@ -262,6 +262,23 @@ static PHP_INI_MH(OnUpdateLockTimeout) /* {{{ */
262262}
263263/* }}} */
264264
265+ static PHP_INI_MH (OnUpdatePrefixStaticKey ) /* {{{ */
266+ {
267+ int i ;
268+
269+ if (new_value ) {
270+ for (i = 0 ; i < ZSTR_LEN (new_value ) ; i ++ ) {
271+ if (ZSTR_VAL (new_value )[i ]== '.' ) {
272+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "memcache.session_prefix_static_key cannot have dot inside (.)" );
273+ return FAILURE ;
274+ }
275+ }
276+ }
277+
278+ return OnUpdateString (entry , new_value , mh_arg1 , mh_arg2 , mh_arg3 , stage );
279+ }
280+ /* }}} */
281+
265282/* {{{ PHP_INI */
266283PHP_INI_BEGIN ()
267284 STD_PHP_INI_ENTRY ("memcache.allow_failover" , "1" , PHP_INI_ALL , OnUpdateLong , allow_failover , zend_memcache_globals , memcache_globals )
@@ -275,6 +292,15 @@ PHP_INI_BEGIN()
275292 STD_PHP_INI_ENTRY ("memcache.session_redundancy" , "2" , PHP_INI_ALL , OnUpdateRedundancy , session_redundancy , zend_memcache_globals , memcache_globals )
276293 STD_PHP_INI_ENTRY ("memcache.compress_threshold" , "20000" , PHP_INI_ALL , OnUpdateCompressThreshold , compress_threshold , zend_memcache_globals , memcache_globals )
277294 STD_PHP_INI_ENTRY ("memcache.lock_timeout" , "15" , PHP_INI_ALL , OnUpdateLockTimeout , lock_timeout , zend_memcache_globals , memcache_globals )
295+ STD_PHP_INI_ENTRY ("memcache.session_prefix_host_key" , "0" , PHP_INI_ALL , OnUpdateBool , session_prefix_host_key , zend_memcache_globals , memcache_globals )
296+ STD_PHP_INI_ENTRY ("memcache.session_prefix_host_key_remove_www" , "1" , PHP_INI_ALL , OnUpdateBool , session_prefix_host_key_remove_www , zend_memcache_globals , memcache_globals )
297+ STD_PHP_INI_ENTRY ("memcache.session_prefix_host_key_remove_subdomain" , "0" , PHP_INI_ALL , OnUpdateBool , session_prefix_host_key_remove_subdomain , zend_memcache_globals , memcache_globals )
298+ STD_PHP_INI_ENTRY ("memcache.session_prefix_static_key" , NULL , PHP_INI_ALL , OnUpdatePrefixStaticKey , session_prefix_static_key , zend_memcache_globals , memcache_globals )
299+ STD_PHP_INI_ENTRY ("memcache.session_save_path" , NULL , PHP_INI_ALL , OnUpdateString , session_save_path , zend_memcache_globals , memcache_globals )
300+ STD_PHP_INI_ENTRY ("memcache.prefix_host_key" , "0" , PHP_INI_ALL , OnUpdateBool , prefix_host_key , zend_memcache_globals , memcache_globals )
301+ STD_PHP_INI_ENTRY ("memcache.prefix_host_key_remove_www" , "1" , PHP_INI_ALL , OnUpdateBool , prefix_host_key_remove_www , zend_memcache_globals , memcache_globals )
302+ STD_PHP_INI_ENTRY ("memcache.prefix_host_key_remove_subdomain" , "0" , PHP_INI_ALL , OnUpdateBool , prefix_host_key_remove_subdomain , zend_memcache_globals , memcache_globals )
303+ STD_PHP_INI_ENTRY ("memcache.prefix_static_key" , NULL , PHP_INI_ALL , OnUpdatePrefixStaticKey , prefix_static_key , zend_memcache_globals , memcache_globals )
278304PHP_INI_END ()
279305/* }}} */
280306
@@ -294,6 +320,150 @@ static void php_memcache_init_globals(zend_memcache_globals *memcache_globals_p)
294320}
295321/* }}} */
296322
323+ /* {{{ get_session_key_prefix
324+ */
325+ static char * get_session_key_prefix () {
326+ char * server_name = NULL , * prefix = NULL ;
327+ int static_key_len = 0 , server_name_len = 0 , i ;
328+ zval * array , * token ;
329+
330+ if (MEMCACHE_G (session_prefix_static_key )) {
331+ static_key_len = strlen (MEMCACHE_G (session_prefix_static_key ));
332+ }
333+
334+ zend_is_auto_global_str ("_SERVER" , sizeof ("_SERVER" )- 1 );
335+
336+ if (MEMCACHE_G (session_prefix_host_key )) {
337+ if ((array = zend_hash_str_find (& EG (symbol_table ), "_SERVER" , sizeof ("_SERVER" )- 1 )) &&
338+ Z_TYPE_P (array ) == IS_ARRAY &&
339+ (token = zend_hash_str_find (Z_ARRVAL_P (array ), "SERVER_NAME" , sizeof ("SERVER_NAME" )- 1 )) &&
340+ Z_TYPE_P (token ) == IS_STRING ) {
341+
342+ if (MEMCACHE_G (session_prefix_host_key_remove_www ) && !strncasecmp ("www." ,Z_STRVAL_P (token ),4 )) {
343+ server_name = Z_STRVAL_P (token )+ 4 ;
344+ } else {
345+ server_name = Z_STRVAL_P (token );
346+ }
347+
348+ if (MEMCACHE_G (session_prefix_host_key_remove_subdomain ) && server_name ) {
349+ int dots = 0 ;
350+ char * dots_ptr [3 ]= {NULL ,NULL ,NULL };
351+
352+ for (i = strlen (server_name ) ; i > 0 ; i -- ) {
353+ if (dots == sizeof (dots_ptr )) {
354+ break ;
355+ }
356+
357+ if (server_name [i ]== '.' ) {
358+ dots_ptr [dots ]= & server_name [i ];
359+ dots ++ ;
360+ }
361+ }
362+
363+ if (dots_ptr [1 ] && * (dots_ptr [1 ]+ 1 )) {
364+ server_name = dots_ptr [1 ]+ 1 ;
365+ }
366+
367+ }
368+
369+ server_name_len = (strlen (server_name ));
370+ }
371+ }
372+
373+ if (!static_key_len && !server_name_len ) {
374+ return NULL ;
375+ }
376+
377+ prefix = emalloc (static_key_len + server_name_len + 1 );
378+
379+ if (static_key_len )
380+ memcpy (prefix , MEMCACHE_G (session_prefix_static_key ), static_key_len );
381+
382+ if (server_name_len )
383+ memcpy (prefix + static_key_len , server_name , server_name_len );
384+
385+ prefix [static_key_len + server_name_len ]= '\0' ;
386+
387+ return prefix ;
388+ }
389+ /* }}} */
390+
391+ /* get_key_prefix
392+ */
393+ static char * get_key_prefix () {
394+ char * server_name = NULL , * prefix = NULL ;
395+ int static_key_len = 0 , server_name_len = 0 , i ;
396+ zval * array , * token ;
397+
398+ if (MEMCACHE_G (prefix_static_key )) {
399+ static_key_len = strlen (MEMCACHE_G (prefix_static_key ));
400+ }
401+
402+ if (MEMCACHE_G (prefix_host_key )) {
403+
404+ if ((array = zend_hash_str_find (& EG (symbol_table ), "_SERVER" , sizeof ("_SERVER" )- 1 )) &&
405+ Z_TYPE_P (array ) == IS_ARRAY &&
406+ (token = zend_hash_str_find (Z_ARRVAL_P (array ), "SERVER_NAME" , sizeof ("SERVER_NAME" )- 1 )) &&
407+ Z_TYPE_P (token ) == IS_STRING ) {
408+
409+ if (MEMCACHE_G (prefix_host_key_remove_www ) && !strncasecmp ("www." ,Z_STRVAL_P (token ),4 )) {
410+ server_name = Z_STRVAL_P (token )+ 4 ;
411+ } else {
412+ server_name = Z_STRVAL_P (token );
413+ }
414+
415+ if (MEMCACHE_G (prefix_host_key_remove_subdomain ) && server_name ) {
416+ int dots = 0 ;
417+ char * dots_ptr [3 ]= {NULL ,NULL ,NULL };
418+
419+ for (i = strlen (server_name ) ; i > 0 ; i -- ) {
420+ if (dots == sizeof (dots_ptr )) {
421+ break ;
422+ }
423+ if (server_name [i ]== '.' ) {
424+ dots_ptr [dots ]= & server_name [i ];
425+ dots ++ ;
426+ }
427+ }
428+
429+ if (dots_ptr [1 ] && * (dots_ptr [1 ]+ 1 )) {
430+ server_name = dots_ptr [1 ]+ 1 ;
431+ }
432+
433+ }
434+
435+ server_name_len = (strlen (server_name ));
436+ }
437+ }
438+
439+ if (!static_key_len && !server_name_len ) {
440+ return NULL ;
441+ }
442+
443+ prefix = emalloc (static_key_len + server_name_len + 1 );
444+
445+ if (static_key_len )
446+ memcpy (prefix , MEMCACHE_G (prefix_static_key ), static_key_len );
447+
448+ if (server_name_len )
449+ memcpy (prefix + static_key_len , server_name , server_name_len );
450+
451+ prefix [static_key_len + server_name_len ]= '\0' ;
452+
453+ return prefix ;
454+ }
455+ /* }}} */
456+
457+ /* {{{ PHP_RINIT_FUNCTION
458+ */
459+ PHP_RINIT_FUNCTION (memcache )
460+ {
461+ MEMCACHE_G (session_key_prefix ) = get_session_key_prefix (TSRMLS_C );
462+
463+ return SUCCESS ;
464+ }
465+ /* }}} */
466+
297467/* {{{ PHP_MINIT_FUNCTION
298468 */
299469PHP_MINIT_FUNCTION (memcache )
@@ -466,7 +636,7 @@ static void php_mmc_store(INTERNAL_FUNCTION_PARAMETERS, int op) /* {{{ */
466636 request = mmc_pool_request (pool , MMC_PROTO_TCP ,
467637 mmc_stored_handler , return_value , mmc_pool_failover_handler , NULL );
468638
469- if (mmc_prepare_key_ex (ZSTR_VAL (key ), ZSTR_LEN (key ), request -> key , & (request -> key_len )) != MMC_OK ) {
639+ if (mmc_prepare_key_ex (ZSTR_VAL (key ), ZSTR_LEN (key ), request -> key , & (request -> key_len ), MEMCACHE_G ( key_prefix ) ) != MMC_OK ) {
470640 php_error_docref (NULL , E_WARNING , "Invalid key" );
471641 mmc_pool_release (pool , request );
472642 zend_string_release (key );
@@ -1103,6 +1273,8 @@ PHP_NAMED_FUNCTION(zif_memcache_pool_connect)
11031273 double timeout = MMC_DEFAULT_TIMEOUT ;
11041274 zend_bool persistent = 1 ;
11051275
1276+ MEMCACHE_G (key_prefix )= get_key_prefix ();
1277+
11061278 if (zend_parse_parameters (ZEND_NUM_ARGS (), "s|llbldl" ,
11071279 & host , & host_len , & tcp_port , & udp_port , & persistent , & weight , & timeout , & retry_interval ) == FAILURE ) {
11081280 return ;
@@ -1136,6 +1308,7 @@ PHP_NAMED_FUNCTION(zif_memcache_pool_connect)
11361308 Connects to server and returns a Memcache object */
11371309PHP_FUNCTION (memcache_connect )
11381310{
1311+ MEMCACHE_G (key_prefix )= get_key_prefix ();
11391312 php_mmc_connect (INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 );
11401313}
11411314/* }}} */
@@ -1144,6 +1317,7 @@ PHP_FUNCTION(memcache_connect)
11441317 Connects to server and returns a Memcache object */
11451318PHP_FUNCTION (memcache_pconnect )
11461319{
1320+ MEMCACHE_G (key_prefix )= get_key_prefix ();
11471321 php_mmc_connect (INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 );
11481322}
11491323/* }}} */
@@ -1161,6 +1335,8 @@ PHP_NAMED_FUNCTION(zif_memcache_pool_addserver)
11611335 double timeout = MMC_DEFAULT_TIMEOUT ;
11621336 zend_bool persistent = 1 , status = 1 ;
11631337
1338+ MEMCACHE_G (key_prefix )= get_key_prefix ();
1339+
11641340 if (zend_parse_parameters (ZEND_NUM_ARGS (), "s|llbldlb" ,
11651341 & host , & host_len , & tcp_port , & udp_port , & persistent , & weight , & timeout , & retry_interval , & status ) == FAILURE ) {
11661342 return ;
@@ -1222,6 +1398,8 @@ PHP_FUNCTION(memcache_add_server)
12221398 double timeout = MMC_DEFAULT_TIMEOUT ;
12231399 zend_bool persistent = 1 , status = 1 ;
12241400
1401+ MEMCACHE_G (key_prefix )= get_key_prefix ();
1402+
12251403 if (mmc_object ) {
12261404 if (zend_parse_parameters (ZEND_NUM_ARGS (), "s|lbldlbz" ,
12271405 & host , & host_len , & tcp_port , & persistent , & weight , & timeout , & retry_interval , & status , & failure_callback ) == FAILURE ) {
0 commit comments