xref: /php-src/ext/pdo/tests/pdo_018.phpt (revision f4a5db3e)
1--TEST--
2PDO Common: serializing
3--EXTENSIONS--
4pdo
5--SKIPIF--
6<?php
7$dir = getenv('REDIR_TEST_DIR');
8if (false == $dir) die('skip no driver');
9require_once $dir . 'pdo_test.inc';
10PDOTest::skip();
11?>
12--FILE--
13<?php
14if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.__DIR__ . '/../../pdo/tests/');
15require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
16$db = PDOTest::factory();
17
18class TestBase implements Serializable
19{
20    public    $BasePub = 'Public';
21    protected $BasePro = 'Protected';
22    private   $BasePri = 'Private';
23
24    function serialize()
25    {
26        $serialized = array();
27        foreach($this as $prop => $val) {
28            $serialized[$prop] = $val;
29        }
30        $serialized = serialize($serialized);
31        echo __METHOD__ . "() = '$serialized'\n";
32        return $serialized;
33    }
34
35    function unserialize($serialized)
36    {
37        echo __METHOD__ . "($serialized)\n";
38        foreach(unserialize($serialized) as $prop => $val) {
39            $this->$prop = '#'.$val;
40        }
41        return true;
42    }
43}
44
45class TestDerived extends TestBase
46{
47    public    $BasePub    = 'DerivedPublic';
48    protected $BasePro    = 'DerivdeProtected';
49    public    $DerivedPub = 'Public';
50    protected $DerivedPro = 'Protected';
51    private   $DerivedPri = 'Private';
52
53    function serialize()
54    {
55        echo __METHOD__ . "()\n";
56        return TestBase::serialize();
57    }
58
59    function unserialize($serialized)
60    {
61        echo __METHOD__ . "()\n";
62        return TestBase::unserialize($serialized);
63    }
64}
65
66class TestLeaf extends TestDerived
67{
68}
69
70$db->exec('CREATE TABLE classtypes018(id int NOT NULL PRIMARY KEY, name VARCHAR(20) NOT NULL UNIQUE)');
71$db->exec("INSERT INTO classtypes018 VALUES(0, 'stdClass')");
72$db->exec("INSERT INTO classtypes018 VALUES(1, 'TestBase')");
73$db->exec("INSERT INTO classtypes018 VALUES(2, 'TestDerived')");
74
75switch ($db->getAttribute(PDO::ATTR_DRIVER_NAME)) {
76  case 'dblib':
77    // environment settings can influence how the table is created if specifics are missing
78    // https://msdn.microsoft.com/en-us/library/ms174979.aspx#Nullability Rules Within a Table Definition
79    $sql = 'CREATE TABLE test018(id int NOT NULL PRIMARY KEY, classtype int NULL, val VARCHAR(255) NULL)';
80    break;
81  default:
82    $sql = 'CREATE TABLE test018(id int NOT NULL PRIMARY KEY, classtype int, val VARCHAR(255))';
83    break;
84}
85$db->exec($sql);
86
87$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
88
89var_dump($db->query('SELECT COUNT(*) FROM classtypes018')->fetchColumn());
90var_dump($db->query('SELECT id, name FROM classtypes018 ORDER by id')->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_UNIQUE));
91
92$objs = array();
93$objs[0] = new stdClass;
94$objs[1] = new TestBase;
95$objs[2] = new TestDerived;
96$objs[3] = new TestLeaf;
97
98$stmt = $db->prepare('SELECT id FROM classtypes018 WHERE name=:cname');
99$stmt->bindParam(':cname', $cname);
100
101$ctypes = array();
102
103foreach($objs as $obj)
104{
105    $cname = get_class($obj);
106    $ctype = NULL; /* set default for non stored class name */
107    $stmt->execute();
108    $stmt->bindColumn('id', $ctype);
109    $stmt->fetch(PDO::FETCH_BOUND);
110    $ctypes[$cname] = $ctype;
111}
112
113echo "===TYPES===\n";
114var_dump($ctypes);
115
116unset($stmt);
117
118echo "===INSERT===\n";
119$stmt = $db->prepare('INSERT INTO test018 VALUES(:id, :classtype, :val)');
120$stmt->bindParam(':id', $idx);
121$stmt->bindParam(':classtype', $ctype);
122$stmt->bindParam(':val', $val);
123
124foreach($objs as $idx => $obj)
125{
126    $ctype = $ctypes[get_class($obj)];
127    if (method_exists($obj, 'serialize'))
128    {
129        $val = $obj->serialize();
130    }
131    else
132    {
133        $val = '';
134    }
135    $stmt->execute();
136}
137
138unset($stmt);
139
140echo "===DATA===\n";
141$res = $db->query('SELECT test018.val FROM test018')->fetchAll(PDO::FETCH_COLUMN);
142
143switch ($db->getAttribute(PDO::ATTR_DRIVER_NAME)) {
144    case 'dblib':
145        // map whitespace (from early TDS versions) to empty string so the test doesn't diff
146        if ($res[0] === ' ') {
147            $res[0] = '';
148        }
149        break;
150
151    case 'oci':
152        // map NULL to empty string so the test doesn't diff
153        if ($res[0] === null) {
154            $res[0] = '';
155        }
156        break;
157}
158var_dump($res);
159
160echo "===FAILURE===\n";
161try
162{
163    $db->query('SELECT classtypes018.name AS name, test018.val AS val FROM test018 LEFT JOIN classtypes018 ON test018.classtype=classtypes018.id')->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_CLASSTYPE|PDO::FETCH_SERIALIZE, 'TestLeaf', array());
164}
165catch (PDOException $e)
166{
167    echo 'Exception:';
168    echo $e->getMessage()."\n";
169}
170
171echo "===COUNT===\n";
172var_dump($db->query('SELECT COUNT(*) FROM test018 LEFT JOIN classtypes018 ON test018.classtype=classtypes018.id WHERE (classtypes018.id IS NULL OR classtypes018.id > 0)')->fetchColumn());
173
174echo "===DATABASE===\n";
175$stmt = $db->prepare('SELECT classtypes018.name AS name, test018.val AS val FROM test018 LEFT JOIN classtypes018 ON test018.classtype=classtypes018.id WHERE (classtypes018.id IS NULL OR classtypes018.id > 0)');
176
177$stmt->execute();
178var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
179
180echo "===FETCHCLASS===\n";
181$stmt->execute();
182var_dump($stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_CLASSTYPE|PDO::FETCH_SERIALIZE, 'TestLeaf'));
183
184
185?>
186--CLEAN--
187<?php
188require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
189$db = PDOTest::factory();
190PDOTest::dropTableIfExists($db, "test018");
191PDOTest::dropTableIfExists($db, "classtypes018");
192?>
193--EXPECTF--
194Deprecated: %s implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
195
196Deprecated: %s implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
197
198Deprecated: %s implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
199string(1) "3"
200array(3) {
201  [0]=>
202  string(8) "stdClass"
203  [1]=>
204  string(8) "TestBase"
205  [2]=>
206  string(11) "TestDerived"
207}
208===TYPES===
209array(4) {
210  ["stdClass"]=>
211  string(1) "0"
212  ["TestBase"]=>
213  string(1) "1"
214  ["TestDerived"]=>
215  string(1) "2"
216  ["TestLeaf"]=>
217  NULL
218}
219===INSERT===
220TestBase::serialize() = 'a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}'
221TestDerived::serialize()
222TestBase::serialize() = 'a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:7:"BasePri";s:7:"Private";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";}'
223TestDerived::serialize()
224TestBase::serialize() = 'a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:7:"BasePri";s:7:"Private";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";}'
225===DATA===
226array(4) {
227  [0]=>
228  string(0) ""
229  [1]=>
230  string(91) "a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}"
231  [2]=>
232  string(172) "a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:7:"BasePri";s:7:"Private";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";}"
233  [3]=>
234  string(172) "a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:7:"BasePri";s:7:"Private";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";}"
235}
236===FAILURE===
237
238Deprecated: PDOStatement::fetchAll(): The PDO::FETCH_SERIALIZE mode is deprecated in %s on line %d
239Exception:SQLSTATE[HY000]: General error: cannot unserialize class
240===COUNT===
241string(1) "3"
242===DATABASE===
243array(3) {
244  [0]=>
245  array(2) {
246    ["name"]=>
247    string(8) "TestBase"
248    ["val"]=>
249    string(91) "a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}"
250  }
251  [1]=>
252  array(2) {
253    ["name"]=>
254    string(11) "TestDerived"
255    ["val"]=>
256    string(172) "a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:7:"BasePri";s:7:"Private";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";}"
257  }
258  [2]=>
259  array(2) {
260    ["name"]=>
261    NULL
262    ["val"]=>
263    string(172) "a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:7:"BasePri";s:7:"Private";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";}"
264  }
265}
266===FETCHCLASS===
267
268Deprecated: PDOStatement::fetchAll(): The PDO::FETCH_SERIALIZE mode is deprecated in %s on line %d
269TestBase::unserialize(a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";})
270TestDerived::unserialize()
271TestBase::unserialize(a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:7:"BasePri";s:7:"Private";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";})
272TestDerived::unserialize()
273TestBase::unserialize(a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:7:"BasePri";s:7:"Private";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";})
274array(3) {
275  [0]=>
276  object(TestBase)#%d (3) {
277    ["BasePub"]=>
278    string(7) "#Public"
279    ["BasePro":protected]=>
280    string(10) "#Protected"
281    ["BasePri":"TestBase":private]=>
282    string(8) "#Private"
283  }
284  [1]=>
285  object(TestDerived)#%d (6) {
286    ["BasePub"]=>
287    string(14) "#DerivedPublic"
288    ["BasePro":protected]=>
289    string(17) "#DerivdeProtected"
290    ["BasePri":"TestBase":private]=>
291    string(8) "#Private"
292    ["DerivedPub"]=>
293    string(7) "#Public"
294    ["DerivedPro":protected]=>
295    string(10) "#Protected"
296    ["DerivedPri":"TestDerived":private]=>
297    string(7) "Private"
298  }
299  [2]=>
300  object(TestLeaf)#%d (6) {
301    ["BasePub"]=>
302    string(14) "#DerivedPublic"
303    ["BasePro":protected]=>
304    string(17) "#DerivdeProtected"
305    ["BasePri":"TestBase":private]=>
306    string(8) "#Private"
307    ["DerivedPub"]=>
308    string(7) "#Public"
309    ["DerivedPro":protected]=>
310    string(10) "#Protected"
311    ["DerivedPri":"TestDerived":private]=>
312    string(7) "Private"
313  }
314}
315