@@ -157,6 +157,16 @@ static int le_memc;
157
157
158
158
static zend_class_entry * memcached_ce = NULL ;
159
159
static zend_class_entry * memcached_exception_ce = NULL ;
160
+
161
+ static struct callbackContext
162
+ {
163
+ zval * array ;
164
+ zval * entry ;
165
+ memcached_stat_st * stats ; /* for use with functions that need stats */
166
+ void * return_value ;
167
+ unsigned int i ; /* for use with structures mapped against servers */
168
+ } ;
169
+
160
170
static zend_class_entry * spl_ce_RuntimeException = NULL ;
161
171
162
172
#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 3 )
@@ -190,6 +200,9 @@ static void php_memc_incdec_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool incr);
190
200
static void php_memc_getDelayed_impl (INTERNAL_FUNCTION_PARAMETERS , zend_bool by_key );
191
201
static memcached_return php_memc_do_cache_callback (zval * memc_obj , zend_fcall_info * fci , zend_fcall_info_cache * fcc , char * key , size_t key_len , zval * value TSRMLS_DC );
192
202
static int php_memc_do_result_callback (zval * memc_obj , zend_fcall_info * fci , zend_fcall_info_cache * fcc , memcached_result_st * result TSRMLS_DC );
203
+ static memcached_return php_memc_do_serverlist_callback (memcached_st * ptr , memcached_server_instance_st instance , void * in_context );
204
+ static memcached_return php_memc_do_stats_callback (memcached_st * ptr , memcached_server_instance_st instance , void * in_context );
205
+ static memcached_return php_memc_do_version_callback (memcached_st * ptr , memcached_server_instance_st instance , void * in_context );
193
206
194
207
195
208
/****************************************
@@ -1447,7 +1460,7 @@ PHP_METHOD(Memcached, addServers)
1447
1460
}
1448
1461
1449
1462
list = memcached_server_list_append_with_weight (list , Z_STRVAL_PP (z_host ),
1450
- Z_LVAL_PP (z_port ), weight , & status );
1463
+ Z_LVAL_PP (z_port ), weight , & status );
1451
1464
1452
1465
if (php_memc_handle_error (status TSRMLS_CC ) == 0 ) {
1453
1466
continue ;
@@ -1468,13 +1481,14 @@ PHP_METHOD(Memcached, addServers)
1468
1481
}
1469
1482
/* }}} */
1470
1483
1484
+
1471
1485
/* {{{ Memcached::getServerList()
1472
1486
Returns the list of the memcache servers in use */
1473
1487
PHP_METHOD (Memcached , getServerList )
1474
1488
{
1475
- memcached_server_st * servers ;
1476
- unsigned int i , servers_count ;
1477
1489
zval * array ;
1490
+ struct callbackContext context = {0 };
1491
+ memcached_server_function callbacks [1 ];
1478
1492
MEMC_METHOD_INIT_VARS ;
1479
1493
1480
1494
if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "" ) == FAILURE ) {
@@ -1483,21 +1497,11 @@ PHP_METHOD(Memcached, getServerList)
1483
1497
1484
1498
MEMC_METHOD_FETCH_OBJECT ;
1485
1499
1500
+ callbacks [0 ] = php_memc_do_serverlist_callback ;
1486
1501
array_init (return_value );
1487
- servers = memcached_server_list (i_obj -> memc );
1488
- servers_count = memcached_server_count (i_obj -> memc );
1489
- if (servers == NULL ) {
1490
- return ;
1491
- }
1492
-
1493
- for (i = 0 ; i < servers_count ; i ++ ) {
1494
- MAKE_STD_ZVAL (array );
1495
- array_init (array );
1496
- add_assoc_string (array , "host" , servers [i ].hostname , 1 );
1497
- add_assoc_long (array , "port" , servers [i ].port );
1498
- add_assoc_long (array , "weight" , servers [i ].weight );
1499
- add_next_index_zval (return_value , array );
1500
- }
1502
+ context .array = array ;
1503
+ context .return_value = return_value ;
1504
+ memcached_server_cursor (i_obj -> memc , callbacks , & context , 1 );
1501
1505
}
1502
1506
/* }}} */
1503
1507
@@ -1541,13 +1545,12 @@ PHP_METHOD(Memcached, getServerByKey)
1541
1545
Returns statistics for the memcache servers */
1542
1546
PHP_METHOD (Memcached , getStats )
1543
1547
{
1544
- memcached_stat_st * stats ;
1548
+ memcached_stat_st * stats ;
1545
1549
memcached_server_st * servers ;
1546
- unsigned int i , servers_count ;
1547
1550
memcached_return status ;
1548
- char * hostport = NULL ;
1549
- int hostport_len ;
1550
1551
zval * entry ;
1552
+ struct callbackContext context = {0 };
1553
+ memcached_server_function callbacks [1 ];
1551
1554
MEMC_METHOD_INIT_VARS ;
1552
1555
1553
1556
if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "" ) == FAILURE ) {
@@ -1562,46 +1565,13 @@ PHP_METHOD(Memcached, getStats)
1562
1565
}
1563
1566
1564
1567
array_init (return_value );
1565
- servers = memcached_server_list (i_obj -> memc );
1566
- servers_count = memcached_server_count (i_obj -> memc );
1567
- if (servers == NULL ) {
1568
- return ;
1569
- }
1570
1568
1571
- for (i = 0 ; i < servers_count ; i ++ ) {
1572
- hostport_len = spprintf (& hostport , 0 , "%s:%d" , servers [i ].hostname , servers [i ].port );
1573
-
1574
- MAKE_STD_ZVAL (entry );
1575
- array_init (entry );
1576
-
1577
- add_assoc_long (entry , "pid" , stats [i ].pid );
1578
- add_assoc_long (entry , "uptime" , stats [i ].uptime );
1579
- add_assoc_long (entry , "threads" , stats [i ].threads );
1580
- add_assoc_long (entry , "time" , stats [i ].time );
1581
- add_assoc_long (entry , "pointer_size" , stats [i ].pointer_size );
1582
- add_assoc_long (entry , "rusage_user_seconds" , stats [i ].rusage_user_seconds );
1583
- add_assoc_long (entry , "rusage_user_microseconds" , stats [i ].rusage_user_microseconds );
1584
- add_assoc_long (entry , "rusage_system_seconds" , stats [i ].rusage_system_seconds );
1585
- add_assoc_long (entry , "rusage_system_microseconds" , stats [i ].rusage_system_microseconds );
1586
- add_assoc_long (entry , "curr_items" , stats [i ].curr_items );
1587
- add_assoc_long (entry , "total_items" , stats [i ].total_items );
1588
- add_assoc_long (entry , "limit_maxbytes" , stats [i ].limit_maxbytes );
1589
- add_assoc_long (entry , "curr_connections" , stats [i ].curr_connections );
1590
- add_assoc_long (entry , "total_connections" , stats [i ].total_connections );
1591
- add_assoc_long (entry , "connection_structures" , stats [i ].connection_structures );
1592
- add_assoc_long (entry , "bytes" , stats [i ].bytes );
1593
- add_assoc_long (entry , "cmd_get" , stats [i ].cmd_get );
1594
- add_assoc_long (entry , "cmd_set" , stats [i ].cmd_set );
1595
- add_assoc_long (entry , "get_hits" , stats [i ].get_hits );
1596
- add_assoc_long (entry , "get_misses" , stats [i ].get_misses );
1597
- add_assoc_long (entry , "evictions" , stats [i ].evictions );
1598
- add_assoc_long (entry , "bytes_read" , stats [i ].bytes_read );
1599
- add_assoc_long (entry , "bytes_written" , stats [i ].bytes_written );
1600
- add_assoc_stringl (entry , "version" , stats [i ].version , strlen (stats [i ].version ), 1 );
1601
-
1602
- add_assoc_zval_ex (return_value , hostport , hostport_len + 1 , entry );
1603
- efree (hostport );
1604
- }
1569
+ callbacks [0 ] = php_memc_do_stats_callback ;
1570
+ context .i = 0 ;
1571
+ context .entry = entry ;
1572
+ context .stats = stats ;
1573
+ context .return_value = return_value ;
1574
+ memcached_server_cursor (i_obj -> memc , callbacks , & context , 1 );
1605
1575
1606
1576
memcached_stat_free (i_obj -> memc , stats );
1607
1577
}
@@ -1612,11 +1582,9 @@ PHP_METHOD(Memcached, getStats)
1612
1582
PHP_METHOD (Memcached , getVersion )
1613
1583
{
1614
1584
memcached_server_st * servers ;
1615
- unsigned int i , servers_count ;
1616
- char * hostport = NULL ;
1617
- char version [16 ];
1618
- int hostport_len , version_len ;
1619
1585
memcached_return status = MEMCACHED_SUCCESS ;
1586
+ struct callbackContext context = {0 };
1587
+ memcached_server_function callbacks [1 ];
1620
1588
MEMC_METHOD_INIT_VARS ;
1621
1589
1622
1590
if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "" ) == FAILURE ) {
@@ -1626,27 +1594,17 @@ PHP_METHOD(Memcached, getVersion)
1626
1594
MEMC_METHOD_FETCH_OBJECT ;
1627
1595
1628
1596
array_init (return_value );
1629
- servers = memcached_server_list (i_obj -> memc );
1630
- servers_count = memcached_server_count (i_obj -> memc );
1631
- if (servers == NULL ) {
1632
- return ;
1633
- }
1634
1597
1635
1598
status = memcached_version (i_obj -> memc );
1636
1599
if (php_memc_handle_error (status TSRMLS_CC ) < 0 ) {
1637
1600
zval_dtor (return_value );
1638
1601
RETURN_FALSE ;
1639
1602
}
1640
1603
1641
- for (i = 0 ; i < servers_count ; i ++ ) {
1642
- hostport_len = spprintf (& hostport , 0 , "%s:%d" , servers [i ].hostname , servers [i ].port );
1643
- version_len = snprintf (version , sizeof (version ), "%d.%d.%d" ,
1644
- servers [i ].major_version , servers [i ].minor_version ,
1645
- servers [i ].micro_version );
1604
+ callbacks [0 ] = php_memc_do_version_callback ;
1605
+ context .return_value = return_value ;
1646
1606
1647
- add_assoc_stringl_ex (return_value , hostport , hostport_len + 1 , version , version_len , 1 );
1648
- efree (hostport );
1649
- }
1607
+ memcached_server_cursor (i_obj -> memc , callbacks , & context , 1 );
1650
1608
}
1651
1609
/* }}} */
1652
1610
@@ -1925,6 +1883,79 @@ ZEND_RSRC_DTOR_FUNC(php_memc_dtor)
1925
1883
/* }}} */
1926
1884
1927
1885
/* {{{ internal API functions */
1886
+ static memcached_return php_memc_do_serverlist_callback (memcached_st * ptr , memcached_server_instance_st instance , void * in_context )
1887
+ {
1888
+ struct callbackContext * context = (struct callbackContext * ) in_context ;
1889
+
1890
+ MAKE_STD_ZVAL (context -> array );
1891
+ array_init (context -> array );
1892
+ add_assoc_string (context -> array , "host" , instance -> hostname , 1 );
1893
+ add_assoc_long (context -> array , "port" , instance -> port );
1894
+ add_assoc_long (context -> array , "weight" , instance -> weight );
1895
+ add_next_index_zval (context -> return_value , context -> array );
1896
+ return MEMCACHED_SUCCESS ;
1897
+ }
1898
+
1899
+ static memcached_return php_memc_do_stats_callback (memcached_st * ptr , memcached_server_instance_st instance , void * in_context )
1900
+ {
1901
+ char * hostport = NULL ;
1902
+ int hostport_len ;
1903
+ struct callbackContext * context = (struct callbackContext * ) in_context ;
1904
+ hostport_len = spprintf (& hostport , 0 , "%s:%d" , instance -> hostname , instance -> port );
1905
+
1906
+ MAKE_STD_ZVAL (context -> entry );
1907
+ array_init (context -> entry );
1908
+
1909
+ add_assoc_long (context -> entry , "pid" , context -> stats [context -> i ].pid );
1910
+ add_assoc_long (context -> entry , "uptime" , context -> stats [context -> i ].uptime );
1911
+ add_assoc_long (context -> entry , "threads" , context -> stats [context -> i ].threads );
1912
+ add_assoc_long (context -> entry , "time" , context -> stats [context -> i ].time );
1913
+ add_assoc_long (context -> entry , "pointer_size" , context -> stats [context -> i ].pointer_size );
1914
+ add_assoc_long (context -> entry , "rusage_user_seconds" , context -> stats [context -> i ].rusage_user_seconds );
1915
+ add_assoc_long (context -> entry , "rusage_user_microseconds" , context -> stats [context -> i ].rusage_user_microseconds );
1916
+ add_assoc_long (context -> entry , "rusage_system_seconds" , context -> stats [context -> i ].rusage_system_seconds );
1917
+ add_assoc_long (context -> entry , "rusage_system_microseconds" , context -> stats [context -> i ].rusage_system_microseconds );
1918
+ add_assoc_long (context -> entry , "curr_items" , context -> stats [context -> i ].curr_items );
1919
+ add_assoc_long (context -> entry , "total_items" , context -> stats [context -> i ].total_items );
1920
+ add_assoc_long (context -> entry , "limit_maxbytes" , context -> stats [context -> i ].limit_maxbytes );
1921
+ add_assoc_long (context -> entry , "curr_connections" , context -> stats [context -> i ].curr_connections );
1922
+ add_assoc_long (context -> entry , "total_connections" , context -> stats [context -> i ].total_connections );
1923
+ add_assoc_long (context -> entry , "connection_structures" , context -> stats [context -> i ].connection_structures );
1924
+ add_assoc_long (context -> entry , "bytes" , context -> stats [context -> i ].bytes );
1925
+ add_assoc_long (context -> entry , "cmd_get" , context -> stats [context -> i ].cmd_get );
1926
+ add_assoc_long (context -> entry , "cmd_set" , context -> stats [context -> i ].cmd_set );
1927
+ add_assoc_long (context -> entry , "get_hits" , context -> stats [context -> i ].get_hits );
1928
+ add_assoc_long (context -> entry , "get_misses" , context -> stats [context -> i ].get_misses );
1929
+ add_assoc_long (context -> entry , "evictions" , context -> stats [context -> i ].evictions );
1930
+ add_assoc_long (context -> entry , "bytes_read" , context -> stats [context -> i ].bytes_read );
1931
+ add_assoc_long (context -> entry , "bytes_written" , context -> stats [context -> i ].bytes_written );
1932
+ add_assoc_stringl (context -> entry , "version" , context -> stats [context -> i ].version , strlen (context -> stats [context -> i ].version ), 1 );
1933
+
1934
+ add_assoc_zval_ex (context -> return_value , hostport , hostport_len + 1 , context -> entry );
1935
+ efree (hostport );
1936
+
1937
+ /* Increment the server count in our context structure. Failure to do so will cause only the stats for the last server to get displayed. */
1938
+ context -> i ++ ;
1939
+ return MEMCACHED_SUCCESS ;
1940
+ }
1941
+
1942
+ static memcached_return php_memc_do_version_callback (memcached_st * ptr , memcached_server_instance_st instance , void * in_context )
1943
+ {
1944
+ char * hostport = NULL ;
1945
+ char version [16 ];
1946
+ int hostport_len , version_len ;
1947
+ struct callbackContext * context = (struct callbackContext * ) in_context ;
1948
+
1949
+ hostport_len = spprintf (& hostport , 0 , "%s:%d" , instance -> hostname , instance -> port );
1950
+ version_len = snprintf (version , sizeof (version ), "%d.%d.%d" ,
1951
+ instance -> major_version , instance -> minor_version ,
1952
+ instance -> micro_version );
1953
+
1954
+ add_assoc_stringl_ex (context -> return_value , hostport , hostport_len + 1 , version , version_len , 1 );
1955
+ efree (hostport );
1956
+ return MEMCACHED_SUCCESS ;
1957
+ }
1958
+
1928
1959
static int php_memc_handle_error (memcached_return status TSRMLS_DC )
1929
1960
{
1930
1961
int result = 0 ;
@@ -1999,7 +2030,7 @@ static char *php_memc_zval_to_payload(zval *value, size_t *payload_len, uint32_t
1999
2030
#if HAVE_JSON_API
2000
2031
case SERIALIZER_JSON :
2001
2032
{
2002
- php_json_encode (& buf , value TSRMLS_CC );
2033
+ php_json_encode (& buf , value , 0 TSRMLS_CC );
2003
2034
buf .c [buf .len ] = 0 ;
2004
2035
MEMC_VAL_SET_TYPE (* flags , MEMC_VAL_IS_JSON );
2005
2036
break ;
@@ -2164,7 +2195,7 @@ static int php_memc_zval_from_payload(zval *value, char *payload, size_t payload
2164
2195
2165
2196
case MEMC_VAL_IS_JSON :
2166
2197
#if HAVE_JSON_API
2167
- php_json_decode (value , payload , payload_len , 0 TSRMLS_CC );
2198
+ php_json_decode (value , payload , payload_len , 0 , 512 TSRMLS_CC );
2168
2199
#else
2169
2200
php_error_docref (NULL TSRMLS_CC , E_WARNING , "could not unserialize value, no json support" );
2170
2201
return -1 ;
@@ -2777,8 +2808,8 @@ static zend_function_entry memcached_class_methods[] = {
2777
2808
MEMC_ME (getServerList , arginfo_getServerList )
2778
2809
MEMC_ME (getServerByKey , arginfo_getServerByKey )
2779
2810
2780
- MEMC_ME (getStats , arginfo_getStats )
2781
- MEMC_ME (getVersion , arginfo_getVersion )
2811
+ MEMC_ME (getStats , arginfo_getStats )
2812
+ MEMC_ME (getVersion , arginfo_getVersion )
2782
2813
2783
2814
MEMC_ME (flush , arginfo_flush )
2784
2815
0 commit comments