@@ -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 , HashTable const * 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,18 @@ 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
+ /* Separate array */
824
+ dbh -> def_stmt_ctor_args = zend_array_dup (Z_ARRVAL_P (item ));
831
825
}
832
826
return true;
833
827
}
@@ -906,9 +900,10 @@ PHP_METHOD(PDO, getAttribute)
906
900
case PDO_ATTR_STATEMENT_CLASS :
907
901
array_init (return_value );
908
902
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 );
903
+ if (dbh -> def_stmt_ctor_args ) {
904
+ /* Increment refcount of constructor arguments */
905
+ zend_gc_addref (& dbh -> def_stmt_ctor_args -> gc );
906
+ add_next_index_array (return_value , dbh -> def_stmt_ctor_args );
912
907
}
913
908
return ;
914
909
case PDO_ATTR_DEFAULT_FETCH_MODE :
@@ -1093,7 +1088,7 @@ PHP_METHOD(PDO, query)
1093
1088
1094
1089
PDO_DBH_CLEAR_ERR ();
1095
1090
1096
- if (!pdo_stmt_instantiate (dbh , return_value , dbh -> def_stmt_ce , & dbh -> def_stmt_ctor_args )) {
1091
+ if (!pdo_stmt_instantiate (dbh , return_value , dbh -> def_stmt_ce , dbh -> def_stmt_ctor_args )) {
1097
1092
RETURN_THROWS ();
1098
1093
}
1099
1094
stmt = Z_PDO_STMT_P (return_value );
@@ -1122,11 +1117,7 @@ PHP_METHOD(PDO, query)
1122
1117
stmt -> executed = 1 ;
1123
1118
}
1124
1119
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
- }
1120
+ pdo_stmt_construct (stmt , return_value , dbh -> def_stmt_ce , dbh -> def_stmt_ctor_args );
1130
1121
return ;
1131
1122
}
1132
1123
}
@@ -1320,7 +1311,9 @@ static HashTable *dbh_get_gc(zend_object *object, zval **gc_data, int *gc_count)
1320
1311
{
1321
1312
pdo_dbh_t * dbh = php_pdo_dbh_fetch_inner (object );
1322
1313
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 );
1314
+ if (dbh -> def_stmt_ctor_args ) {
1315
+ zend_get_gc_buffer_add_ht (gc_buffer , dbh -> def_stmt_ctor_args );
1316
+ }
1324
1317
if (dbh -> methods && dbh -> methods -> get_gc ) {
1325
1318
dbh -> methods -> get_gc (dbh , gc_buffer );
1326
1319
}
@@ -1382,10 +1375,6 @@ static void dbh_free(pdo_dbh_t *dbh, bool free_persistent)
1382
1375
pefree ((char * )dbh -> persistent_id , dbh -> is_persistent );
1383
1376
}
1384
1377
1385
- if (!Z_ISUNDEF (dbh -> def_stmt_ctor_args )) {
1386
- zval_ptr_dtor (& dbh -> def_stmt_ctor_args );
1387
- }
1388
-
1389
1378
for (i = 0 ; i < PDO_DBH_DRIVER_METHOD_KIND__MAX ; i ++ ) {
1390
1379
if (dbh -> cls_methods [i ]) {
1391
1380
zend_hash_destroy (dbh -> cls_methods [i ]);
@@ -1413,6 +1402,13 @@ static void pdo_dbh_free_storage(zend_object *std)
1413
1402
if (dbh -> is_persistent && dbh -> methods && dbh -> methods -> persistent_shutdown ) {
1414
1403
dbh -> methods -> persistent_shutdown (dbh );
1415
1404
}
1405
+
1406
+ /* TODO ? Freeing of constructor arguments is handles via GC */
1407
+ if (dbh -> def_stmt_ctor_args ) {
1408
+ zend_array_release (dbh -> def_stmt_ctor_args );
1409
+ //zend_hash_destroy(dbh->def_stmt_ctor_args);
1410
+ }
1411
+
1416
1412
zend_object_std_dtor (std );
1417
1413
dbh_free (dbh , 0 );
1418
1414
}
@@ -1427,6 +1423,7 @@ zend_object *pdo_dbh_new(zend_class_entry *ce)
1427
1423
rebuild_object_properties (& dbh -> std );
1428
1424
dbh -> inner = ecalloc (1 , sizeof (pdo_dbh_t ));
1429
1425
dbh -> inner -> def_stmt_ce = pdo_dbstmt_ce ;
1426
+ dbh -> inner -> def_stmt_ctor_args = NULL ;
1430
1427
1431
1428
return & dbh -> std ;
1432
1429
}
0 commit comments