int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, int skip)
{
long mode = PDO_FETCH_BOTH;
- int argc = ZEND_NUM_ARGS() - skip;
+ int flags, argc = ZEND_NUM_ARGS() - skip;
zval ***args;
zend_class_entry **cep;
convert_to_long_ex(args[skip]);
mode = Z_LVAL_PP(args[skip]);
+ flags = mode & PDO_FETCH_FLAGS;
if (!pdo_stmt_verify_mode(stmt, mode, 0 TSRMLS_CC)) {
efree(args);
break;
case PDO_FETCH_CLASS:
- if (argc < 2 || argc > 3) {
- goto fail_out;
- }
- convert_to_string_ex(args[skip+1]);
-
- if (FAILURE == zend_lookup_class(Z_STRVAL_PP(args[skip+1]),
- Z_STRLEN_PP(args[skip+1]), &cep TSRMLS_CC)) {
- goto fail_out;
- }
+ /* Gets its class name from 1st column */
+ if ((flags & PDO_FETCH_CLASSTYPE) == PDO_FETCH_CLASSTYPE) {
+ if (argc != 1) {
+ goto fail_out;
+ }
+ stmt->fetch.cls.ce = NULL;
+ } else {
+ if (argc < 2 || argc > 3) {
+ goto fail_out;
+ }
+ convert_to_string_ex(args[skip+1]);
- if (!cep || !*cep) {
- goto fail_out;
+ if (FAILURE == zend_lookup_class(Z_STRVAL_PP(args[skip+1]),
+ Z_STRLEN_PP(args[skip+1]), &cep TSRMLS_CC)) {
+ goto fail_out;
+ }
+
+ if (!cep || !*cep) {
+ goto fail_out;
+ }
+
+ stmt->fetch.cls.ce = *cep;
}
-
- stmt->fetch.cls.ce = *cep;
+
stmt->fetch.cls.ctor_args = NULL;
#ifdef ilia_0 /* we'll only need this when we have persistent statements, if ever */
--- /dev/null
+--TEST--
+Bug #46292 (PDO::setFetchMode() shouldn't requires the 2nd arg when using FETCH_CLASSTYPE)
+--FILE--
+<?php
+
+ require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+ $pdoDb = MySQLPDOTest::factory();
+
+
+ class myclass implements Serializable {
+ public function __construct() {
+ printf("%s()\n", __METHOD__);
+ }
+
+ public function serialize() {
+ printf("%s()\n", __METHOD__);
+ return "any data from serialize()";
+ }
+
+ public function unserialize($dat) {
+ printf("%s(%s)\n", __METHOD__, var_export($dat, true));
+ return $dat;
+ }
+ }
+
+ class myclass2 extends myclass { }
+
+ $pdoDb->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
+
+ $pdoDb->query('DROP TABLE IF EXISTS testz');
+
+ $pdoDb->query('CREATE TABLE testz (name VARCHAR(20) NOT NULL, value INT)');
+
+ $pdoDb->query("INSERT INTO testz VALUES ('myclass', 1), ('myclass2', 2), ('myclass', NULL), ('myclass3', NULL)");
+
+ $stmt = $pdoDb->prepare("SELECT * FROM testz");
+
+ var_dump($stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE | PDO::FETCH_GROUP));
+ $stmt->execute();
+
+ var_dump($stmt->fetch());
+ var_dump($stmt->fetch());
+ var_dump($stmt->fetchAll());
+
+ $pdoDb->query('DROP TABLE IF EXISTS testz');
+
+?>
+--EXPECTF--
+bool(true)
+myclass::__construct()
+object(myclass)#3 (1) {
+ ["value"]=>
+ string(1) "1"
+}
+myclass::__construct()
+object(myclass2)#3 (1) {
+ ["value"]=>
+ string(1) "2"
+}
+myclass::__construct()
+array(2) {
+ [0]=>
+ object(myclass)#3 (1) {
+ ["value"]=>
+ NULL
+ }
+ [1]=>
+ object(stdClass)#4 (1) {
+ ["value"]=>
+ NULL
+ }
+}