@@ -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