1--TEST-- 2MySQL PDO->__construct() - Generic + DSN 3--SKIPIF-- 4<?php 5require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc'); 6require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); 7MySQLPDOTest::skip(); 8?> 9--FILE-- 10<?php 11 require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); 12 13 function tryandcatch($offset, $code) { 14 15 try { 16 eval($code); 17 assert(sprintf("[%03d] Should have failed\n", $offset) != ''); 18 } catch (PDOException $e) { 19 return sprintf("[%03d] %s, [%s] %s\n", 20 $offset, 21 $e->getMessage(), 22 (isset($db) && is_object($db)) ? $db->errorCode() : 'n/a', 23 (isset($db) && is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a'); 24 } 25 26 return ''; 27 } 28 29 try { 30 31 if (NULL !== ($db = @new PDO())) 32 printf("[001] Too few parameters\n"); 33 34 print tryandcatch(2, '$db = new PDO(chr(0));'); 35 print tryandcatch(3, '$db = new PDO("a" . chr(0) . "b");'); 36 print tryandcatch(4, '$db = new PDO("MYSQL");'); 37 print tryandcatch(5, '$db = new PDO("mysql");'); 38 print tryandcatch(6, '$db = new PDO("mysql ");'); 39 print tryandcatch(7, '$db = new PDO("fantasyandfriends :");'); 40 41 $dsn = PDO_MYSQL_TEST_DSN; 42 // MySQL Server might accept anonymous connections, don't 43 // print anything 44 tryandcatch(8, '$db = new PDO("' . $dsn . '");'); 45 46 $user = 'dontcreatesuchauser'; 47 $pass = 'withthispassword'; 48 print tryandcatch(9, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");'); 49 50 // should fail 51 $dsn = 'mysql:'; 52 // don't print the message since it can be different 53 tryandcatch(10, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");'); 54 55 $dsn = PDO_MYSQL_TEST_DSN; 56 $user = PDO_MYSQL_TEST_USER; 57 $pass = PDO_MYSQL_TEST_PASS; 58 // should work... 59 $db = new PDO($dsn, $user, $pass); 60 61 // Reaction on host not specified differs for different configs, so no printing 62 $dsn = 'mysql:invalid=foo'; 63 tryandcatch(11, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");'); 64 65 $dsn = 'mysql:' . str_repeat('howmuch=canpdoeat;', 1000); 66 tryandcatch(12, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");'); 67 68 $dsn = 'mysql:' . str_repeat('abcdefghij', 1024 * 10) . '=somevalue'; 69 tryandcatch(13, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");'); 70 71 if (PDO_MYSQL_TEST_HOST) { 72 $host = PDO_MYSQL_TEST_HOST; 73 $invalid_host = $host . 'invalid'; 74 75 // last host specification should be the one used 76 $dsn = MySQLPDOTest::getDSN(array('host' => $host), 'host=' . $invalid_host); 77 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 78 $tmp = $e->getMessage(); 79 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005') && !stristr($tmp, '2002')) 80 printf("[014] Cannot find proper error codes: %s\n", $tmp); 81 } 82 83 $dsn = MySQLPDOTest::getDSN(array('host' => $invalid_host), 'host=' . $host); 84 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 85 printf("[015] DSN=%s, %s\n", $dsn, $e->getMessage()); 86 } 87 88 $invalid_host = '-' . chr(0); 89 90 $dsn = MySQLPDOTest::getDSN(array('host' => $invalid_host)); 91 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 92 $tmp = $e->getMessage(); 93 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005') && !stristr($tmp, '2002')) 94 printf("[016] Cannot find proper error codes: %s\n", $tmp); 95 } 96 97 // parsing should not get confused by chr(0) 98 $dsn = MySQLPDOTest::getDSN(array('host' => $invalid_host), 'host=' . $host); 99 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 100 printf("[017] DSN=%s, %s\n", $dsn, $e->getMessage()); 101 } 102 103 } 104 105 // what about long values for a valid option ... 106 // hostnames > 1024 chars break on some NIS-enabled FreeBSD... 107 $dsn = MySQLPDOTest::getDSN(array('host' => str_repeat('0123456789', 100))); 108 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 109 $tmp = $e->getMessage(); 110 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005') && !stristr($tmp, '2002')) 111 printf("[018] Cannot find proper error codes: %s\n", $tmp); 112 } 113 114 if (PDO_MYSQL_TEST_PORT && (PDO_MYSQL_TEST_SOCKET == '')) { 115 // Playing with the port makes only sense if no socket gets used 116 117 $port = PDO_MYSQL_TEST_PORT; 118 // let's hope we don't hit a MySQL running on that port... 119 $invalid_port = $port * 2; 120 121 $dsn = MySQLPDOTest::getDSN(array('port' => $port), 'port=' . $invalid_port); 122 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 123 $tmp = $e->getMessage(); 124 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005')) 125 printf("[019] Cannot find proper error codes: %s\n", $tmp); 126 } 127 128 $dsn = MySQLPDOTest::getDSN(array('port' => $invalid_port), 'port=' . $port); 129 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 130 printf("[020] DSN=%s, %s\n", $dsn, $e->getMessage()); 131 } 132 133 $invalid_port = 'abc'; 134 $dsn = MySQLPDOTest::getDSN(array('port' => $port), 'port=' . $invalid_port); 135 try { 136 $db = @new PDO($dsn, $user, $pass); 137 // atoi('abc') = 0, 0 -> fallback to default 3306 -> may or may not fail! 138 } catch (PDOException $e) { 139 } 140 141 } 142 143 if (PDO_MYSQL_TEST_DB) { 144 $db = PDO_MYSQL_TEST_DB; 145 $invalid_db = 'letshopeitdoesnotexist'; 146 147 $dsn = MySQLPDOTest::getDSN(array('dbname' => $db), 'dbname=' . $invalid_db); 148 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 149 $tmp = $e->getMessage(); 150 if (!stristr($tmp, '42000') && !stristr($tmp, '1049')) 151 printf("[022] Cannot find proper error codes: %s\n", $tmp); 152 } 153 154 $dsn = MySQLPDOTest::getDSN(array('dbname' => $invalid_db), 'dbname=' . $db); 155 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 156 printf("[023] DSN=%s, %s\n", $dsn, $e->getMessage()); 157 } 158 159 } 160 161 if (PDO_MYSQL_TEST_SOCKET && (stristr(PDO_MYSQL_TEST_DSN, PDO_MYSQL_TEST_SOCKET) !== false)) { 162 $socket = PDO_MYSQL_TEST_SOCKET; 163 $invalid_socket = '/lets/hope/it/does/not/exist'; 164 165 $dsn = MySQLPDOTest::getDSN(array('unix_socket' => $socket), 'unix_socket=' . $invalid_socket); 166 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 167 $tmp = $e->getMessage(); 168 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2002')) 169 printf("[024] Cannot find proper error codes: %s\n", $tmp); 170 } 171 172 $dsn = MySQLPDOTest::getDSN(array('unix_socket' => $invalid_socket), 'unix_socket=' . $socket); 173 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 174 printf("[025] DSN=%s, %s\n", $dsn, $e->getMessage()); 175 } 176 177 } 178 179 $have_charset_support = false; 180 $dsn = MySQLPDOTest::getDSN(); 181 try { 182 $db = new PDO($dsn, $user, $pass); 183 $stmt = $db->query('SELECT VERSION() as _version'); 184 $version = $stmt->fetch(PDO::FETCH_ASSOC); 185 186 $tmp = explode('.', $version['_version']); 187 if ((count($tmp) == 3) && 188 (($tmp[0] >= 4 && $tmp[1] >= 1) || ($tmp[0] >= 5))) { 189 // MySQL Server 4.1 - charset support available 190 $have_charset_support = true; 191 } 192 193 } catch (PDOException $e) { 194 printf("[026] DSN=%s, %s\n", $dsn, $e->getMessage()); 195 } 196 197 if (PDO_MYSQL_TEST_CHARSET) { 198 $charset = PDO_MYSQL_TEST_CHARSET; 199 $invalid_charset = 'invalid'; 200 201 if ($have_charset_support) { 202 $dsn = MySQLPDOTest::getDSN(); 203 $db = new PDO($dsn, $user, $pass); 204 $stmt = $db->query(sprintf('SHOW CHARACTER SET LIKE "%s"', $charset)); 205 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 206 $have_charset = (empty($tmp)) ? false : true; 207 208 if ($have_charset) { 209 $dsn = MySQLPDOTest::getDSN(array('charset' => $charset), 'charset=' . $invalid_charset); 210 try { 211 $db = @new PDO($dsn, $user, $pass); 212 /* NOTE: MySQL does a fallback to the charset suggested during the handshake - no error - no bug! */ 213 } catch (PDOException $e) { 214 $tmp = $e->getMessage(); 215 /* TODO: add proper codes */ 216 if (!stristr($tmp, 'sqlstatecode') || !stristr($tmp, 'mysqlinternalerrcode')) 217 printf("[027] TODO - Cannot find proper error codes: %s\n", $tmp); 218 } 219 220 $dsn = MySQLPDOTest::getDSN(array('charset' => $invalid_charset), 'charset=' . $charset); 221 try { 222 $db = @new PDO($dsn, $user, $pass); 223 /* Strictly speaking we should test more: character_set_client, character_set_results, and character_set_connection */ 224 $stmt = $db->query('SELECT @@character_set_connection AS _charset'); 225 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 226 if ($tmp['_charset'] != $charset) 227 printf("[028] Character sets has not been set, @@character_set_connection reports '%s', expecting '%s'", 228 $tmp['_charset'], $charset); 229 } catch (PDOException $e) { 230 printf("[029] DSN=%s, %s\n", $dsn, $e->getMessage()); 231 } 232 } else { 233 printf("[030] You're trying to run the tests with charset '%s' which seems not supported by the server!", $charset); 234 } 235 236 } 237 238 } 239 240 if ($have_charset_support) { 241 // In case the PDO_MYSQL_TEST_CHARSET interferes with any defaults 242 // we do another test to verify that the charset has been set. 243 $dsn = MySQLPDOTest::getDSN(); 244 $db = new PDO($dsn, $user, $pass); 245 $stmt = $db->query('SHOW CHARACTER SET LIKE "latin1"'); 246 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 247 $have_latin1 =(empty($tmp)) ? false : true; 248 $stmt = $db->query('SHOW CHARACTER SET LIKE "latin2"'); 249 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 250 $have_latin2 =(empty($tmp)) ? false : true; 251 252 if ($have_latin1 && $have_latin2) { 253 // very likely we do have both of them... 254 try { 255 $dsn = MySQLPDOTest::getDSN(array('charset' => 'latin1')); 256 $db = new PDO($dsn, $user, $pass); 257 $stmt = $db->query('SELECT @@character_set_connection AS _charset'); 258 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 259 if ($tmp['_charset'] != 'latin1') 260 printf("[031] DSN = %s, Character sets has not been set, @@character_set_connection reports '%s', expecting '%s'", 261 $dsn, $tmp['_charset'], 'latin1'); 262 263 } catch (PDOException $e) { 264 printf("[032] %s\n", $e->getMessage()); 265 } 266 267 try { 268 $dsn = MySQLPDOTest::getDSN(array('charset' => 'latin2')); 269 $db = new PDO($dsn, $user, $pass); 270 $stmt = $db->query('SELECT @@character_set_connection AS _charset'); 271 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 272 if ($tmp['_charset'] != 'latin2') 273 printf("[033] DSN = %s, character sets has not been set, @@character_set_connection reports '%s', expecting '%s'", 274 $dsn, $tmp['_charset'], 'latin2'); 275 276 } catch (PDOException $e) { 277 printf("[034] %s\n", $e->getMessage()); 278 } 279 280 } 281 } 282 283 } catch (PDOException $e) { 284 printf("[001] %s, [%s] %s\n", 285 $e->getMessage(), 286 (is_object($db)) ? $db->errorCode() : 'n/a', 287 (is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a'); 288 } 289 290 print "done!"; 291?> 292--EXPECTF-- 293[002] invalid data source name, [n/a] n/a 294[003] invalid data source name, [n/a] n/a 295[004] invalid data source name, [n/a] n/a 296[005] invalid data source name, [n/a] n/a 297[006] invalid data source name, [n/a] n/a 298[007] could not find driver, [n/a] n/a 299[009] SQLSTATE[%s] [1045] Access denied for user 'dont%s'@'%s' (using password: YES), [n/a] n/a 300[017] DSN=%s, SQLSTATE[%s] [%d] %s 301done! 302