@@ -434,11 +434,9 @@ PHP_METHOD(PDO, __construct)
434
434
}
435
435
/* }}} */
436
436
437
- static zval * pdo_stmt_instantiate (pdo_dbh_t * dbh , zval * object , zend_class_entry * dbstmt_ce , zval * ctor_args ) /* {{{ */
437
+ static zval * pdo_stmt_instantiate (pdo_dbh_t * dbh , zval * object , zend_class_entry * dbstmt_ce , const HashTable * ctor_args ) /* {{{ */
438
438
{
439
- if (!Z_ISUNDEF_P (ctor_args )) {
440
- /* This implies an error within PDO if this does not hold */
441
- ZEND_ASSERT (Z_TYPE_P (ctor_args ) == IS_ARRAY );
439
+ if (ctor_args ) {
442
440
if (!dbstmt_ce -> constructor ) {
443
441
zend_throw_error (NULL , "User-supplied statement does not accept constructor arguments" );
444
442
return NULL ;
@@ -475,8 +473,9 @@ PHP_METHOD(PDO, prepare)
475
473
{
476
474
pdo_stmt_t * stmt ;
477
475
zend_string * statement ;
478
- zval * options = NULL , * value , * item , ctor_args ;
476
+ zval * options = NULL , * value , * item ;
479
477
zend_class_entry * dbstmt_ce , * pce ;
478
+ /* const */ HashTable * ctor_args = NULL ;
480
479
pdo_dbh_object_t * dbh_obj = Z_PDO_OBJECT_P (ZEND_THIS );
481
480
pdo_dbh_t * dbh = dbh_obj -> inner ;
482
481
@@ -525,16 +524,14 @@ PHP_METHOD(PDO, prepare)
525
524
zend_zval_value_name (value ));
526
525
RETURN_THROWS ();
527
526
}
528
- ZVAL_COPY_VALUE (& ctor_args , item );
529
- } else {
530
- ZVAL_UNDEF (& ctor_args );
527
+ ctor_args = Z_ARRVAL_P (item );
531
528
}
532
529
} else {
533
530
dbstmt_ce = dbh -> def_stmt_ce ;
534
- ZVAL_COPY_VALUE ( & ctor_args , & dbh -> def_stmt_ctor_args ) ;
531
+ ctor_args = dbh -> def_stmt_ctor_args ;
535
532
}
536
533
537
- if (!pdo_stmt_instantiate (dbh , return_value , dbstmt_ce , & ctor_args )) {
534
+ if (!pdo_stmt_instantiate (dbh , return_value , dbstmt_ce , ctor_args )) {
538
535
RETURN_THROWS ();
539
536
}
540
537
stmt = Z_PDO_STMT_P (return_value );
@@ -549,11 +546,7 @@ PHP_METHOD(PDO, prepare)
549
546
ZVAL_UNDEF (& stmt -> lazy_object_ref );
550
547
551
548
if (dbh -> methods -> preparer (dbh , statement , stmt , options )) {
552
- if (Z_TYPE (ctor_args ) == IS_ARRAY ) {
553
- pdo_stmt_construct (stmt , return_value , dbstmt_ce , Z_ARRVAL (ctor_args ));
554
- } else {
555
- pdo_stmt_construct (stmt , return_value , dbstmt_ce , /* ctor_args */ NULL );
556
- }
549
+ pdo_stmt_construct (stmt , return_value , dbstmt_ce , ctor_args );
557
550
return ;
558
551
}
559
552
@@ -817,17 +810,19 @@ static bool pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) /
817
810
return false;
818
811
}
819
812
dbh -> def_stmt_ce = pce ;
820
- if (! Z_ISUNDEF ( dbh -> def_stmt_ctor_args ) ) {
821
- zval_ptr_dtor ( & dbh -> def_stmt_ctor_args );
822
- ZVAL_UNDEF ( & dbh -> def_stmt_ctor_args ) ;
813
+ if (dbh -> def_stmt_ctor_args ) {
814
+ zend_array_release ( dbh -> def_stmt_ctor_args );
815
+ dbh -> def_stmt_ctor_args = NULL ;
823
816
}
824
817
if ((item = zend_hash_index_find (Z_ARRVAL_P (value ), 1 )) != NULL ) {
825
818
if (Z_TYPE_P (item ) != IS_ARRAY ) {
826
819
zend_type_error ("PDO::ATTR_STATEMENT_CLASS constructor_args must be of type ?array, %s given" ,
827
820
zend_zval_value_name (value ));
828
821
return false;
829
822
}
830
- ZVAL_COPY (& dbh -> def_stmt_ctor_args , item );
823
+ dbh -> def_stmt_ctor_args = Z_ARRVAL_P (item );
824
+ /* Increase refcount */
825
+ GC_TRY_ADDREF (dbh -> def_stmt_ctor_args );
831
826
}
832
827
return true;
833
828
}
@@ -906,9 +901,10 @@ PHP_METHOD(PDO, getAttribute)
906
901
case PDO_ATTR_STATEMENT_CLASS :
907
902
array_init (return_value );
908
903
add_next_index_str (return_value , zend_string_copy (dbh -> def_stmt_ce -> name ));
909
- if (!Z_ISUNDEF (dbh -> def_stmt_ctor_args )) {
910
- Z_TRY_ADDREF (dbh -> def_stmt_ctor_args );
911
- add_next_index_zval (return_value , & dbh -> def_stmt_ctor_args );
904
+ if (dbh -> def_stmt_ctor_args ) {
905
+ /* Increment refcount of constructor arguments */
906
+ GC_TRY_ADDREF (dbh -> def_stmt_ctor_args );
907
+ add_next_index_array (return_value , dbh -> def_stmt_ctor_args );
912
908
}
913
909
return ;
914
910
case PDO_ATTR_DEFAULT_FETCH_MODE :
@@ -1093,7 +1089,7 @@ PHP_METHOD(PDO, query)
1093
1089
1094
1090
PDO_DBH_CLEAR_ERR ();
1095
1091
1096
- if (!pdo_stmt_instantiate (dbh , return_value , dbh -> def_stmt_ce , & dbh -> def_stmt_ctor_args )) {
1092
+ if (!pdo_stmt_instantiate (dbh , return_value , dbh -> def_stmt_ce , dbh -> def_stmt_ctor_args )) {
1097
1093
RETURN_THROWS ();
1098
1094
}
1099
1095
stmt = Z_PDO_STMT_P (return_value );
@@ -1122,11 +1118,7 @@ PHP_METHOD(PDO, query)
1122
1118
stmt -> executed = 1 ;
1123
1119
}
1124
1120
if (ret ) {
1125
- if (Z_TYPE (dbh -> def_stmt_ctor_args ) == IS_ARRAY ) {
1126
- pdo_stmt_construct (stmt , return_value , dbh -> def_stmt_ce , Z_ARRVAL (dbh -> def_stmt_ctor_args ));
1127
- } else {
1128
- pdo_stmt_construct (stmt , return_value , dbh -> def_stmt_ce , /* ctor_args */ NULL );
1129
- }
1121
+ pdo_stmt_construct (stmt , return_value , dbh -> def_stmt_ce , dbh -> def_stmt_ctor_args );
1130
1122
return ;
1131
1123
}
1132
1124
}
@@ -1320,7 +1312,9 @@ static HashTable *dbh_get_gc(zend_object *object, zval **gc_data, int *gc_count)
1320
1312
{
1321
1313
pdo_dbh_t * dbh = php_pdo_dbh_fetch_inner (object );
1322
1314
zend_get_gc_buffer * gc_buffer = zend_get_gc_buffer_create ();
1323
- zend_get_gc_buffer_add_zval (gc_buffer , & dbh -> def_stmt_ctor_args );
1315
+ if (dbh -> def_stmt_ctor_args ) {
1316
+ zend_get_gc_buffer_add_ht (gc_buffer , dbh -> def_stmt_ctor_args );
1317
+ }
1324
1318
if (dbh -> methods && dbh -> methods -> get_gc ) {
1325
1319
dbh -> methods -> get_gc (dbh , gc_buffer );
1326
1320
}
@@ -1382,9 +1376,7 @@ static void dbh_free(pdo_dbh_t *dbh, bool free_persistent)
1382
1376
pefree ((char * )dbh -> persistent_id , dbh -> is_persistent );
1383
1377
}
1384
1378
1385
- if (!Z_ISUNDEF (dbh -> def_stmt_ctor_args )) {
1386
- zval_ptr_dtor (& dbh -> def_stmt_ctor_args );
1387
- }
1379
+ /* The GC, via dbh_get_gc(), will free dbh->def_stmt_ctor_args() */
1388
1380
1389
1381
for (i = 0 ; i < PDO_DBH_DRIVER_METHOD_KIND__MAX ; i ++ ) {
1390
1382
if (dbh -> cls_methods [i ]) {
@@ -1413,6 +1405,7 @@ static void pdo_dbh_free_storage(zend_object *std)
1413
1405
if (dbh -> is_persistent && dbh -> methods && dbh -> methods -> persistent_shutdown ) {
1414
1406
dbh -> methods -> persistent_shutdown (dbh );
1415
1407
}
1408
+
1416
1409
zend_object_std_dtor (std );
1417
1410
dbh_free (dbh , 0 );
1418
1411
}
@@ -1427,6 +1420,7 @@ zend_object *pdo_dbh_new(zend_class_entry *ce)
1427
1420
rebuild_object_properties (& dbh -> std );
1428
1421
dbh -> inner = ecalloc (1 , sizeof (pdo_dbh_t ));
1429
1422
dbh -> inner -> def_stmt_ce = pdo_dbstmt_ce ;
1423
+ dbh -> inner -> def_stmt_ctor_args = NULL ;
1430
1424
1431
1425
return & dbh -> std ;
1432
1426
}
0 commit comments