@@ -4918,93 +4918,92 @@ PHP_METHOD(Redis, hIncrBy)
49184918
49194919}
49204920
4921-
4921+ /* {{{ array Redis::hMget(string hash, array keys) */
49224922PHP_METHOD (Redis , hMget ) {
49234923 zval * object ;
49244924 RedisSock * redis_sock ;
4925- char * key = NULL , * cmd ;
4926- int key_len , cmd_len , key_free ;
4927- zval * z_array ;
4928- zval * * z_keys ;
4929- int nb_fields , i ;
4930- char * old_cmd = NULL ;
4931-
4932- zval * * data ;
4933- HashTable * arr_hash ;
4934- HashPosition pointer ;
4925+ char * key = NULL ;
4926+ zval * z_array , * * z_keys , * * data ;
4927+ int field_count , i , valid , key_len , key_free ;
4928+ HashTable * ht_array ;
4929+ HashPosition ptr ;
4930+ smart_str cmd = {0 };
49354931
4936- if (zend_parse_method_parameters (ZEND_NUM_ARGS () TSRMLS_CC , getThis (), "Osa" ,
4937- & object , redis_ce ,
4938- & key , & key_len , & z_array ) == FAILURE ) {
4932+ // Make sure we can grab our arguments properly
4933+ if (zend_parse_method_parameters (ZEND_NUM_ARGS () TSRMLS_CC , getThis (), "Osa" ,
4934+ & object , redis_ce , & key , & key_len , & z_array )
4935+ == FAILURE )
4936+ {
49394937 RETURN_FALSE ;
49404938 }
49414939
4942- if (redis_sock_get (object , & redis_sock TSRMLS_CC , 0 ) < 0 ) {
4940+ // We'll need our socket
4941+ if (redis_sock_get (object , & redis_sock TSRMLS_CC , 0 ) < 0 ) {
49434942 RETURN_FALSE ;
49444943 }
4945- nb_fields = zend_hash_num_elements (Z_ARRVAL_P (z_array ));
49464944
4947- if ( nb_fields == 0 ) {
4945+ // Grab member count and abort if we don't have any
4946+ if ((field_count = zend_hash_num_elements (Z_ARRVAL_P (z_array ))) == 0 ) {
49484947 RETURN_FALSE ;
49494948 }
49504949
4951- z_keys = ecalloc (nb_fields , sizeof (zval * ));
4950+ // Prefix our key if we need to
4951+ key_free = redis_key_prefix (redis_sock , & key , & key_len TSRMLS_CC );
49524952
4953- key_free = redis_key_prefix (redis_sock , & key , & key_len TSRMLS_CC );
4953+ // Allocate enough memory for the number of keys being requested
4954+ z_keys = ecalloc (field_count , sizeof (zval * ));
49544955
4955- cmd_len = redis_cmd_format (& cmd ,
4956- "*%d" _NL
4957- "$5" _NL
4958- "HMGET" _NL
4956+ // Grab our HashTable
4957+ ht_array = Z_ARRVAL_P (z_array );
49594958
4960- "$%d" _NL /* key */
4961- "%s" _NL
4962- , nb_fields + 2
4963- , key_len , key , key_len );
4964- if (key_free ) efree (key );
4959+ // Iterate through our keys, grabbing members that are valid
4960+ for (valid = 0 , zend_hash_internal_pointer_reset_ex (ht_array , & ptr );
4961+ zend_hash_get_current_data_ex (ht_array , (void * * )& data , & ptr )== SUCCESS ;
4962+ zend_hash_move_forward_ex (ht_array , & ptr ))
4963+ {
4964+ // Make sure the data is a long or string, and if it's a string that
4965+ // it isn't empty. There is no reason to send empty length members.
4966+ if ((Z_TYPE_PP (data ) == IS_STRING && Z_STRLEN_PP (data )> 0 ) ||
4967+ Z_TYPE_PP (data ) == IS_LONG )
4968+ {
4969+ // This is a key we can ask for, copy it and set it in our array
4970+ MAKE_STD_ZVAL (z_keys [valid ]);
4971+ * z_keys [valid ] = * * data ;
4972+ zval_copy_ctor (z_keys [valid ]);
4973+ convert_to_string (z_keys [valid ]);
4974+
4975+ // Increment the number of valid keys we've encountered
4976+ valid ++ ;
4977+ }
4978+ }
49654979
4966- arr_hash = Z_ARRVAL_P (z_array );
4980+ // If we don't have any valid keys, we can abort here
4981+ if (valid == 0 ) {
4982+ if (key_free ) efree (key );
4983+ efree (z_keys );
4984+ RETURN_FALSE ;
4985+ }
49674986
4968- for (i = 0 , zend_hash_internal_pointer_reset_ex (arr_hash , & pointer );
4969- zend_hash_get_current_data_ex (arr_hash , (void * * ) & data ,
4970- & pointer ) == SUCCESS ;
4971- zend_hash_move_forward_ex (arr_hash , & pointer )) {
4987+ // Build command header. One extra argument for the hash key itself
4988+ redis_cmd_init_sstr (& cmd , valid + 1 , "HMGET" , sizeof ("HMGET" )- 1 );
49724989
4973- if (Z_TYPE_PP (data ) == IS_LONG || Z_TYPE_PP (data ) == IS_STRING ) {
4990+ // Add the hash key
4991+ redis_cmd_append_sstr (& cmd , key , key_len );
49744992
4975- old_cmd = cmd ;
4976- if (Z_TYPE_PP (data ) == IS_LONG ) {
4977- cmd_len = redis_cmd_format (& cmd , "%s" "$%d" _NL "%d" _NL
4978- , cmd , cmd_len
4979- , integer_length (Z_LVAL_PP (data )), (int )Z_LVAL_PP (data ));
4980- } else if (Z_TYPE_PP (data ) == IS_STRING ) {
4981- cmd_len = redis_cmd_format (& cmd , "%s" "$%d" _NL "%s" _NL
4982- , cmd , cmd_len
4983- , Z_STRLEN_PP (data ), Z_STRVAL_PP (data ), Z_STRLEN_PP (data ));
4984- }
4985- efree (old_cmd );
4986- /* save context */
4987- MAKE_STD_ZVAL (z_keys [i ]);
4988- * z_keys [i ] = * * data ;
4989- zval_copy_ctor (z_keys [i ]);
4990- convert_to_string (z_keys [i ]);
4993+ // Free key memory if it was prefixed
4994+ if (key_free ) efree (key );
49914995
4992- i ++ ;
4993- }
4996+ // Iterate our keys, appending them as arguments
4997+ for (i = 0 ;i < valid ;i ++ ) {
4998+ redis_cmd_append_sstr (& cmd , Z_STRVAL_P (z_keys [i ]), Z_STRLEN_P (z_keys [i ]));
49944999 }
49955000
4996- // This is a failure if none of the keys were valid
4997- if (i == 0 ) {
4998- efree (cmd );
4999- efree (z_keys );
5000- RETURN_FALSE ;
5001+ // Kick off our request
5002+ REDIS_PROCESS_REQUEST (redis_sock , cmd .c , cmd .len );
5003+ IF_ATOMIC () {
5004+ redis_sock_read_multibulk_reply_assoc (INTERNAL_FUNCTION_PARAM_PASSTHRU , redis_sock , NULL , z_keys );
50015005 }
5002-
5003- REDIS_PROCESS_REQUEST (redis_sock , cmd , cmd_len );
5004- IF_ATOMIC () {
5005- redis_sock_read_multibulk_reply_assoc (INTERNAL_FUNCTION_PARAM_PASSTHRU , redis_sock , NULL , z_keys );
5006- }
5007- REDIS_PROCESS_RESPONSE_CLOSURE (redis_sock_read_multibulk_reply_assoc , z_keys );
5006+ REDIS_PROCESS_RESPONSE_CLOSURE (redis_sock_read_multibulk_reply_assoc , z_keys );
50085007}
50095008
50105009PHP_METHOD (Redis , hMset )
0 commit comments