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 classtypes(id int NOT NULL PRIMARY KEY, name VARCHAR(20) NOT NULL UNIQUE)'); 71$db->exec('INSERT INTO classtypes VALUES(0, \'stdClass\')'); 72$db->exec('INSERT INTO classtypes VALUES(1, \'TestBase\')'); 73$db->exec('INSERT INTO classtypes 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 test(id int NOT NULL PRIMARY KEY, classtype int NULL, val VARCHAR(255) NULL)'; 80 break; 81 default: 82 $sql = 'CREATE TABLE test(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 classtypes')->fetchColumn()); 90var_dump($db->query('SELECT id, name FROM classtypes 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 classtypes 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 test 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 test.val FROM test')->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 classtypes.name AS name, test.val AS val FROM test LEFT JOIN classtypes ON test.classtype=classtypes.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 test LEFT JOIN classtypes ON test.classtype=classtypes.id WHERE (classtypes.id IS NULL OR classtypes.id > 0)')->fetchColumn()); 173 174echo "===DATABASE===\n"; 175$stmt = $db->prepare('SELECT classtypes.name AS name, test.val AS val FROM test LEFT JOIN classtypes ON test.classtype=classtypes.id WHERE (classtypes.id IS NULL OR classtypes.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--EXPECTF-- 187Deprecated: %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 188 189Deprecated: %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 190 191Deprecated: %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 192string(1) "3" 193array(3) { 194 [0]=> 195 string(8) "stdClass" 196 [1]=> 197 string(8) "TestBase" 198 [2]=> 199 string(11) "TestDerived" 200} 201===TYPES=== 202array(4) { 203 ["stdClass"]=> 204 string(1) "0" 205 ["TestBase"]=> 206 string(1) "1" 207 ["TestDerived"]=> 208 string(1) "2" 209 ["TestLeaf"]=> 210 NULL 211} 212===INSERT=== 213TestBase::serialize() = 'a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}' 214TestDerived::serialize() 215TestBase::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";}' 216TestDerived::serialize() 217TestBase::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";}' 218===DATA=== 219array(4) { 220 [0]=> 221 string(0) "" 222 [1]=> 223 string(91) "a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}" 224 [2]=> 225 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";}" 226 [3]=> 227 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";}" 228} 229===FAILURE=== 230 231Deprecated: PDOStatement::fetchAll(): The PDO::FETCH_SERIALIZE mode is deprecated in %s on line %d 232Exception:SQLSTATE[HY000]: General error: cannot unserialize class 233===COUNT=== 234string(1) "3" 235===DATABASE=== 236array(3) { 237 [0]=> 238 array(2) { 239 ["name"]=> 240 string(8) "TestBase" 241 ["val"]=> 242 string(91) "a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}" 243 } 244 [1]=> 245 array(2) { 246 ["name"]=> 247 string(11) "TestDerived" 248 ["val"]=> 249 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";}" 250 } 251 [2]=> 252 array(2) { 253 ["name"]=> 254 NULL 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} 259===FETCHCLASS=== 260 261Deprecated: PDOStatement::fetchAll(): The PDO::FETCH_SERIALIZE mode is deprecated in %s on line %d 262TestBase::unserialize(a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}) 263TestDerived::unserialize() 264TestBase::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";}) 265TestDerived::unserialize() 266TestBase::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";}) 267array(3) { 268 [0]=> 269 object(TestBase)#%d (3) { 270 ["BasePub"]=> 271 string(7) "#Public" 272 ["BasePro":protected]=> 273 string(10) "#Protected" 274 ["BasePri":"TestBase":private]=> 275 string(8) "#Private" 276 } 277 [1]=> 278 object(TestDerived)#%d (6) { 279 ["BasePub"]=> 280 string(14) "#DerivedPublic" 281 ["BasePro":protected]=> 282 string(17) "#DerivdeProtected" 283 ["BasePri":"TestBase":private]=> 284 string(8) "#Private" 285 ["DerivedPub"]=> 286 string(7) "#Public" 287 ["DerivedPro":protected]=> 288 string(10) "#Protected" 289 ["DerivedPri":"TestDerived":private]=> 290 string(7) "Private" 291 } 292 [2]=> 293 object(TestLeaf)#%d (6) { 294 ["BasePub"]=> 295 string(14) "#DerivedPublic" 296 ["BasePro":protected]=> 297 string(17) "#DerivdeProtected" 298 ["BasePri":"TestBase":private]=> 299 string(8) "#Private" 300 ["DerivedPub"]=> 301 string(7) "#Public" 302 ["DerivedPro":protected]=> 303 string(10) "#Protected" 304 ["DerivedPri":"TestDerived":private]=> 305 string(7) "Private" 306 } 307} 308