@@ -1736,11 +1736,22 @@ PHP_METHOD(PDOStatement, getColumnMeta)
1736
1736
1737
1737
/* {{{ Changes the default fetch mode for subsequent fetches (params have different meaning for different fetch modes) */
1738
1738
1739
- bool pdo_stmt_setup_fetch_mode (pdo_stmt_t * stmt , uint32_t total_num_args , zend_long fetch_mode ,
1740
- uint32_t mode_arg_num , zval * arg1 , uint32_t arg1_arg_num , HashTable * constructor_args ,
1741
- uint32_t constructor_arg_num )
1739
+ bool pdo_stmt_setup_fetch_mode (pdo_stmt_t * stmt , zend_long mode , uint32_t mode_arg_num ,
1740
+ zval * args , uint32_t variadic_num_args )
1742
1741
{
1743
1742
int flags = 0 ;
1743
+ uint32_t arg1_arg_num = mode_arg_num + 1 ;
1744
+ uint32_t constructor_arg_num = mode_arg_num + 2 ;
1745
+ uint32_t total_num_args = mode_arg_num + variadic_num_args ;
1746
+ zval arg1 , constructor_args ;
1747
+
1748
+ /* Assign variadic params to dedicated ones */
1749
+ if (variadic_num_args >= 1 ) {
1750
+ arg1 = args [0 ];
1751
+ if (variadic_num_args >= 1 ) {
1752
+ constructor_args = args [1 ];
1753
+ }
1754
+ }
1744
1755
1745
1756
switch (stmt -> default_fetch_type ) {
1746
1757
case PDO_FETCH_INTO :
@@ -1755,13 +1766,13 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, uint32_t total_num_args, zend_l
1755
1766
1756
1767
stmt -> default_fetch_type = PDO_FETCH_BOTH ;
1757
1768
1758
- flags = fetch_mode & PDO_FETCH_FLAGS ;
1769
+ flags = mode & PDO_FETCH_FLAGS ;
1759
1770
1760
- if (!pdo_stmt_verify_mode (stmt , fetch_mode , mode_arg_num , false)) {
1771
+ if (!pdo_stmt_verify_mode (stmt , mode , mode_arg_num , false)) {
1761
1772
return false;
1762
1773
}
1763
1774
1764
- switch (fetch_mode & ~PDO_FETCH_FLAGS ) {
1775
+ switch (mode & ~PDO_FETCH_FLAGS ) {
1765
1776
case PDO_FETCH_USE_DEFAULT :
1766
1777
case PDO_FETCH_LAZY :
1767
1778
case PDO_FETCH_ASSOC :
@@ -1773,7 +1784,7 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, uint32_t total_num_args, zend_l
1773
1784
case PDO_FETCH_KEY_PAIR :
1774
1785
if (total_num_args != mode_arg_num ) {
1775
1786
zend_string * func = get_active_function_or_method_name ();
1776
- zend_argument_count_error ("%s() expects exactly %d argument for the fetch mode provided, %d given" ,
1787
+ zend_argument_count_error ("%s() expects exactly %d arguments for the fetch mode provided, %d given" ,
1777
1788
ZSTR_VAL (func ), mode_arg_num , total_num_args );
1778
1789
zend_string_release (func );
1779
1790
return false;
@@ -1783,57 +1794,68 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, uint32_t total_num_args, zend_l
1783
1794
case PDO_FETCH_COLUMN :
1784
1795
if (total_num_args != arg1_arg_num ) {
1785
1796
zend_string * func = get_active_function_or_method_name ();
1786
- zend_argument_count_error ("%s() expects exactly %d argument for the fetch mode provided, %d given" ,
1797
+ zend_argument_count_error ("%s() expects exactly %d arguments for the fetch mode provided, %d given" ,
1787
1798
ZSTR_VAL (func ), arg1_arg_num , total_num_args );
1788
1799
zend_string_release (func );
1789
1800
return false;
1790
1801
}
1791
- if (Z_TYPE_P (arg1 ) != IS_LONG ) {
1792
- zend_argument_type_error (arg1_arg_num , "must be int, %s given" , zend_zval_type_name (arg1 ));
1802
+ /* arg1 is initialized at the start */
1803
+ if (Z_TYPE (arg1 ) != IS_LONG ) {
1804
+ zend_argument_type_error (arg1_arg_num , "must be int, %s given" , zend_zval_type_name (& arg1 ));
1793
1805
return false;
1794
1806
}
1795
- if (Z_LVAL_P (arg1 ) < 0 ) {
1807
+ if (Z_LVAL (arg1 ) < 0 ) {
1796
1808
zend_argument_value_error (arg1_arg_num , "must be greater than or equal to 0" );
1797
1809
return false;
1798
1810
}
1799
- stmt -> fetch .column = Z_LVAL_P (arg1 );
1811
+ stmt -> fetch .column = Z_LVAL (arg1 );
1800
1812
break ;
1801
1813
1802
1814
case PDO_FETCH_CLASS :
1803
1815
/* Undef constructor arguments */
1804
1816
ZVAL_UNDEF (& stmt -> fetch .cls .ctor_args );
1805
1817
/* Gets its class name from 1st column */
1806
1818
if ((flags & PDO_FETCH_CLASSTYPE ) == PDO_FETCH_CLASSTYPE ) {
1807
- if (arg1 || constructor_args ) {
1819
+ if (variadic_num_args != 0 ) {
1808
1820
zend_string * func = get_active_function_or_method_name ();
1809
- zend_argument_count_error ("%s() expects exactly %d argument for the fetch mode provided, %d given" ,
1821
+ zend_argument_count_error ("%s() expects exactly %d arguments for the fetch mode provided, %d given" ,
1810
1822
ZSTR_VAL (func ), mode_arg_num , total_num_args );
1811
1823
zend_string_release (func );
1812
1824
return false;
1813
1825
}
1814
1826
stmt -> fetch .cls .ce = NULL ;
1815
1827
} else {
1816
1828
zend_class_entry * cep ;
1817
-
1818
- if (!arg1 || total_num_args > constructor_arg_num ) {
1829
+ if (variadic_num_args == 0 ) {
1830
+ zend_string * func = get_active_function_or_method_name ();
1831
+ zend_argument_count_error ("%s() expects at least %d arguments for the fetch mode provided, %d given" ,
1832
+ ZSTR_VAL (func ), arg1_arg_num , total_num_args );
1833
+ zend_string_release (func );
1834
+ return false;
1835
+ }
1836
+ /* constructor_arguments can be null/not passed */
1837
+ if (variadic_num_args > 2 ) {
1819
1838
zend_string * func = get_active_function_or_method_name ();
1820
- zend_argument_count_error ("%s() expects exactly %d argument for the fetch mode provided, %d given" ,
1839
+ zend_argument_count_error ("%s() expects at most %d arguments for the fetch mode provided, %d given" ,
1821
1840
ZSTR_VAL (func ), constructor_arg_num , total_num_args );
1822
1841
zend_string_release (func );
1823
1842
return false;
1824
1843
}
1825
- if (Z_TYPE_P (arg1 ) != IS_STRING ) {
1826
- zend_argument_type_error (arg1_arg_num , "must be string, %s given" , zend_zval_type_name (arg1 ));
1844
+ /* arg1 is initialized at the start */
1845
+ if (Z_TYPE (arg1 ) != IS_STRING ) {
1846
+ zend_argument_type_error (arg1_arg_num , "must be string, %s given" , zend_zval_type_name (& arg1 ));
1827
1847
return false;
1828
1848
}
1829
- cep = zend_lookup_class (Z_STR_P (arg1 ));
1849
+ cep = zend_lookup_class (Z_STR (arg1 ));
1830
1850
if (!cep ) {
1831
1851
zend_argument_type_error (arg1_arg_num , "must be a valid class" );
1832
1852
return false;
1833
1853
}
1834
1854
stmt -> fetch .cls .ce = cep ;
1835
- if (constructor_args && zend_hash_num_elements (constructor_args )) {
1836
- ZVAL_ARR (& stmt -> fetch .cls .ctor_args , zend_array_dup (constructor_args ));
1855
+
1856
+ /* constructor_args is initialized at the start if variadic_num_args == 2 */
1857
+ if (variadic_num_args == 2 && zend_hash_num_elements (Z_ARRVAL (constructor_args ))) {
1858
+ ZVAL_ARR (& stmt -> fetch .cls .ctor_args , zend_array_dup (Z_ARRVAL (constructor_args )));
1837
1859
}
1838
1860
}
1839
1861
@@ -1843,44 +1865,45 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, uint32_t total_num_args, zend_l
1843
1865
case PDO_FETCH_INTO :
1844
1866
if (total_num_args != arg1_arg_num ) {
1845
1867
zend_string * func = get_active_function_or_method_name ();
1846
- zend_argument_count_error ("%s() expects exactly %d argument for the fetch mode provided, %d given" ,
1868
+ zend_argument_count_error ("%s() expects exactly %d arguments for the fetch mode provided, %d given" ,
1847
1869
ZSTR_VAL (func ), arg1_arg_num , total_num_args );
1848
1870
zend_string_release (func );
1849
1871
return false;
1850
1872
}
1851
- if (Z_TYPE_P (arg1 ) != IS_OBJECT ) {
1852
- zend_argument_type_error (arg1_arg_num , "must be object, %s given" , zend_zval_type_name (arg1 ));
1873
+ /* arg1 is initialized at the start */
1874
+ if (Z_TYPE (arg1 ) != IS_OBJECT ) {
1875
+ zend_argument_type_error (arg1_arg_num , "must be object, %s given" , zend_zval_type_name (& arg1 ));
1853
1876
return false;
1854
1877
}
1855
1878
1856
- ZVAL_COPY (& stmt -> fetch .into , arg1 );
1879
+ ZVAL_COPY (& stmt -> fetch .into , & arg1 );
1857
1880
break ;
1858
1881
default :
1859
1882
zend_argument_value_error (mode_arg_num , "must be one of the PDO::FETCH_* constants" );
1860
1883
return false;
1861
1884
}
1862
1885
1863
- stmt -> default_fetch_type = fetch_mode ;
1886
+ stmt -> default_fetch_type = mode ;
1864
1887
1865
1888
return true;
1866
1889
}
1867
1890
1868
1891
PHP_METHOD (PDOStatement , setFetchMode )
1869
1892
{
1870
1893
zend_long fetch_mode ;
1871
- zval * arg1 = NULL ;
1872
- HashTable * constructor_args = NULL ;
1894
+ zval * args = NULL ;
1895
+ uint32_t num_args = 0 ;
1873
1896
1874
1897
/* Support null for constructor arguments for BC */
1875
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "l|z!h! " , & fetch_mode , & arg1 , & constructor_args ) == FAILURE ) {
1898
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "l* " , & fetch_mode , & args , & num_args ) == FAILURE ) {
1876
1899
RETURN_THROWS ();
1877
1900
}
1878
1901
1879
1902
PHP_STMT_GET_OBJ ;
1880
1903
1881
1904
do_fetch_opt_finish (stmt , 1 );
1882
1905
1883
- if (!pdo_stmt_setup_fetch_mode (stmt , ZEND_NUM_ARGS (), fetch_mode , 1 , arg1 , 2 , constructor_args , 3 )) {
1906
+ if (!pdo_stmt_setup_fetch_mode (stmt , fetch_mode , 1 , args , num_args )) {
1884
1907
RETURN_THROWS ();
1885
1908
}
1886
1909
0 commit comments