1--TEST-- 2PDO::ATTR_STATEMENT_CLASS 3--SKIPIF-- 4<?php 5require_once(__DIR__ . DIRECTORY_SEPARATOR . 'skipif.inc'); 6require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); 7MySQLPDOTest::skip(); 8$db = MySQLPDOTest::factory(); 9?> 10--FILE-- 11<?php 12 require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); 13 $db = MySQLPDOTest::factory(); 14 MySQLPDOTest::createTestTable($db); 15 16 $default = $db->getAttribute(PDO::ATTR_STATEMENT_CLASS); 17 var_dump($default); 18 19 try { 20 $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, 'foo'); 21 } catch (\TypeError $e) { 22 echo $e->getMessage(), \PHP_EOL; 23 } 24 try { 25 $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, ['classname']); 26 } catch (\TypeError $e) { 27 echo $e->getMessage(), \PHP_EOL; 28 } 29 // unknown class 30 try { 31 $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, ['classname', []]); 32 } catch (\TypeError $e) { 33 echo $e->getMessage(), \PHP_EOL; 34 } 35 36 // class not derived from PDOStatement 37 class myclass { 38 function __construct() { 39 printf("myclass\n"); 40 } 41 } 42 43 try { 44 $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, ['myclass', []]); 45 } catch (\TypeError $e) { 46 echo $e->getMessage(), \PHP_EOL; 47 } 48 49 // public constructor not allowed 50 class mystatement extends PDOStatement { 51 public function __construct() { 52 printf("mystatement\n"); 53 } 54 } 55 56 try { 57 if (false !== ($tmp = $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, ['mystatement', []]))) 58 printf("[006] Expecting boolean/false got %s\n", var_export($tmp, true)); 59 } catch (\Error $e) { 60 echo get_class($e), ': ', $e->getMessage(), \PHP_EOL; 61 } 62 63 64 // ... but a public destructor is allowed 65 class mystatement2 extends PDOStatement { 66 public function __destruct() { 67 printf("mystatement\n"); 68 } 69 } 70 71 if (true !== ($tmp = $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('mystatement2', array())))) 72 printf("[007] Expecting boolean/true got %s\n", var_export($tmp, true)); 73 74 // private constructor 75 class mystatement3 extends PDOStatement { 76 private function __construct($msg) { 77 printf("mystatement3\n"); 78 var_dump($msg); 79 } 80 } 81 if (true !== ($tmp = $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('mystatement3', array('param1'))))) 82 printf("[008] Expecting boolean/true got %s\n", var_export($tmp, true)); 83 84 // private constructor 85 class mystatement4 extends PDOStatement { 86 private function __construct($msg) { 87 printf("%s\n", get_class($this)); 88 var_dump($msg); 89 } 90 } 91 if (true !== ($tmp = $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('mystatement4', array('param1'))))) 92 printf("[008] Expecting boolean/true got %s\n", var_export($tmp, true)); 93 94 var_dump($db->getAttribute(PDO::ATTR_STATEMENT_CLASS)); 95 $stmt = $db->query('SELECT id, label FROM test ORDER BY id ASC LIMIT 2'); 96 97 class mystatement5 extends mystatement4 { 98 public function fetchAll($fetch_style = 1, ...$fetch_args) { 99 return "no data :)"; 100 } 101 } 102 103 if (true !== ($tmp = $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('mystatement5', array('mystatement5'))))) 104 printf("[009] Expecting boolean/true got %s\n", var_export($tmp, true)); 105 $stmt = $db->query('SELECT id, label FROM test ORDER BY id ASC LIMIT 2'); 106 var_dump($stmt->fetchAll()); 107 108 if (true !== ($tmp = $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDOStatement')))) 109 printf("[010] Expecting boolean/true got %s\n", var_export($tmp, true)); 110 111 $stmt = $db->query('SELECT id, label FROM test ORDER BY id ASC LIMIT 1'); 112 var_dump($stmt->fetchAll()); 113 114 // Yes, this is a fatal error and I want it to fail. 115 abstract class mystatement6 extends mystatement5 { 116 } 117 try { 118 $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, ['mystatement6', ['mystatement6']]); 119 $stmt = $db->query('SELECT id, label FROM test ORDER BY id ASC LIMIT 1'); 120 } catch (\Error $e) { 121 echo get_class($e), ': ', $e->getMessage(), \PHP_EOL; 122 } 123 124?> 125--EXPECT-- 126array(1) { 127 [0]=> 128 string(12) "PDOStatement" 129} 130PDO::ATTR_STATEMENT_CLASS value must be of type array, string given 131PDO::ATTR_STATEMENT_CLASS class must be a valid class 132PDO::ATTR_STATEMENT_CLASS class must be a valid class 133PDO::ATTR_STATEMENT_CLASS class must be derived from PDOStatement 134TypeError: User-supplied statement class cannot have a public constructor 135array(2) { 136 [0]=> 137 string(12) "mystatement4" 138 [1]=> 139 array(1) { 140 [0]=> 141 string(6) "param1" 142 } 143} 144mystatement4 145string(6) "param1" 146mystatement5 147string(12) "mystatement5" 148string(10) "no data :)" 149array(1) { 150 [0]=> 151 array(4) { 152 ["id"]=> 153 string(1) "1" 154 [0]=> 155 string(1) "1" 156 ["label"]=> 157 string(1) "a" 158 [1]=> 159 string(1) "a" 160 } 161} 162Error: Cannot instantiate abstract class mystatement6 163