@@ -51,6 +51,55 @@ PHONGO_API zend_class_entry *php_phongo_manager_ce;
51
51
52
52
zend_object_handlers php_phongo_handler_manager ;
53
53
54
+ /* Checks if driverOptions contains a stream context resource in the "context"
55
+ * key and incorporates any of its SSL options into the base array that did not
56
+ * already exist (i.e. array union). The "context" key is then unset from the
57
+ * base array.
58
+ *
59
+ * This handles the merging of any legacy SSL context options and also makes
60
+ * driverOptions suitable for serialization by removing the resource zval. */
61
+ static bool php_phongo_manager_merge_context_options (zval * zdriverOptions TSRMLS_DC )
62
+ {
63
+ php_stream_context * context ;
64
+ zval * zcontext , * zcontextOptions ;
65
+
66
+ if (!php_array_existsc (zdriverOptions , "context" )) {
67
+ return true;
68
+ }
69
+
70
+ zcontext = php_array_fetchc (zdriverOptions , "context" );
71
+ context = php_stream_context_from_zval (zcontext , 1 );
72
+
73
+ if (!context ) {
74
+ phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC , "\"context\" driver option is not a valid Stream-Context resource" );
75
+ return false;
76
+ }
77
+
78
+ #if PHP_VERSION_ID >= 70000
79
+ zcontextOptions = php_array_fetchc_array (& context -> options , "ssl" );
80
+ #else
81
+ zcontextOptions = php_array_fetchc_array (context -> options , "ssl" );
82
+ #endif
83
+
84
+ if (!zcontextOptions ) {
85
+ phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC , "Stream-Context resource does not contain \"ssl\" options array" );
86
+ return false;
87
+ }
88
+
89
+ /* Perform array union (see: add_function() in zend_operators.c) */
90
+ #if PHP_VERSION_ID >= 70000
91
+ zend_hash_merge (Z_ARRVAL_P (zdriverOptions ), Z_ARRVAL_P (zcontextOptions ), zval_add_ref , 0 );
92
+ #else
93
+ {
94
+ zval * tmp ;
95
+ zend_hash_merge (Z_ARRVAL_P (zdriverOptions ), Z_ARRVAL_P (zcontextOptions ), (void (* )(void * pData )) zval_add_ref , (void * ) & tmp , sizeof (zval * ), 0 );
96
+ }
97
+ #endif
98
+
99
+ php_array_unsetc (zdriverOptions , "context" );
100
+ return true;
101
+ }
102
+
54
103
/* {{{ proto void Manager::__construct([string $uri = "mongodb://127.0.0.1/"[, array $options = array()[, array $driverOptions = array()]]])
55
104
Constructs a new Manager */
56
105
PHP_METHOD (Manager , __construct )
@@ -60,26 +109,27 @@ PHP_METHOD(Manager, __construct)
60
109
char * uri_string = NULL ;
61
110
phongo_zpp_char_len uri_string_len = 0 ;
62
111
zval * options = NULL ;
63
- bson_t bson_options = BSON_INITIALIZER ;
64
112
zval * driverOptions = NULL ;
65
113
SUPPRESS_UNUSED_WARNING (return_value ) SUPPRESS_UNUSED_WARNING (return_value_ptr ) SUPPRESS_UNUSED_WARNING (return_value_used )
66
114
67
115
68
116
zend_replace_error_handling (EH_THROW , phongo_exception_from_phongo_domain (PHONGO_ERROR_INVALID_ARGUMENT ), & error_handling TSRMLS_CC );
69
117
intern = Z_MANAGER_OBJ_P (getThis ());
70
118
119
+ /* Separate the driverOptions zval, since we may end up modifying it in
120
+ * php_phongo_manager_merge_context_options() below. */
71
121
if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "|s!a!a!" , & uri_string , & uri_string_len , & options , & driverOptions ) == FAILURE ) {
72
122
zend_restore_error_handling (& error_handling TSRMLS_CC );
73
123
return ;
74
124
}
75
125
zend_restore_error_handling (& error_handling TSRMLS_CC );
76
126
77
- if (options ) {
78
- phongo_zval_to_bson (options , PHONGO_BSON_NONE , & bson_options , NULL TSRMLS_CC );
127
+ if (driverOptions && !php_phongo_manager_merge_context_options (driverOptions TSRMLS_CC )) {
128
+ /* Exception should already have been thrown */
129
+ return ;
79
130
}
80
131
81
- phongo_manager_init (intern , uri_string ? uri_string : PHONGO_MANAGER_URI_DEFAULT , & bson_options , driverOptions TSRMLS_CC );
82
- bson_destroy (& bson_options );
132
+ phongo_manager_init (intern , uri_string ? uri_string : PHONGO_MANAGER_URI_DEFAULT , options , driverOptions TSRMLS_CC );
83
133
}
84
134
/* }}} */
85
135
@@ -359,7 +409,8 @@ static void php_phongo_manager_free_object(phongo_free_object_arg *object TSRMLS
359
409
zend_object_std_dtor (& intern -> std TSRMLS_CC );
360
410
361
411
if (intern -> client ) {
362
- mongoc_client_destroy (intern -> client );
412
+ MONGOC_DEBUG ("Not destroying persistent client for Manager" );
413
+ intern -> client = NULL ;
363
414
}
364
415
365
416
#if PHP_VERSION_ID < 70000
0 commit comments