1--TEST-- 2PDO Common: serializing 3--SKIPIF-- 4<?php # vim:ft=php 5if (!extension_loaded('pdo')) die('skip'); 6if (!interface_exists('Serializable')) die('skip no Serializable interface'); 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='.dirname(__FILE__) . '/../../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$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, classtype int, val VARCHAR(255))'); 75 76$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 77 78var_dump($db->query('SELECT COUNT(*) FROM classtypes')->fetchColumn()); 79var_dump($db->query('SELECT id, name FROM classtypes ORDER by id')->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_UNIQUE)); 80 81$objs = array(); 82$objs[0] = new stdClass; 83$objs[1] = new TestBase; 84$objs[2] = new TestDerived; 85$objs[3] = new TestLeaf; 86 87$stmt = $db->prepare('SELECT id FROM classtypes WHERE name=:cname'); 88$stmt->bindParam(':cname', $cname); 89 90$ctypes = array(); 91 92foreach($objs as $obj) 93{ 94 $cname = get_class($obj); 95 $ctype = NULL; /* set default for non stored class name */ 96 $stmt->execute(); 97 $stmt->bindColumn('id', $ctype); 98 $stmt->fetch(PDO::FETCH_BOUND); 99 $ctypes[$cname] = $ctype; 100} 101 102echo "===TYPES===\n"; 103var_dump($ctypes); 104 105unset($stmt); 106 107echo "===INSERT===\n"; 108$stmt = $db->prepare('INSERT INTO test VALUES(:id, :classtype, :val)'); 109$stmt->bindParam(':id', $idx); 110$stmt->bindParam(':classtype', $ctype); 111$stmt->bindParam(':val', $val); 112 113foreach($objs as $idx => $obj) 114{ 115 $ctype = $ctypes[get_class($obj)]; 116 if (method_exists($obj, 'serialize')) 117 { 118 $val = $obj->serialize(); 119 } 120 else 121 { 122 $val = ''; 123 } 124 $stmt->execute(); 125} 126 127unset($stmt); 128 129echo "===DATA===\n"; 130$res = $db->query('SELECT test.val FROM test')->fetchAll(PDO::FETCH_COLUMN); 131 132switch ($db->getAttribute(PDO::ATTR_DRIVER_NAME)) { 133 case 'dblib': 134 // map whitespace (from early TDS versions) to empty string so the test doesn't diff 135 if ($res[0] === ' ') { 136 $res[0] = ''; 137 } 138 break; 139 140 case 'oci': 141 // map NULL to empty string so the test doesn't diff 142 if ($res[0] === null) { 143 $res[0] = ''; 144 } 145 break; 146} 147var_dump($res); 148 149echo "===FAILURE===\n"; 150try 151{ 152 $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()); 153} 154catch (PDOException $e) 155{ 156 echo 'Exception:'; 157 echo $e->getMessage()."\n"; 158} 159 160echo "===COUNT===\n"; 161var_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()); 162 163echo "===DATABASE===\n"; 164$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)'); 165 166$stmt->execute(); 167var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); 168 169echo "===FETCHCLASS===\n"; 170$stmt->execute(); 171var_dump($stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_CLASSTYPE|PDO::FETCH_SERIALIZE, 'TestLeaf')); 172 173 174?> 175--EXPECTF-- 176string(1) "3" 177array(3) { 178 [0]=> 179 string(8) "stdClass" 180 [1]=> 181 string(8) "TestBase" 182 [2]=> 183 string(11) "TestDerived" 184} 185===TYPES=== 186array(4) { 187 ["stdClass"]=> 188 string(1) "0" 189 ["TestBase"]=> 190 string(1) "1" 191 ["TestDerived"]=> 192 string(1) "2" 193 ["TestLeaf"]=> 194 NULL 195} 196===INSERT=== 197TestBase::serialize() = 'a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}' 198TestDerived::serialize() 199TestBase::serialize() = 'a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}' 200TestDerived::serialize() 201TestBase::serialize() = 'a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}' 202===DATA=== 203array(4) { 204 [0]=> 205 string(0) "" 206 [1]=> 207 string(91) "a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}" 208 [2]=> 209 string(172) "a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}" 210 [3]=> 211 string(172) "a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}" 212} 213===FAILURE=== 214Exception:SQLSTATE[HY000]: General error: cannot unserialize class 215===COUNT=== 216string(1) "3" 217===DATABASE=== 218array(3) { 219 [0]=> 220 array(2) { 221 ["name"]=> 222 string(8) "TestBase" 223 ["val"]=> 224 string(91) "a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}" 225 } 226 [1]=> 227 array(2) { 228 ["name"]=> 229 string(11) "TestDerived" 230 ["val"]=> 231 string(172) "a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}" 232 } 233 [2]=> 234 array(2) { 235 ["name"]=> 236 NULL 237 ["val"]=> 238 string(172) "a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}" 239 } 240} 241===FETCHCLASS=== 242TestBase::unserialize(a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}) 243TestDerived::unserialize() 244TestBase::unserialize(a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}) 245TestDerived::unserialize() 246TestBase::unserialize(a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}) 247array(3) { 248 [0]=> 249 object(TestBase)#%d (3) { 250 ["BasePub"]=> 251 string(7) "#Public" 252 ["BasePro":protected]=> 253 string(10) "#Protected" 254 ["BasePri":"TestBase":private]=> 255 string(8) "#Private" 256 } 257 [1]=> 258 object(TestDerived)#%d (6) { 259 ["BasePub"]=> 260 string(14) "#DerivedPublic" 261 ["BasePro":protected]=> 262 string(17) "#DerivdeProtected" 263 ["DerivedPub"]=> 264 string(7) "#Public" 265 ["DerivedPro":protected]=> 266 string(10) "#Protected" 267 ["DerivedPri":"TestDerived":private]=> 268 string(7) "Private" 269 ["BasePri":"TestBase":private]=> 270 string(8) "#Private" 271 } 272 [2]=> 273 object(TestLeaf)#%d (6) { 274 ["BasePub"]=> 275 string(14) "#DerivedPublic" 276 ["BasePro":protected]=> 277 string(17) "#DerivdeProtected" 278 ["DerivedPub"]=> 279 string(7) "#Public" 280 ["DerivedPro":protected]=> 281 string(10) "#Protected" 282 ["DerivedPri":"TestDerived":private]=> 283 string(7) "Private" 284 ["BasePri":"TestBase":private]=> 285 string(8) "#Private" 286 } 287} 288