誰もこんなことをやろうとしていないのか、ぐぐってもわからず、結局ソースまで調べて、解決したことをまとめておく。
cygwin の PHP および MySQL は Cygwin Ports から入手することができるため、それをインストールする。
CLI
普通に MySQL のクライアントから接続しようとすると、ソケットがないと怒られてしまう。
% mysql ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) %
マニュアルを確認すると、--protocol というオプションがあるため、それで TCP を指定すると、接続することができる。
% mysql --protocol=TCP -uroot -pvertrigo Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.0.51b-community MySQL Community Edition (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> status -------------- mysql Ver 14.12 Distrib 5.0.75, for pc-cygwin (i686) using readline 5.2 Connection id: 2 Current database: Current user: root@localhost SSL: Not in use Current pager: stdout Using outfile: '' Using delimiter: ; Server version: 5.0.51b-community MySQL Community Edition (GPL) Protocol version: 10 Connection: localhost via TCP/IP Server characterset: latin1 Db characterset: latin1 Client characterset: latin1 Conn. characterset: latin1 TCP port: 3306 Uptime: 50 sec Threads: 1 Questions: 4 Slow queries: 0 Opens: 12 Flush tables: 1 Open tables: 6 Queries per second avg: 0.080 -------------- mysql>
PDO (MySQL)
一方で PHP の PDO で接続する場合は DSN で指定すれば良いように思われるが、普通に指定しても、CLI の場合と同様にソケットを使用しようとしてしまい、やはり怒られてしまう。
<?php $dsn = 'mysql:dbname=hogehoge;host=localhost'; $user = 'root'; $password = 'vertrigo'; try { $dbh = new PDO($dsn, $user, $password); } catch (PDOException $e) { echo 'Connection failed: ' . $e->getMessage(); } ?>
ポート番号を指定しないといけないのかな?と思い 'port=3306' とか、ソケット名を無効にすればいいのかな?と思い 'unix_socket=' とか指定してみるが、駄目。
しかし、MySQL CLI と同じメッセージが表示されるということは --protocol=TCP 相当の情報を渡せば、接続できるはずと思い、PHP の pdo_mysql のソースを調べているうちに以下のコードを発見した。
static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) { pdo_mysql_db_handle *H; int i, ret = 0; char *host = NULL, *unix_socket = NULL; unsigned int port = 3306; char *dbname; struct pdo_data_src_parser vars[] = { { "charset", NULL, 0 }, { "dbname", "", 0 }, { "host", "localhost", 0 }, { "port", "3306", 0 }, { "unix_socket", MYSQL_UNIX_ADDR, 0 }, }; // snip php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 5); // PDO の第一引数 ($dsn) を parse する関数っぽい。 // snip dbname = vars[1].optval; host = vars[2].optval; if(vars[3].optval) { port = atoi(vars[3].optval); } if (vars[2].optval && !strcmp("localhost", vars[2].optval)) { unix_socket = vars[4].optval; } // snip }
どうも 'host=localhost' があると、強制的に 'unix_socket=MYSQL_UNIX_ADDR' (おそらく '/tmp/mysql.sock') が指定されるようになっている感じだったため、試しに 'host=127.0.0.1' に変更してみたところ、接続できることを確認した。
まあ、Windows で cygwin と VertrigoServ を併用している人くらいしかこんなことではまらないとは思いますけどね...。