@@ -425,12 +425,10 @@ PHP_METHOD(PDO, __construct)
425
425
static zval * pdo_stmt_instantiate (pdo_dbh_t * dbh , zval * object , zend_class_entry * dbstmt_ce , zval * ctor_args ) /* {{{ */
426
426
{
427
427
if (!Z_ISUNDEF_P (ctor_args )) {
428
- if (Z_TYPE_P (ctor_args ) != IS_ARRAY ) {
429
- pdo_raise_impl_error (dbh , NULL , "HY000" , "constructor arguments must be passed as an array" );
430
- return NULL ;
431
- }
428
+ /* This implies an error within PDO if this does not hold */
429
+ ZEND_ASSERT (Z_TYPE_P (ctor_args ) == IS_ARRAY );
432
430
if (!dbstmt_ce -> constructor ) {
433
- pdo_raise_impl_error ( dbh , NULL , "HY000" , "user -supplied statement does not accept constructor arguments" );
431
+ zend_throw_error ( NULL , "User -supplied statement does not accept constructor arguments" );
434
432
return NULL ;
435
433
}
436
434
}
@@ -487,7 +485,7 @@ PHP_METHOD(PDO, prepare)
487
485
pdo_stmt_t * stmt ;
488
486
char * statement ;
489
487
size_t statement_len ;
490
- zval * options = NULL , * opt , * item , ctor_args ;
488
+ zval * options = NULL , * value , * item , ctor_args ;
491
489
zend_class_entry * dbstmt_ce , * pce ;
492
490
pdo_dbh_object_t * dbh_obj = Z_PDO_OBJECT_P (ZEND_THIS );
493
491
pdo_dbh_t * dbh = dbh_obj -> inner ;
@@ -498,42 +496,44 @@ PHP_METHOD(PDO, prepare)
498
496
Z_PARAM_ARRAY (options )
499
497
ZEND_PARSE_PARAMETERS_END ();
500
498
501
- PDO_DBH_CLEAR_ERR ();
502
499
PDO_CONSTRUCT_CHECK ;
503
500
504
- if (ZEND_NUM_ARGS () > 1 && (opt = zend_hash_index_find (Z_ARRVAL_P (options ), PDO_ATTR_STATEMENT_CLASS )) != NULL ) {
505
- if (Z_TYPE_P (opt ) != IS_ARRAY || (item = zend_hash_index_find (Z_ARRVAL_P (opt ), 0 )) == NULL
506
- || Z_TYPE_P (item ) != IS_STRING
507
- || (pce = zend_lookup_class (Z_STR_P (item ))) == NULL
508
- ) {
509
- pdo_raise_impl_error (dbh , NULL , "HY000" ,
510
- "PDO::ATTR_STATEMENT_CLASS requires format array(classname, array(ctor_args)); "
511
- "the classname must be a string specifying an existing class"
512
- );
513
- PDO_HANDLE_DBH_ERR ();
514
- RETURN_FALSE ;
501
+ if (statement_len == 0 ) {
502
+ zend_argument_value_error (1 , "cannot be empty" );
503
+ RETURN_THROWS ();
504
+ }
505
+
506
+ PDO_DBH_CLEAR_ERR ();
507
+
508
+ if (options && (value = zend_hash_index_find (Z_ARRVAL_P (options ), PDO_ATTR_STATEMENT_CLASS )) != NULL ) {
509
+ if (Z_TYPE_P (value ) != IS_ARRAY ) {
510
+ zend_type_error ("PDO::ATTR_STATEMENT_CLASS value must be of type array, %s given" ,
511
+ zend_zval_type_name (value ));
512
+ RETURN_THROWS ();
513
+ }
514
+ if ((item = zend_hash_index_find (Z_ARRVAL_P (value ), 0 )) == NULL ) {
515
+ zend_value_error ("PDO::ATTR_STATEMENT_CLASS value must be an array with the format "
516
+ "array(classname, array(ctor_args))" );
517
+ RETURN_THROWS ();
518
+ }
519
+ if (Z_TYPE_P (item ) != IS_STRING || (pce = zend_lookup_class (Z_STR_P (item ))) == NULL ) {
520
+ zend_type_error ("PDO::ATTR_STATEMENT_CLASS class must be a valid class" );
521
+ RETURN_THROWS ();
515
522
}
516
523
dbstmt_ce = pce ;
517
524
if (!instanceof_function (dbstmt_ce , pdo_dbstmt_ce )) {
518
- pdo_raise_impl_error (dbh , NULL , "HY000" ,
519
- "user-supplied statement class must be derived from PDOStatement" );
520
- PDO_HANDLE_DBH_ERR ();
521
- RETURN_FALSE ;
525
+ zend_type_error ("PDO::ATTR_STATEMENT_CLASS class must be derived from PDOStatement" );
526
+ RETURN_THROWS ();
522
527
}
523
528
if (dbstmt_ce -> constructor && !(dbstmt_ce -> constructor -> common .fn_flags & (ZEND_ACC_PRIVATE |ZEND_ACC_PROTECTED ))) {
524
- pdo_raise_impl_error (dbh , NULL , "HY000" ,
525
- "user-supplied statement class cannot have a public constructor" );
526
- PDO_HANDLE_DBH_ERR ();
527
- RETURN_FALSE ;
529
+ zend_type_error ("User-supplied statement class cannot have a public constructor" );
530
+ RETURN_THROWS ();
528
531
}
529
- if ((item = zend_hash_index_find (Z_ARRVAL_P (opt ), 1 )) != NULL ) {
532
+ if ((item = zend_hash_index_find (Z_ARRVAL_P (value ), 1 )) != NULL ) {
530
533
if (Z_TYPE_P (item ) != IS_ARRAY ) {
531
- pdo_raise_impl_error (dbh , NULL , "HY000" ,
532
- "PDO::ATTR_STATEMENT_CLASS requires format array(classname, ctor_args); "
533
- "ctor_args must be an array"
534
- );
535
- PDO_HANDLE_DBH_ERR ();
536
- RETURN_FALSE ;
534
+ zend_type_error ("PDO::ATTR_STATEMENT_CLASS ctor_args must be of type ?array, %s given" ,
535
+ zend_zval_type_name (value ));
536
+ RETURN_THROWS ();
537
537
}
538
538
ZVAL_COPY_VALUE (& ctor_args , item );
539
539
} else {
@@ -544,11 +544,10 @@ PHP_METHOD(PDO, prepare)
544
544
ZVAL_COPY_VALUE (& ctor_args , & dbh -> def_stmt_ctor_args );
545
545
}
546
546
547
+ /* Need to check if pdo_stmt_instantiate() throws an exception unconditionally to see if can change the RETURN_FALSE; */
547
548
if (!pdo_stmt_instantiate (dbh , return_value , dbstmt_ce , & ctor_args )) {
548
549
if (EXPECTED (!EG (exception ))) {
549
- pdo_raise_impl_error (dbh , NULL , "HY000" ,
550
- "failed to instantiate user-supplied statement class"
551
- );
550
+ zend_throw_error (NULL , "Cannot instantiate user-supplied statement class" );
552
551
}
553
552
PDO_HANDLE_DBH_ERR ();
554
553
RETURN_FALSE ;
@@ -679,10 +678,10 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) /*
679
678
{
680
679
zend_long lval ;
681
680
681
+ /* TODO: Make distinction between numeric and non-numeric strings */
682
682
#define PDO_LONG_PARAM_CHECK \
683
683
if (Z_TYPE_P(value) != IS_LONG && Z_TYPE_P(value) != IS_STRING && Z_TYPE_P(value) != IS_FALSE && Z_TYPE_P(value) != IS_TRUE) { \
684
- pdo_raise_impl_error(dbh, NULL, "HY000", "attribute value must be an integer"); \
685
- PDO_HANDLE_DBH_ERR(); \
684
+ zend_type_error("Attribute value must be of type int for selected attribute, %s given", zend_zval_type_name(value)); \
686
685
return FAILURE; \
687
686
} \
688
687
@@ -697,8 +696,7 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) /*
697
696
dbh -> error_mode = lval ;
698
697
return SUCCESS ;
699
698
default :
700
- pdo_raise_impl_error (dbh , NULL , "HY000" , "invalid error mode" );
701
- PDO_HANDLE_DBH_ERR ();
699
+ zend_value_error ("Error mode must be one of the PDO::ERRMODE_* constants" );
702
700
return FAILURE ;
703
701
}
704
702
return FAILURE ;
@@ -713,8 +711,7 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) /*
713
711
dbh -> desired_case = lval ;
714
712
return SUCCESS ;
715
713
default :
716
- pdo_raise_impl_error (dbh , NULL , "HY000" , "invalid case folding mode" );
717
- PDO_HANDLE_DBH_ERR ();
714
+ zend_value_error ("Case folding mode must be one of the PDO::CASE_* constants" );
718
715
return FAILURE ;
719
716
}
720
717
return FAILURE ;
@@ -729,7 +726,7 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) /*
729
726
zval * tmp ;
730
727
if ((tmp = zend_hash_index_find (Z_ARRVAL_P (value ), 0 )) != NULL && Z_TYPE_P (tmp ) == IS_LONG ) {
731
728
if (Z_LVAL_P (tmp ) == PDO_FETCH_INTO || Z_LVAL_P (tmp ) == PDO_FETCH_CLASS ) {
732
- pdo_raise_impl_error ( dbh , NULL , "HY000" , " FETCH_INTO and FETCH_CLASS are not yet supported as default fetch modes " );
729
+ zend_value_error ( "PDO:: FETCH_INTO and PDO:: FETCH_CLASS cannot be set as the default fetch mode " );
733
730
return FAILURE ;
734
731
}
735
732
}
@@ -738,7 +735,7 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) /*
738
735
}
739
736
lval = zval_get_long (value );
740
737
if (lval == PDO_FETCH_USE_DEFAULT ) {
741
- pdo_raise_impl_error ( dbh , NULL , "HY000" , "invalid fetch mode type " );
738
+ zend_value_error ( "Fetch mode must be a bitmask of PDO::FETCH_* constants " );
742
739
return FAILURE ;
743
740
}
744
741
dbh -> default_fetch_type = lval ;
@@ -761,28 +758,26 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) /*
761
758
PDO_HANDLE_DBH_ERR ();
762
759
return FAILURE ;
763
760
}
764
- if (Z_TYPE_P (value ) != IS_ARRAY
765
- || (item = zend_hash_index_find (Z_ARRVAL_P (value ), 0 )) == NULL
766
- || Z_TYPE_P (item ) != IS_STRING
767
- || (pce = zend_lookup_class (Z_STR_P (item ))) == NULL
768
- ) {
769
- pdo_raise_impl_error (dbh , NULL , "HY000" ,
770
- "PDO::ATTR_STATEMENT_CLASS requires format array(classname, array(ctor_args)); "
771
- "the classname must be a string specifying an existing class"
772
- );
773
- PDO_HANDLE_DBH_ERR ();
761
+ if (Z_TYPE_P (value ) != IS_ARRAY ) {
762
+ zend_type_error ("PDO::ATTR_STATEMENT_CLASS value must be of type array, %s given" ,
763
+ zend_zval_type_name (value ));
764
+ return FAILURE ;
765
+ }
766
+ if ((item = zend_hash_index_find (Z_ARRVAL_P (value ), 0 )) == NULL ) {
767
+ zend_value_error ("PDO::ATTR_STATEMENT_CLASS value must be an array with the format "
768
+ "array(classname, array(ctor_args))" );
769
+ return FAILURE ;
770
+ }
771
+ if (Z_TYPE_P (item ) != IS_STRING || (pce = zend_lookup_class (Z_STR_P (item ))) == NULL ) {
772
+ zend_type_error ("PDO::ATTR_STATEMENT_CLASS class must be a valid class" );
774
773
return FAILURE ;
775
774
}
776
775
if (!instanceof_function (pce , pdo_dbstmt_ce )) {
777
- pdo_raise_impl_error (dbh , NULL , "HY000" ,
778
- "user-supplied statement class must be derived from PDOStatement" );
779
- PDO_HANDLE_DBH_ERR ();
776
+ zend_type_error ("PDO::ATTR_STATEMENT_CLASS class must be derived from PDOStatement" );
780
777
return FAILURE ;
781
778
}
782
779
if (pce -> constructor && !(pce -> constructor -> common .fn_flags & (ZEND_ACC_PRIVATE |ZEND_ACC_PROTECTED ))) {
783
- pdo_raise_impl_error (dbh , NULL , "HY000" ,
784
- "user-supplied statement class cannot have a public constructor" );
785
- PDO_HANDLE_DBH_ERR ();
780
+ zend_type_error ("User-supplied statement class cannot have a public constructor" );
786
781
return FAILURE ;
787
782
}
788
783
dbh -> def_stmt_ce = pce ;
@@ -792,11 +787,8 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) /*
792
787
}
793
788
if ((item = zend_hash_index_find (Z_ARRVAL_P (value ), 1 )) != NULL ) {
794
789
if (Z_TYPE_P (item ) != IS_ARRAY ) {
795
- pdo_raise_impl_error (dbh , NULL , "HY000" ,
796
- "PDO::ATTR_STATEMENT_CLASS requires format array(classname, array(ctor_args)); "
797
- "ctor_args must be an array"
798
- );
799
- PDO_HANDLE_DBH_ERR ();
790
+ zend_type_error ("PDO::ATTR_STATEMENT_CLASS ctor_args must be of type ?array, %s given" ,
791
+ zend_zval_type_name (value ));
800
792
return FAILURE ;
801
793
}
802
794
ZVAL_COPY (& dbh -> def_stmt_ctor_args , item );
@@ -927,10 +919,11 @@ PHP_METHOD(PDO, exec)
927
919
Z_PARAM_STRING (statement , statement_len )
928
920
ZEND_PARSE_PARAMETERS_END ();
929
921
930
- if (! statement_len ) {
931
- pdo_raise_impl_error ( dbh , NULL , "HY000" , "trying to execute an empty query " );
932
- RETURN_FALSE ;
922
+ if (statement_len == 0 ) {
923
+ zend_argument_value_error ( 1 , "cannot be empty" );
924
+ RETURN_THROWS () ;
933
925
}
926
+
934
927
PDO_DBH_CLEAR_ERR ();
935
928
PDO_CONSTRUCT_CHECK ;
936
929
ret = dbh -> methods -> doer (dbh , statement , statement_len );
@@ -955,8 +948,10 @@ PHP_METHOD(PDO, lastInsertId)
955
948
Z_PARAM_STRING_OR_NULL (name , namelen )
956
949
ZEND_PARSE_PARAMETERS_END ();
957
950
958
- PDO_DBH_CLEAR_ERR ();
959
951
PDO_CONSTRUCT_CHECK ;
952
+
953
+ PDO_DBH_CLEAR_ERR ();
954
+
960
955
if (!dbh -> methods -> last_id ) {
961
956
pdo_raise_impl_error (dbh , NULL , "IM001" , "driver does not support lastInsertId()" );
962
957
RETURN_FALSE ;
@@ -1060,13 +1055,20 @@ PHP_METHOD(PDO, query)
1060
1055
pdo_dbh_object_t * dbh_obj = Z_PDO_OBJECT_P (ZEND_THIS );
1061
1056
pdo_dbh_t * dbh = dbh_obj -> inner ;
1062
1057
1063
- if (FAILURE == zend_parse_parameters (ZEND_NUM_ARGS (), "s|l!*" , & statement , & statement_len , & fetch_mode , & fetch_mode_is_null , & args , & num_args )) {
1058
+ if (FAILURE == zend_parse_parameters (ZEND_NUM_ARGS (), "s|l!*" , & statement , & statement_len ,
1059
+ & fetch_mode , & fetch_mode_is_null , & args , & num_args )) {
1064
1060
RETURN_THROWS ();
1065
1061
}
1066
1062
1067
- PDO_DBH_CLEAR_ERR ();
1068
1063
PDO_CONSTRUCT_CHECK ;
1069
1064
1065
+ if (statement_len == 0 ) {
1066
+ zend_argument_value_error (1 , "cannot be empty" );
1067
+ RETURN_THROWS ();
1068
+ }
1069
+
1070
+ PDO_DBH_CLEAR_ERR ();
1071
+
1070
1072
if (!pdo_stmt_instantiate (dbh , return_value , dbh -> def_stmt_ce , & dbh -> def_stmt_ctor_args )) {
1071
1073
if (EXPECTED (!EG (exception ))) {
1072
1074
pdo_raise_impl_error (dbh , NULL , "HY000" , "failed to instantiate user supplied statement class" );
@@ -1090,8 +1092,7 @@ PHP_METHOD(PDO, query)
1090
1092
1091
1093
if (dbh -> methods -> preparer (dbh , statement , statement_len , stmt , NULL )) {
1092
1094
PDO_STMT_CLEAR_ERR ();
1093
- if (fetch_mode_is_null || SUCCESS == pdo_stmt_setup_fetch_mode (stmt , fetch_mode , args , num_args )) {
1094
-
1095
+ if (fetch_mode_is_null || pdo_stmt_setup_fetch_mode (stmt , fetch_mode , 2 , args , num_args )) {
1095
1096
/* now execute the statement */
1096
1097
PDO_STMT_CLEAR_ERR ();
1097
1098
if (stmt -> methods -> executer (stmt )) {
@@ -1139,8 +1140,9 @@ PHP_METHOD(PDO, quote)
1139
1140
Z_PARAM_LONG (paramtype )
1140
1141
ZEND_PARSE_PARAMETERS_END ();
1141
1142
1142
- PDO_DBH_CLEAR_ERR ();
1143
1143
PDO_CONSTRUCT_CHECK ;
1144
+
1145
+ PDO_DBH_CLEAR_ERR ();
1144
1146
if (!dbh -> methods -> quoter ) {
1145
1147
pdo_raise_impl_error (dbh , NULL , "IM001" , "driver does not support quoting" );
1146
1148
RETURN_FALSE ;
0 commit comments