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