@@ -51,6 +51,55 @@ PHONGO_API zend_class_entry *php_phongo_manager_ce;
5151
5252zend_object_handlers php_phongo_handler_manager ;
5353
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+
54103/* {{{ proto void Manager::__construct([string $uri = "mongodb://127.0.0.1/"[, array $options = array()[, array $driverOptions = array()]]])
55104 Constructs a new Manager */
56105PHP_METHOD (Manager , __construct )
@@ -60,26 +109,27 @@ PHP_METHOD(Manager, __construct)
60109 char * uri_string = NULL ;
61110 phongo_zpp_char_len uri_string_len = 0 ;
62111 zval * options = NULL ;
63- bson_t bson_options = BSON_INITIALIZER ;
64112 zval * driverOptions = NULL ;
65113 SUPPRESS_UNUSED_WARNING (return_value ) SUPPRESS_UNUSED_WARNING (return_value_ptr ) SUPPRESS_UNUSED_WARNING (return_value_used )
66114
67115
68116 zend_replace_error_handling (EH_THROW , phongo_exception_from_phongo_domain (PHONGO_ERROR_INVALID_ARGUMENT ), & error_handling TSRMLS_CC );
69117 intern = Z_MANAGER_OBJ_P (getThis ());
70118
119+ /* Separate the driverOptions zval, since we may end up modifying it in
120+ * php_phongo_manager_merge_context_options() below. */
71121 if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "|s!a!a!" , & uri_string , & uri_string_len , & options , & driverOptions ) == FAILURE ) {
72122 zend_restore_error_handling (& error_handling TSRMLS_CC );
73123 return ;
74124 }
75125 zend_restore_error_handling (& error_handling TSRMLS_CC );
76126
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 ;
79130 }
80131
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 );
83133}
84134/* }}} */
85135
@@ -359,7 +409,8 @@ static void php_phongo_manager_free_object(phongo_free_object_arg *object TSRMLS
359409 zend_object_std_dtor (& intern -> std TSRMLS_CC );
360410
361411 if (intern -> client ) {
362- mongoc_client_destroy (intern -> client );
412+ MONGOC_DEBUG ("Not destroying persistent client for Manager" );
413+ intern -> client = NULL ;
363414 }
364415
365416#if PHP_VERSION_ID < 70000
0 commit comments