pdo_018.phpt 9.6 KB

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