@@ -219,7 +219,7 @@ static char *dsn_from_uri(char *uri, char *buf, size_t buflen) /* {{{ */
219
219
}
220
220
/* }}} */
221
221
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 )
223
223
{
224
224
zend_class_entry * ce ;
225
225
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
235
235
236
236
if (ce_based_on_called_object ) {
237
237
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 )) {
239
239
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
+ );
243
249
return false;
244
250
}
245
251
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
+ }
248
256
return true;
249
257
} else {
250
258
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
+ );
254
265
return false;
255
266
}
256
267
}
257
268
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
+
258
274
if (ce_based_on_driver_name ) {
259
275
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 */
261
277
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
+ );
265
287
return false;
266
288
}
267
289
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 ) {
271
294
/* No driver-specific implementation found */
272
- object_init_ex (new_object , called_scope );
295
+ object_init_ex (new_zval_object , called_scope );
273
296
}
274
297
275
298
return true;
276
299
}
277
300
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 )
279
302
{
280
303
pdo_dbh_t * dbh = NULL ;
281
304
bool is_persistent = 0 ;
@@ -343,15 +366,16 @@ static void internal_construct(INTERNAL_FUNCTION_PARAMETERS, zend_object *object
343
366
RETURN_THROWS ();
344
367
}
345
368
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
+ }
351
374
375
+ if (new_zval_object ) {
352
376
dbh = Z_PDO_DBH_P (new_zval_object );
353
377
} else {
354
- dbh = php_pdo_dbh_fetch_inner (object );
378
+ dbh = php_pdo_dbh_fetch_inner (current_object );
355
379
}
356
380
357
381
/* is this supposed to be a persistent connection ? */
@@ -413,7 +437,7 @@ static void internal_construct(INTERNAL_FUNCTION_PARAMETERS, zend_object *object
413
437
if (pdbh ) {
414
438
efree (dbh );
415
439
/* 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 ;
417
441
pdbh -> refcount ++ ;
418
442
dbh = pdbh ;
419
443
}
@@ -497,14 +521,14 @@ static void internal_construct(INTERNAL_FUNCTION_PARAMETERS, zend_object *object
497
521
/* {{{ */
498
522
PHP_METHOD (PDO , __construct )
499
523
{
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 );
501
525
}
502
526
/* }}} */
503
527
504
528
/* {{{ */
505
529
PHP_METHOD (PDO , connect )
506
530
{
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 );
508
532
}
509
533
/* }}} */
510
534
0 commit comments