@@ -4918,93 +4918,92 @@ PHP_METHOD(Redis, hIncrBy)
4918
4918
4919
4919
}
4920
4920
4921
-
4921
+ /* {{{ array Redis::hMget(string hash, array keys) */
4922
4922
PHP_METHOD (Redis , hMget ) {
4923
4923
zval * object ;
4924
4924
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 };
4935
4931
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
+ {
4939
4937
RETURN_FALSE ;
4940
4938
}
4941
4939
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 ) {
4943
4942
RETURN_FALSE ;
4944
4943
}
4945
- nb_fields = zend_hash_num_elements (Z_ARRVAL_P (z_array ));
4946
4944
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 ) {
4948
4947
RETURN_FALSE ;
4949
4948
}
4950
4949
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 );
4952
4952
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 * ));
4954
4955
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 );
4959
4958
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
+ }
4965
4979
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
+ }
4967
4986
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 );
4972
4989
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 );
4974
4992
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 );
4991
4995
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 ]));
4994
4999
}
4995
5000
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 );
5001
5005
}
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 );
5008
5007
}
5009
5008
5010
5009
PHP_METHOD (Redis , hMset )
0 commit comments