pdo_stmt_t *stmt;
char *statement;
size_t statement_len;
+ zend_long fetch_mode;
+ zval *args = NULL;
+ uint32_t num_args = 0;
pdo_dbh_object_t *dbh_obj = Z_PDO_OBJECT_P(ZEND_THIS);
pdo_dbh_t *dbh = dbh_obj->inner;
- /* Return a meaningful error when no parameters were passed */
- if (!ZEND_NUM_ARGS()) {
- zend_parse_parameters(0, "z|z", NULL, NULL);
- RETURN_THROWS();
- }
-
- if (FAILURE == zend_parse_parameters(1, "s", &statement,
- &statement_len)) {
+ if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "s|l*", &statement, &statement_len, &fetch_mode, &args, &num_args)) {
RETURN_THROWS();
}
if (dbh->methods->preparer(dbh, statement, statement_len, stmt, NULL)) {
PDO_STMT_CLEAR_ERR();
- if (ZEND_NUM_ARGS() == 1 || SUCCESS == pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAM_PASSTHRU, stmt, 1)) {
+ if (ZEND_NUM_ARGS() == 1 || SUCCESS == pdo_stmt_setup_fetch_mode(stmt, fetch_mode, args, num_args)) {
/* now execute the statement */
PDO_STMT_CLEAR_ERR();
public function prepare(string $statement, array $driver_options = []) {}
/** @return PDOStatement|false */
- public function query(string $statement) {}
+ public function query(string $statement, int $fetch_mode = UNKNOWN, ...$fetch_mode_args) {}
/** @return string|false */
public function quote(string $string, int $parameter_type = PDO::PARAM_STR) {}
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 38748c44d78c0173218bcb771b466d2a04bc87ad */
+ * Stub hash: c329bfda55244467a2cd62f9d5c5120ec3f24eef */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_PDO___construct, 0, 0, 1)
ZEND_ARG_TYPE_INFO(0, dsn, IS_STRING, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, driver_options, IS_ARRAY, 0, "[]")
ZEND_END_ARG_INFO()
-#define arginfo_class_PDO_query arginfo_class_PDO_exec
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_PDO_query, 0, 0, 1)
+ ZEND_ARG_TYPE_INFO(0, statement, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO(0, fetch_mode, IS_LONG, 0)
+ ZEND_ARG_VARIADIC_INFO(0, fetch_mode_args)
+ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_PDO_quote, 0, 0, 1)
ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0)
/* {{{ Changes the default fetch mode for subsequent fetches (params have different meaning for different fetch modes) */
-int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, int skip)
+int pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, zval *args, uint32_t num_args)
{
- zend_long mode = PDO_FETCH_BOTH;
- int flags = 0, argc = ZEND_NUM_ARGS() - skip;
- zval *args;
+ int flags = 0;
zend_class_entry *cep;
int retval;
stmt->default_fetch_type = PDO_FETCH_BOTH;
- if (argc == 0) {
- return SUCCESS;
- }
-
- args = safe_emalloc(ZEND_NUM_ARGS(), sizeof(zval), 0);
-
- retval = zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args);
-
- if (SUCCESS == retval) {
- if (Z_TYPE(args[skip]) != IS_LONG) {
- pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "mode must be an integer");
- retval = FAILURE;
- } else {
- mode = Z_LVAL(args[skip]);
- flags = mode & PDO_FETCH_FLAGS;
-
- retval = pdo_stmt_verify_mode(stmt, mode, 0);
- }
- }
+ flags = mode & PDO_FETCH_FLAGS;
+ retval = pdo_stmt_verify_mode(stmt, mode, 0);
if (FAILURE == retval) {
PDO_STMT_CLEAR_ERR();
- efree(args);
return FAILURE;
}
case PDO_FETCH_BOUND:
case PDO_FETCH_NAMED:
case PDO_FETCH_KEY_PAIR:
- if (argc != 1) {
+ if (num_args != 0) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "fetch mode doesn't allow any extra arguments");
} else {
retval = SUCCESS;
break;
case PDO_FETCH_COLUMN:
- if (argc != 2) {
+ if (num_args != 1) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "fetch mode requires the colno argument");
- } else if (Z_TYPE(args[skip+1]) != IS_LONG) {
+ } else if (Z_TYPE(args[0]) != IS_LONG) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "colno must be an integer");
} else {
- stmt->fetch.column = Z_LVAL(args[skip+1]);
+ stmt->fetch.column = Z_LVAL(args[0]);
retval = SUCCESS;
}
break;
case PDO_FETCH_CLASS:
/* Gets its class name from 1st column */
if ((flags & PDO_FETCH_CLASSTYPE) == PDO_FETCH_CLASSTYPE) {
- if (argc != 1) {
+ if (num_args != 0) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "fetch mode doesn't allow any extra arguments");
} else {
stmt->fetch.cls.ce = NULL;
retval = SUCCESS;
}
} else {
- if (argc < 2) {
+ if (num_args < 1) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "fetch mode requires the classname argument");
- } else if (argc > 3) {
+ } else if (num_args > 2) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "too many arguments");
- } else if (Z_TYPE(args[skip+1]) != IS_STRING) {
+ } else if (Z_TYPE(args[0]) != IS_STRING) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "classname must be a string");
} else {
- cep = zend_lookup_class(Z_STR(args[skip+1]));
+ cep = zend_lookup_class(Z_STR(args[0]));
if (cep) {
retval = SUCCESS;
stmt->fetch.cls.ce = cep;
php_error_docref(NULL, E_WARNING, "PHP might crash if you don't call $stmt->setFetchMode() to reset to defaults on this persistent statement. This will be fixed in a later release");
}
#endif
- if (argc == 3) {
- if (Z_TYPE(args[skip+2]) != IS_NULL && Z_TYPE(args[skip+2]) != IS_ARRAY) {
+ if (num_args == 2) {
+ if (Z_TYPE(args[1]) != IS_NULL && Z_TYPE(args[1]) != IS_ARRAY) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "ctor_args must be either NULL or an array");
retval = FAILURE;
- } else if (Z_TYPE(args[skip+2]) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL(args[skip+2]))) {
- ZVAL_ARR(&stmt->fetch.cls.ctor_args, zend_array_dup(Z_ARRVAL(args[skip+2])));
+ } else if (Z_TYPE(args[1]) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL(args[1]))) {
+ ZVAL_ARR(&stmt->fetch.cls.ctor_args, zend_array_dup(Z_ARRVAL(args[1])));
}
}
break;
case PDO_FETCH_INTO:
- if (argc != 2) {
+ if (num_args != 1) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "fetch mode requires the object parameter");
- } else if (Z_TYPE(args[skip+1]) != IS_OBJECT) {
+ } else if (Z_TYPE(args[0]) != IS_OBJECT) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "object must be an object");
} else {
retval = SUCCESS;
php_error_docref(NULL, E_WARNING, "PHP might crash if you don't call $stmt->setFetchMode() to reset to defaults on this persistent statement. This will be fixed in a later release");
}
#endif
- ZVAL_COPY(&stmt->fetch.into, &args[skip+1]);
+ ZVAL_COPY(&stmt->fetch.into, &args[0]);
}
break;
*/
PDO_STMT_CLEAR_ERR();
- efree(args);
-
return retval;
}
PHP_METHOD(PDOStatement, setFetchMode)
{
+ zend_long fetch_mode;
+ zval *args = NULL;
+ uint32_t num_args = 0;
PHP_STMT_GET_OBJ;
- RETVAL_BOOL(
- pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAM_PASSTHRU,
- stmt, 0) == SUCCESS
- );
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "l*", &fetch_mode, &args, &num_args) == FAILURE) {
+ RETURN_THROWS();
+ }
+
+ RETVAL_BOOL(pdo_stmt_setup_fetch_mode(stmt, fetch_mode, args, num_args) == SUCCESS);
}
/* }}} */
public function setAttribute(int $attribute, $value) {}
/** @return bool */
- public function setFetchMode(int $mode, $param1 = UNKNOWN, $param2 = UNKNOWN) {}
+ public function setFetchMode(int $mode, ...$params) {}
public function getIterator(): Iterator {}
}
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 77e61065025ff7394466ef6d683d37b4a1c793e7 */
+ * Stub hash: 590a642abbc8d54be143a1c595e9e704888e9b5f */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_PDOStatement_bindColumn, 0, 0, 2)
ZEND_ARG_TYPE_MASK(0, column, MAY_BE_LONG|MAY_BE_STRING, NULL)
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_PDOStatement_setFetchMode, 0, 0, 1)
ZEND_ARG_TYPE_INFO(0, mode, IS_LONG, 0)
- ZEND_ARG_INFO(0, param1)
- ZEND_ARG_INFO(0, param2)
+ ZEND_ARG_VARIADIC_INFO(0, params)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_PDOStatement_getIterator, 0, 0, Iterator, 0)
zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object, int by_ref);
extern zend_object_handlers pdo_dbstmt_object_handlers;
int pdo_stmt_describe_columns(pdo_stmt_t *stmt);
-int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, int skip_first_arg);
+int pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long fetch_mode, zval *args, uint32_t num_args);
extern zend_object *pdo_row_new(zend_class_entry *ce);
extern const zend_function_entry pdo_row_functions[];
// Bug entry [3]
-$stmt = $db->query("SELECT * FROM test", 'abc');
-var_dump($stmt);
-
+try {
+ $stmt = $db->query("SELECT * FROM test", 'abc');
+} catch (TypeError $e) {
+ echo $e->getMessage(), "\n";
+}
// Bug entry [4]
$stmt = $db->query("SELECT * FROM test", PDO::FETCH_CLASS, 0, 0, 0);
--EXPECTF--
Warning: PDO::query(): SQLSTATE[HY000]: General error: fetch mode doesn't allow any extra arguments in %s
bool(false)
-
-Warning: PDO::query(): SQLSTATE[HY000]: General error: mode must be an integer in %s
-bool(false)
+PDO::query(): Argument #2 ($fetch_mode) must be of type int, string given
Warning: PDO::query(): SQLSTATE[HY000]: General error: too many arguments in %s
bool(false)
$this->test2 = 22;
}
- function query($sql)
+ function query($sql, ...$rest)
{
echo __METHOD__ . "()\n";
$stmt = parent::prepare($sql, array(PDO::ATTR_STATEMENT_CLASS=>array('PDOStatementx')));
echo __METHOD__ . "()\n";
}
- function query($sql)
+ function query($sql, ...$rest)
{
echo __METHOD__ . "()\n";
$stmt = $this->prepare($sql, array(PDO::ATTR_STATEMENT_CLASS=>array('PDOStatementx', array($this))));
echo __METHOD__ . "()\n";
}
- function query($sql)
+ function query($sql, ...$rest)
{
echo __METHOD__ . "()\n";
$stmt = $this->prepare($sql, array(PDO::ATTR_STATEMENT_CLASS=>array('PDOStatementx', array($this))));
echo __METHOD__ . "()\n";
}
- function query($sql)
+ function query($sql, ...$rest)
{
echo __METHOD__ . "()\n";
return parent::query($sql);