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 132// For Oracle map NULL to empty string so the test doesn't diff 133if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'oci' && $res[0] === null) { 134 $res[0] = ""; 135} 136var_dump($res); 137 138echo "===FAILURE===\n"; 139try 140{ 141 $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()); 142} 143catch (PDOException $e) 144{ 145 echo 'Exception:'; 146 echo $e->getMessage()."\n"; 147} 148 149echo "===COUNT===\n"; 150var_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()); 151 152echo "===DATABASE===\n"; 153$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)'); 154 155$stmt->execute(); 156var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); 157 158echo "===FETCHCLASS===\n"; 159$stmt->execute(); 160var_dump($stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_CLASSTYPE|PDO::FETCH_SERIALIZE, 'TestLeaf')); 161 162 163?> 164--EXPECTF-- 165string(1) "3" 166array(3) { 167 [0]=> 168 string(8) "stdClass" 169 [1]=> 170 string(8) "TestBase" 171 [2]=> 172 string(11) "TestDerived" 173} 174===TYPES=== 175array(4) { 176 ["stdClass"]=> 177 string(1) "0" 178 ["TestBase"]=> 179 string(1) "1" 180 ["TestDerived"]=> 181 string(1) "2" 182 ["TestLeaf"]=> 183 NULL 184} 185===INSERT=== 186TestBase::serialize() = 'a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}' 187TestDerived::serialize() 188TestBase::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";}' 189TestDerived::serialize() 190TestBase::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";}' 191===DATA=== 192array(4) { 193 [0]=> 194 string(0) "" 195 [1]=> 196 string(91) "a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}" 197 [2]=> 198 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";}" 199 [3]=> 200 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";}" 201} 202===FAILURE=== 203Exception:SQLSTATE[HY000]: General error: cannot unserialize class 204===COUNT=== 205string(1) "3" 206===DATABASE=== 207array(3) { 208 [0]=> 209 array(2) { 210 ["name"]=> 211 string(8) "TestBase" 212 ["val"]=> 213 string(91) "a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}" 214 } 215 [1]=> 216 array(2) { 217 ["name"]=> 218 string(11) "TestDerived" 219 ["val"]=> 220 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";}" 221 } 222 [2]=> 223 array(2) { 224 ["name"]=> 225 NULL 226 ["val"]=> 227 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";}" 228 } 229} 230===FETCHCLASS=== 231TestBase::unserialize(a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}) 232TestDerived::unserialize() 233TestBase::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";}) 234TestDerived::unserialize() 235TestBase::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";}) 236array(3) { 237 [0]=> 238 object(TestBase)#%d (3) { 239 ["BasePub"]=> 240 string(7) "#Public" 241 ["BasePro":protected]=> 242 string(10) "#Protected" 243 ["BasePri":"TestBase":private]=> 244 string(8) "#Private" 245 } 246 [1]=> 247 object(TestDerived)#%d (6) { 248 ["BasePub"]=> 249 string(14) "#DerivedPublic" 250 ["BasePro":protected]=> 251 string(17) "#DerivdeProtected" 252 ["DerivedPub"]=> 253 string(7) "#Public" 254 ["DerivedPro":protected]=> 255 string(10) "#Protected" 256 ["DerivedPri":"TestDerived":private]=> 257 string(7) "Private" 258 ["BasePri":"TestBase":private]=> 259 string(8) "#Private" 260 } 261 [2]=> 262 object(TestLeaf)#%d (6) { 263 ["BasePub"]=> 264 string(14) "#DerivedPublic" 265 ["BasePro":protected]=> 266 string(17) "#DerivdeProtected" 267 ["DerivedPub"]=> 268 string(7) "#Public" 269 ["DerivedPro":protected]=> 270 string(10) "#Protected" 271 ["DerivedPri":"TestDerived":private]=> 272 string(7) "Private" 273 ["BasePri":"TestBase":private]=> 274 string(8) "#Private" 275 } 276} 277