1--TEST--
2MySQL PDO: PDOStatement->fetchObject()
3--EXTENSIONS--
4pdo_mysql
5--SKIPIF--
6<?php
7require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
8MySQLPDOTest::skip();
9$db = MySQLPDOTest::factory();
10
11try {
12    $query = "SELECT '', NULL, \"\" FROM DUAL";
13    $stmt = $db->prepare($query);
14    $ok = @$stmt->execute();
15} catch (PDOException $e) {
16    die("skip: Test cannot be run with SQL mode ANSI");
17}
18if (!$ok)
19    die("skip: Test cannot be run with SQL mode ANSI");
20?>
21--FILE--
22<?php
23require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
24$db = MySQLPDOTest::factory();
25$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
26MySQLPDOTest::createTestTable($db);
27
28try {
29
30    $query = "SELECT id, '', NULL, \"\" FROM test ORDER BY id ASC LIMIT 3";
31    $stmt = $db->prepare($query);
32
33    #[AllowDynamicProperties]
34    class myclass {
35
36        private $set_calls = 0;
37        protected static $static_set_calls = 0;
38
39        // NOTE: PDO does not care about protected
40        protected $grp;
41
42        // NOTE: PDO does not care about private and calls __construct() after __set()
43        private function __construct($param1, $param2) {
44            printf("myclass::__construct(%s, %s): %d / %d\n",
45                $param1, $param2,
46                self::$static_set_calls, $this->set_calls);
47        }
48
49        // NOTE: PDO will call __set() prior to calling __construct()
50        public function __set($prop, $value) {
51            $this->not_a_magic_one();
52            printf("myclass::__set(%s, -%s-) %d\n",
53                $prop, var_export($value, true), $this->set_calls, self::$static_set_calls);
54            if ("" != $prop)
55                $this->{$prop} = $value;
56        }
57
58        // NOTE: PDO can call regular methods prior to calling __construct()
59        public function not_a_magic_one() {
60            $this->set_calls++;
61            self::$static_set_calls++;
62        }
63
64    }
65    $stmt->execute();
66    $rowno = 0;
67    $rows[] = array();
68    while (is_object($rows[] = $stmt->fetchObject('myclass', array($rowno++, $rowno))))
69        ;
70
71    var_dump($rows[$rowno - 1]);
72
73    try {
74        $stmt->fetchObject('class_does_not_exist');
75    } catch (TypeError $e) {
76        echo $e->getMessage(), "\n";
77    }
78} catch (PDOException $e) {
79    // we should never get here, we use warnings, but never trust a system...
80    printf("[001] %s, [%s} %s\n",
81        $e->getMessage(), $db->errorInfo(), implode(' ', $db->errorInfo()));
82}
83
84print "done!";
85?>
86--CLEAN--
87<?php
88require __DIR__ . '/mysql_pdo_test.inc';
89MySQLPDOTest::dropTestTable();
90?>
91--EXPECTF--
92myclass::__set(id, -'1'-) 1
93myclass::__set(, -''-) 2
94myclass::__set(null, -NULL-) 3
95myclass::__set(, -''-) 4
96myclass::__construct(0, 1): 4 / 4
97myclass::__set(id, -'2'-) 1
98myclass::__set(, -''-) 2
99myclass::__set(null, -NULL-) 3
100myclass::__set(, -''-) 4
101myclass::__construct(1, 2): 8 / 4
102myclass::__set(id, -'3'-) 1
103myclass::__set(, -''-) 2
104myclass::__set(null, -NULL-) 3
105myclass::__set(, -''-) 4
106myclass::__construct(2, 3): 12 / 4
107object(myclass)#%d (4) {
108  ["set_calls":"myclass":private]=>
109  int(4)
110  ["grp":protected]=>
111  NULL
112  ["id"]=>
113  string(1) "3"
114  ["null"]=>
115  NULL
116}
117PDOStatement::fetchObject(): Argument #1 ($class) must be a valid class name, class_does_not_exist given
118done!
119