@@ -100,6 +100,67 @@ static bool php_phongo_manager_merge_context_options(zval *zdriverOptions TSRMLS
100100 return true;
101101}
102102
103+ /* Prepare tagSets for BSON encoding by converting each array in the set to an
104+ * object. This ensures that empty arrays will serialize as empty documents.
105+ *
106+ * php_phongo_read_preference_tags_are_valid() handles actual validation of the
107+ * tag set structure. */
108+ static void php_phongo_manager_prep_tagsets (zval * options TSRMLS_DC )
109+ {
110+ HashTable * ht_data ;
111+
112+ if (Z_TYPE_P (options ) != IS_ARRAY ) {
113+ return ;
114+ }
115+
116+ ht_data = HASH_OF (options );
117+
118+ #if PHP_VERSION_ID >= 70000
119+ {
120+ zend_string * string_key = NULL ;
121+ zend_ulong num_key = 0 ;
122+ zval * tagSets ;
123+
124+ ZEND_HASH_FOREACH_KEY_VAL (ht_data , num_key , string_key , tagSets ) {
125+ if (!string_key ) {
126+ continue ;
127+ }
128+
129+ /* php_phongo_make_uri() and php_phongo_apply_rp_options_to_uri()
130+ * are both case-insensitive, so we need to be as well. */
131+ if (!strcasecmp (ZSTR_VAL (string_key ), "readpreferencetags" )) {
132+ php_phongo_read_preference_prep_tagsets (tagSets TSRMLS_CC );
133+ }
134+ } ZEND_HASH_FOREACH_END ();
135+ }
136+ #else
137+ {
138+ HashPosition pos ;
139+ zval * * tagSets ;
140+
141+ for (zend_hash_internal_pointer_reset_ex (ht_data , & pos );
142+ zend_hash_get_current_data_ex (ht_data , (void * * ) & tagSets , & pos ) == SUCCESS ;
143+ zend_hash_move_forward_ex (ht_data , & pos )) {
144+ char * string_key = NULL ;
145+ uint string_key_len = 0 ;
146+ ulong num_key = 0 ;
147+
148+ if (HASH_KEY_IS_STRING != zend_hash_get_current_key_ex (ht_data , & string_key , & string_key_len , & num_key , 0 , & pos )) {
149+ continue ;
150+ }
151+
152+ /* php_phongo_make_uri() and php_phongo_apply_rp_options_to_uri()
153+ * are both case-insensitive, so we need to be as well. */
154+ if (!strcasecmp (string_key , "readpreferencetags" )) {
155+ php_phongo_read_preference_prep_tagsets (* tagSets TSRMLS_CC );
156+ }
157+ }
158+ }
159+ #endif
160+
161+ return ;
162+ } /* }}} */
163+
103164/* {{{ proto void Manager::__construct([string $uri = "mongodb://127.0.0.1/"[, array $options = array()[, array $driverOptions = array()]]])
104165 Constructs a new Manager */
105166PHP_METHOD (Manager , __construct )
@@ -124,6 +185,10 @@ PHP_METHOD(Manager, __construct)
124185 }
125186 zend_restore_error_handling (& error_handling TSRMLS_CC );
126187
188+ if (options ) {
189+ php_phongo_manager_prep_tagsets (options TSRMLS_CC );
190+ }
191+
127192 if (driverOptions && !php_phongo_manager_merge_context_options (driverOptions TSRMLS_CC )) {
128193 /* Exception should already have been thrown */
129194 return ;
0 commit comments