@@ -219,7 +219,7 @@ static char *dsn_from_uri(char *uri, char *buf, size_t buflen) /* {{{ */
219219}
220220/* }}} */
221221
222- static bool create_driver_specific_pdo_object (pdo_driver_t * driver , zend_class_entry * called_scope , zval * new_object )
222+ static bool create_driver_specific_pdo_object (pdo_driver_t * driver , zend_class_entry * called_scope , zval * new_zval_object )
223223{
224224 zend_class_entry * ce ;
225225 zend_class_entry * ce_based_on_driver_name = NULL , * ce_based_on_called_object = NULL ;
@@ -235,47 +235,70 @@ static bool create_driver_specific_pdo_object(pdo_driver_t *driver, zend_class_e
235235
236236 if (ce_based_on_called_object ) {
237237 if (ce_based_on_driver_name ) {
238- if (instanceof_function (ce_based_on_called_object , ce_based_on_driver_name ) == false ) {
238+ if (! instanceof_function (ce_based_on_called_object , ce_based_on_driver_name )) {
239239 zend_throw_exception_ex (pdo_exception_ce , 0 ,
240- "%s::connect() cannot be called when connecting to the \"%s\" driver, "
241- "either %s::connect() or PDO::connect() must be called instead" ,
242- ZSTR_VAL (called_scope -> name ), driver -> driver_name , ZSTR_VAL (ce_based_on_driver_name -> name ));
240+ "%s::%s() cannot be used for connecting to the \"%s\" driver, "
241+ "either call %s::%s() or PDO::%s() instead" ,
242+ ZSTR_VAL (called_scope -> name ),
243+ new_zval_object ? "connect" : "__construct" ,
244+ driver -> driver_name ,
245+ ZSTR_VAL (ce_based_on_driver_name -> name ),
246+ new_zval_object ? "connect" : "__construct" ,
247+ new_zval_object ? "connect" : "__construct"
248+ );
243249 return false;
244250 }
245251
246- /* A driver-specific implementation was instantiated via the connect() method of the appropriate driver class */
247- object_init_ex (new_object , ce_based_on_called_object );
252+ /* A driver-specific implementation is instantiated with the appropriate driver class */
253+ if (new_zval_object ) {
254+ object_init_ex (new_zval_object , called_scope );
255+ }
248256 return true;
249257 } else {
250258 zend_throw_exception_ex (pdo_exception_ce , 0 ,
251- "%s::connect() cannot be called when connecting to an unknown driver, "
252- "PDO::connect() must be called instead" ,
253- ZSTR_VAL (called_scope -> name ));
259+ "%s::%s() cannot be used for connecting to an unknown driver, "
260+ "call PDO::%s() instead" ,
261+ ZSTR_VAL (called_scope -> name ),
262+ new_zval_object ? "connect" : "__construct" ,
263+ new_zval_object ? "connect" : "__construct"
264+ );
254265 return false;
255266 }
256267 }
257268
269+ /* A non-driver specific PDO subclass is instantiated via the constructor. This results in the legacy behavior. */
270+ if (called_scope != pdo_dbh_ce && new_zval_object == NULL ) {
271+ return true;
272+ }
273+
258274 if (ce_based_on_driver_name ) {
259275 if (called_scope != pdo_dbh_ce ) {
260- /* A driver-specific implementation was instantiated via the connect method of a wrong driver class */
276+ /* A driver-specific implementation is instantiated with a wrong driver class */
261277 zend_throw_exception_ex (pdo_exception_ce , 0 ,
262- "%s::connect() cannot be called when connecting to the \"%s\" driver, "
263- "either %s::connect() or PDO::connect() must be called instead" ,
264- ZSTR_VAL (called_scope -> name ), driver -> driver_name , ZSTR_VAL (ce_based_on_driver_name -> name ));
278+ "%s::%s() cannot be used for connecting to the \"%s\" driver, "
279+ "either call %s::%s() or PDO::%s() instead" ,
280+ ZSTR_VAL (called_scope -> name ),
281+ new_zval_object ? "connect" : "__construct" ,
282+ driver -> driver_name ,
283+ ZSTR_VAL (ce_based_on_driver_name -> name ),
284+ new_zval_object ? "connect" : "__construct" ,
285+ new_zval_object ? "connect" : "__construct"
286+ );
265287 return false;
266288 }
267289
268- /* A driver-specific implementation was instantiated via PDO::__construct() */
269- object_init_ex (new_object , ce_based_on_driver_name );
270- } else {
290+ if (new_zval_object ) {
291+ object_init_ex (new_zval_object , ce_based_on_driver_name );
292+ }
293+ } else if (new_zval_object ) {
271294 /* No driver-specific implementation found */
272- object_init_ex (new_object , called_scope );
295+ object_init_ex (new_zval_object , called_scope );
273296 }
274297
275298 return true;
276299}
277300
278- static void internal_construct (INTERNAL_FUNCTION_PARAMETERS , zend_object * object , zend_class_entry * current_scope , zval * new_zval_object )
301+ PDO_API void php_pdo_internal_construct_driver (INTERNAL_FUNCTION_PARAMETERS , zend_object * current_object , zend_class_entry * called_scope , zval * new_zval_object )
279302{
280303 pdo_dbh_t * dbh = NULL ;
281304 bool is_persistent = 0 ;
@@ -343,15 +366,16 @@ static void internal_construct(INTERNAL_FUNCTION_PARAMETERS, zend_object *object
343366 RETURN_THROWS ();
344367 }
345368
346- if ( new_zval_object != NULL ) {
347- ZEND_ASSERT (( driver -> driver_name != NULL ) && "PDO driver name is null" );
348- if (!create_driver_specific_pdo_object (driver , current_scope , new_zval_object )) {
349- RETURN_THROWS ();
350- }
369+ ZEND_ASSERT (( driver -> driver_name != NULL ) && "PDO driver name is null" );
370+
371+ if (!create_driver_specific_pdo_object (driver , called_scope , new_zval_object )) {
372+ RETURN_THROWS ();
373+ }
351374
375+ if (new_zval_object ) {
352376 dbh = Z_PDO_DBH_P (new_zval_object );
353377 } else {
354- dbh = php_pdo_dbh_fetch_inner (object );
378+ dbh = php_pdo_dbh_fetch_inner (current_object );
355379 }
356380
357381 /* is this supposed to be a persistent connection ? */
@@ -413,7 +437,7 @@ static void internal_construct(INTERNAL_FUNCTION_PARAMETERS, zend_object *object
413437 if (pdbh ) {
414438 efree (dbh );
415439 /* switch over to the persistent one */
416- php_pdo_dbh_fetch_object (object )-> inner = pdbh ;
440+ php_pdo_dbh_fetch_object (current_object )-> inner = pdbh ;
417441 pdbh -> refcount ++ ;
418442 dbh = pdbh ;
419443 }
@@ -497,14 +521,14 @@ static void internal_construct(INTERNAL_FUNCTION_PARAMETERS, zend_object *object
497521/* {{{ */
498522PHP_METHOD (PDO , __construct )
499523{
500- internal_construct (INTERNAL_FUNCTION_PARAM_PASSTHRU , Z_OBJ ( EX ( This )), EX ( This ). value . ce , NULL );
524+ php_pdo_internal_construct_driver (INTERNAL_FUNCTION_PARAM_PASSTHRU , Z_OBJ_P ( ZEND_THIS ), Z_OBJCE_P ( ZEND_THIS ) , NULL );
501525}
502526/* }}} */
503527
504528/* {{{ */
505529PHP_METHOD (PDO , connect )
506530{
507- internal_construct (INTERNAL_FUNCTION_PARAM_PASSTHRU , Z_OBJ ( EX ( This )), EX ( This ). value . ce , return_value );
531+ php_pdo_internal_construct_driver (INTERNAL_FUNCTION_PARAM_PASSTHRU , NULL , Z_CE_P ( ZEND_THIS ) , return_value );
508532}
509533/* }}} */
510534
0 commit comments