@@ -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