April 2008
April 30, 2008
Storing images into the Database
phpでデータベースにバイナリデータ(画像・ファイル)を保存する方法。
$binaryはfile_get_contents()などで取得したバイナリデータ。
・MySQL
デフォルトでは4KBを超えるクエリは制限されているので、php.iniのmssql.textlimitやmssql.textsizeのサイズを大きくする必要がある。
他のPDO拡張のようにバイナリデータを直接渡せないので注意。
$binaryはfile_get_contents()などで取得したバイナリデータ。
・MySQL
$query = "INSERT INTO test(bindata) VALUES('%s')";
$query = sprintf($query, mysql_real_escape_string($binary, $conn));
mysql_query($query, $conn);
・MySQLi
$query = "INSERT INTO test(bindata) VALUES('%s')";
$query = sprintf($query, mysqli_real_escape_string($conn, $binary));
mysqli_query($conn, $query);
・PostgreSQL
$query = "INSERT INTO test(bindata) VALUES('%s')";
$query = sprintf($query, pg_escape_bytea($conn, $binary));
pg_query($conn, $query);
・OCI8
$query = "INSERT INTO test(bindata) VALUES(EMPTY_BLOB()) RETURNING bindata INTO :bindata"; $stmt = oci_parse($conn, $query); $lob = oci_new_descripter($conn, OCI_D_LOB); oci_bind_by_name($stmt, ":bindata", $lob, -1, SQLT_BLOB); $res = oci_execute($stmt, OCI_DEFAULT); $lob->save($binary); oci_commit($conn);・SQL Server
デフォルトでは4KBを超えるクエリは制限されているので、php.iniのmssql.textlimitやmssql.textsizeのサイズを大きくする必要がある。
$query = "INSERT INTO test(bindata) VALUES(%s)"; $query = sprintf($query, "0x" . bin2hex($binary)); mssql_query($query, $conn);・Firebird/Interbase
$query = "INSERT INTO test(bindata) VALUES(?)"; $blobId = ibase_blob_create(); ibase_blob_add($blobId, $binary); $blob = ibase_blob_close($blobId); ibase_query($conn, $query, $blob);・PDO_MYSQL/PDO_PGSQL/PDO_SQLITE
$query = "INSERT INTO test(bindata) VALUES(:bindata)";
$stmt = $pdo->prepare($query);
$stmt->bindValue(":bindata", $binary, PDO::PARAM_LOB);
$pdo->beginTransaction();
$stmt->execute();
$pdo->commit();
・PDO_OCI他のPDO拡張のようにバイナリデータを直接渡せないので注意。
$query = "INSERT INTO test(bindata) VALUES(EMPTY_BLOB()) RETURNING bindata INTO :bindata";
$stmt = $pdo->prepare($query);
$tmpfile = file_put_contents($tmpfilePath, $binary);
$fp = fopen($tmpfile, "rb");
$stmt->bindValue(":bindata", $fp, PDO::PARAM_LOB);
$pdo->beginTransaction();
$stmt->execute();
$pdo->commit();
fclose($fp);
unlink($tmpfilePath);
April 26, 2008
Windows Settings
重たい腰を上げて自宅の適当なWindows(XP)をちゃんとした。
テーマ、スタートメニュー、コントロールパネルをクラシック表示に。
「コントロールパネル」->「ユーザー アカウント」->「ユーザーのログオンやログオフの方法を変更する」で「ようこそ画面を使用する」のチェックを外す。
スタートメニューのヘルプとかログオフとかを消すためにレジストリをいじる。
スタートメニューから終了オプションを消したので、Orchisに追加する。
特殊項目の追加 -> ログオン状態と電源管理
「Windowsの終了」と「再起動」を項目に追加する。
Orchisが落ちて、二度と立ち上がらなくてWindowsを落とせないという不幸な状況に陥った場合はコンソールから終了する。
縦1横4の4画面でCTRL-ALT-1〜4のホットキーを各画面に割り当てる。
キーの割り当てに「窓使いの憂鬱」をインストール。
最低限の設定でわりと十分。
PuTTYごった煮版というのをインストールする。
PuTTY設定 -> 変換
文字コードの設定で「UTF-8/AutoDetect Japanese」を選択。
PuTTY設定 -> セッション
「標準の設定」を選択し『保存』。
Live MessengerがあるのにMessengerがあって、勝手に起動してLive Messengerのほうで「別のところでログイン...」がどうのこうのと迷惑なのでアンインストールする。
スタートメニュー -> ファイル名を指定して実行
下のを貼り付けて『OK』。
新しいバージョンのインストール時に「pgsql」アカウントを作成しようと思ったら既にいるらしい。前のインストール時にランダムなパスワードを振ってしまったので、パスワードが分からず。さらにコントロールパネルのユーザアカウントにも表示されないので非常に迷惑。
コンソールから削除することに。"net user"で確認すると、前の前で作成したと思われる「postgres」ユーザも発見したのでそれも削除。
テーマ、スタートメニュー、コントロールパネルをクラシック表示に。
「コントロールパネル」->「ユーザー アカウント」->「ユーザーのログオンやログオフの方法を変更する」で「ようこそ画面を使用する」のチェックを外す。
スタートメニューのヘルプとかログオフとかを消すためにレジストリをいじる。
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer NoClose REG_DWORD 0x00000001 (1) NoFind REG_DWORD 0x00000001 (1) NoRecentDocsMenu REG_DWORD 0x00000001 (1) NoSMHelp REG_DWORD 0x00000001 (1) StartMenuLogoff REG_DWORD 0x00000001 (1)ランチャに「Orchis」をインストール。
スタートメニューから終了オプションを消したので、Orchisに追加する。
特殊項目の追加 -> ログオン状態と電源管理
「Windowsの終了」と「再起動」を項目に追加する。
Orchisが落ちて、二度と立ち上がらなくてWindowsを落とせないという不幸な状況に陥った場合はコンソールから終了する。
> shutdown -s -t 0仮想デスクトップに「WinDeskWide」をインストール。
縦1横4の4画面でCTRL-ALT-1〜4のホットキーを各画面に割り当てる。
キーの割り当てに「窓使いの憂鬱」をインストール。
最低限の設定でわりと十分。
C:\Documents and Settings\USERDIR\.mayu # 日本語109を英語104に include "109.mayu" include "104on109.mayu" keyseq $WindowClose = A-F4 keymap Global key *IC-C-Space = $ToggleIME # CTRL-SpaceでIME切り替え mod control += 英数 # CapsLockをCTRLに key *英数 = *LControl key C-Q = $WindowClose # CTRL-Qでウィンドウクローズマルチバイト対応のPuTTYをインストール。
PuTTYごった煮版というのをインストールする。
PuTTY設定 -> 変換
文字コードの設定で「UTF-8/AutoDetect Japanese」を選択。
PuTTY設定 -> セッション
「標準の設定」を選択し『保存』。
Live MessengerがあるのにMessengerがあって、勝手に起動してLive Messengerのほうで「別のところでログイン...」がどうのこうのと迷惑なのでアンインストールする。
スタートメニュー -> ファイル名を指定して実行
下のを貼り付けて『OK』。
RunDll32 advpack.dll,LaunchINFSection %windir%\INF\msmsgs.inf,BLC.RemovePostgreSQLの最新を入れようと思い、古いバージョンをアンインストール。
新しいバージョンのインストール時に「pgsql」アカウントを作成しようと思ったら既にいるらしい。前のインストール時にランダムなパスワードを振ってしまったので、パスワードが分からず。さらにコントロールパネルのユーザアカウントにも表示されないので非常に迷惑。
コンソールから削除することに。"net user"で確認すると、前の前で作成したと思われる「postgres」ユーザも発見したのでそれも削除。
> net user pgsql /delete > net user postgres /delete
April 23, 2008
Synergy
最近なぜかwindowsをよく使うので、synergyでlinux(fedora)とキーボートとマウスを共有することにした。
windowsをプライマリとする。
"http://www.snapfiles.com/get/synergy.html"からSynergyInstaller-1.3.1.exeをダウンロードし、インストールする。
Synergyを立ち上げ、「Share this computer's keyborad and mouse」を選択し、「Configure」ボタンから設定をする。
Screensの「+」ボタンを押し、Screen Nameにフルコンピュータ名を入力し追加する。フルコンピュータ名はコントロールパネル->システム->コンピュータ名で見れる。次にlinuxのIPをScreen Nameに入力し、追加する。
次にlinksの設定をする。
マシンは、windowsが右手、linuxが左手とする。
windowsのフルコンピュータ名が「mywindows」、linuxのIPが「192.168.0.10」とする。
以下のように2つlinkを設定する。
「Start」からSynergyをスタートさせる。
FedoraでのSynergyのインストール。
windowsをプライマリとする。
"http://www.snapfiles.com/get/synergy.html"からSynergyInstaller-1.3.1.exeをダウンロードし、インストールする。
Synergyを立ち上げ、「Share this computer's keyborad and mouse」を選択し、「Configure」ボタンから設定をする。
Screensの「+」ボタンを押し、Screen Nameにフルコンピュータ名を入力し追加する。フルコンピュータ名はコントロールパネル->システム->コンピュータ名で見れる。次にlinuxのIPをScreen Nameに入力し、追加する。
次にlinksの設定をする。
マシンは、windowsが右手、linuxが左手とする。
windowsのフルコンピュータ名が「mywindows」、linuxのIPが「192.168.0.10」とする。
以下のように2つlinkを設定する。
1. [0]to[100]% of the [right] of [192.168.0.20] goes to [0] to [100]% of [mywindows] 2. [0]to[100]% of the [left] of [mywindows] goes to [0] to [100]% of [192.168.0.20]これで、windowsの左側からlinuxの右側へ、linuxの右側からwindowsの左側へマウスを移動できるようになる。
「Start」からSynergyをスタートさせる。
FedoraでのSynergyのインストール。
$ yum install -y senergySynergy Clientを立ち上げる。
$ synergyc [windowsのIP]
April 22, 2008
PDO_MYSQL::lastInsertId()
トランザクション内(begin〜commit)でINSERTされたデータの連番を取得する場合、commitの前にlastInsertId()をコールする必要がある。そうしないと"0"が返される。
CREATE TABLE test ( id INTEGER PRIMARY KEY AUTO_INCREMENT, name VARCHAR(24) NOT NULL )
$pdo = new PDO("mysql:host=localhost;dbname=testdb", "root", "");
$stmt = $pdo->prepare("INSERT INTO test(name) VALUES(:name)");
$stmt->bindValue(":name", "somename");
$pdo->beginTransaction();
$pdo->execute();
$pdo->lastInsertId(); // last id
$pdo->commit();
$pdo->lastInsertId(); // "0"
commitの後でも、LAST_INSERT_ID()関数なら取得できる。
$stmt = $pdo->prepare("SELECT LAST_INSERT_ID() AS id");
$stmt->execute();
$row = $stmt->fetch(PDO_::FETCH_ASSOC);
$row["id"] // last id
April 21, 2008
April 20, 2008
PHP & Oracle 10g XE
Windows & PHP & Oracle 10g XE
Oracleを'C:\Oracle'にインストールする。
Oracle Instant Client(instantclient-basic-win32-10.2.0.3-20061115.zip)をダウンロードし、展開する。
C:\Oracle\instantclientフォルダを作成する。
展開したフォルダ内のoraociei10.dll、orannzsbb10.dll、oci.dllの3つのファイルを、作成したinstantclientフォルダにコピーする。
C:\Oracle\app\oracle\product\10.2.0\server\NETWORK\ADMIN\tnsnames.oraを作成したinstantclientフォルダにコピーする。
環境変数(コントロールパネル->システム->詳細設定->環境変数)の設定でinstantclientフォルダへのパスをPATHの先頭に追加する。
ユーザ環境変数の「新規」でNLS_LANG変数を作成し、値を'Japanese_Japan.AL32UTF8'にする。
また、TNS_ADMIN変数を作成し、値を'C:\Oracle\instantclient'にする。
php.iniでOCI8をロードする。
Oracleを'C:\Oracle'にインストールする。
Oracle Instant Client(instantclient-basic-win32-10.2.0.3-20061115.zip)をダウンロードし、展開する。
C:\Oracle\instantclientフォルダを作成する。
展開したフォルダ内のoraociei10.dll、orannzsbb10.dll、oci.dllの3つのファイルを、作成したinstantclientフォルダにコピーする。
C:\Oracle\app\oracle\product\10.2.0\server\NETWORK\ADMIN\tnsnames.oraを作成したinstantclientフォルダにコピーする。
環境変数(コントロールパネル->システム->詳細設定->環境変数)の設定でinstantclientフォルダへのパスをPATHの先頭に追加する。
ユーザ環境変数の「新規」でNLS_LANG変数を作成し、値を'Japanese_Japan.AL32UTF8'にする。
また、TNS_ADMIN変数を作成し、値を'C:\Oracle\instantclient'にする。
php.iniでOCI8をロードする。
extension=php_oci8.dll接続する。
$conn = oci_connect("USERNAME", "PASSWORD", "//localhost/XE", "AL32UTF8");
April 19, 2008
PHP & SQL Server 2005 XE
Windows & PHP & SQL Server 2005 XE
Microsoftから下記のものをダウンロード&インストール。
・SQL Server
SQL Server 2005 Express Edition Service Pack 1
・管理ツール
SQL Server Management Studio Express
SQL Serverのインストール時の「認証モード」の選択では、接続ユーザをWindowsアカウントと関係なくするため「混合モード」を選択する。
照合順序の設定では補助文字(サロゲートペアによる文字)を扱えるようにするため、「Japanese_90」を選択する。また、普段使用するデータベースに合わせ、「大文字と小文字を区別する」「アクセントを区別する」「かなを区別する」「文字幅を区別する」にチェックを入れる。これは'Japanese_90_CS_AS_KS_WS'となる。CSとかASとかは以下の通り。
・CI => Case Insensitive
大文字・小文字を区別しない。
・CS => Case Sensitive
大文字・小文字を区別する。
・AI => Accent Insensitive
濁音などを区別しない。(「ハ」=「バ」=「パ」)
・AS => Accent Sensitive
濁音などを区別する。
・KS => Kana Sensitive
ひらがなとカタカナを区別する。
・WS => Width Sensitive
文字幅(全角・半角)を区別する。
・BIN => Binary
すべて区別する。
管理ツールを起動する。
起動時に「ファイル C:\WINDOWS\〜\...\mscorlib.tlbを読み込むことができませんでした。」のようなメッセージが出る場合はレジストリを編集する。
オブジェクトエクスプローラの「セキュリティ」->「ログイン」を右クリックし、新しいログインをクリック。
ログイン名'develop'を入力し「SQL Server認証」を選択しパスワード'develop'を入力。「パスワードポリシーを適用する」のチェックを外し、「規定の言語」をJapaneseにする。
オブジェクトエクスプローラの「データベース」を右クリックし、新しいデータベースをクリック。
データベース名'test'を入力し、所有者を先程作成した'develop'にする。
オブジェクトエクスプローラの「セキュリティ」->「ログイン」->「develop」を右クリックし、プロパティをクリック。
規定のデータベースを先程作成した'test'にする。
・SQL Serverとphpの連携。
デフォルトの設定(php.ini)だと4096バイトより大きいデータがphpから書き込めないので、そのサイズを大きくしておく。また、通常のDATETIME形式で取得できるようにするための設定もする。
接続にPDO_ODBC拡張を使用する場合。
Microsoftから下記のものをダウンロード&インストール。
・SQL Server
SQL Server 2005 Express Edition Service Pack 1
・管理ツール
SQL Server Management Studio Express
SQL Serverのインストール時の「認証モード」の選択では、接続ユーザをWindowsアカウントと関係なくするため「混合モード」を選択する。
照合順序の設定では補助文字(サロゲートペアによる文字)を扱えるようにするため、「Japanese_90」を選択する。また、普段使用するデータベースに合わせ、「大文字と小文字を区別する」「アクセントを区別する」「かなを区別する」「文字幅を区別する」にチェックを入れる。これは'Japanese_90_CS_AS_KS_WS'となる。CSとかASとかは以下の通り。
・CI => Case Insensitive
大文字・小文字を区別しない。
・CS => Case Sensitive
大文字・小文字を区別する。
・AI => Accent Insensitive
濁音などを区別しない。(「ハ」=「バ」=「パ」)
・AS => Accent Sensitive
濁音などを区別する。
・KS => Kana Sensitive
ひらがなとカタカナを区別する。
・WS => Width Sensitive
文字幅(全角・半角)を区別する。
・BIN => Binary
すべて区別する。
管理ツールを起動する。
起動時に「ファイル C:\WINDOWS\〜\...\mscorlib.tlbを読み込むことができませんでした。」のようなメッセージが出る場合はレジストリを編集する。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\90\Tools\ShellSEM\TlbAutoRepair\mscorlib.tlb TlbPathのパス(データ)の%CLRVERSION%を'v2.0.50727'に変更する管理ツールを起動しSQL Server認証を選択し、saアカウントで接続する。
オブジェクトエクスプローラの「セキュリティ」->「ログイン」を右クリックし、新しいログインをクリック。
ログイン名'develop'を入力し「SQL Server認証」を選択しパスワード'develop'を入力。「パスワードポリシーを適用する」のチェックを外し、「規定の言語」をJapaneseにする。
オブジェクトエクスプローラの「データベース」を右クリックし、新しいデータベースをクリック。
データベース名'test'を入力し、所有者を先程作成した'develop'にする。
オブジェクトエクスプローラの「セキュリティ」->「ログイン」->「develop」を右クリックし、プロパティをクリック。
規定のデータベースを先程作成した'test'にする。
・SQL Serverとphpの連携。
デフォルトの設定(php.ini)だと4096バイトより大きいデータがphpから書き込めないので、そのサイズを大きくしておく。また、通常のDATETIME形式で取得できるようにするための設定もする。
mssql.textlimit = 2147483647 mssql.textsize = 2147483647 mssql.datetimeconvert = Off接続にmssql拡張を使用する場合。
extension=php_mssql.dll
$conn = mssql_connect(".\SQLEXPRESS", "develop", "develop");
dllがロードできない場合はコンソールでphpを実行してみて、「ntwdblib.dllが見つからないため〜」のようなメッセージが出るなら、http://www.webzila.com/からntwdblib.dllをダウンロードしC:\WINDOWS\system32に置く。接続にPDO_ODBC拡張を使用する場合。
extension=php_pdo_odbc.dll
$pdo = new PDO("odbc:Driver={SQL Native Client};Server=.\SQLEXPRESS;Database=test;Uid=develop;Pwd=develop;");
April 17, 2008
mail function
phpでメール送信。毎回微妙に忘れるのでメモ。
Message-Idのドメインは引けるものであること。
また、パラメータのアドレスはメールが届くものであること。
Message-Idのドメインは引けるものであること。
また、パラメータのアドレスはメールが届くものであること。
function sendmail($from, $to, $subject, $body)
{
$headers = "MIME-Version: 1.0\r\n"
. "Content-Transfer-Encoding: 7bit\r\n"
. "Content-Type: text/plain; charset=ISO-2022-JP\r\n"
. "Message-Id: <" . md5(uniqid(microtime())) . ">@mail.example.com\r\n"
. "From: $from";
$parameter = "-f admin@example.com";
$subject = mb_encode_mimeheader($subject, "ISO-2022-JP");
$body = mb_convert_encoding($body, "ISO-2022-JP");
mail($to, $subject, $body, $headers, $parameter);
}
エンベロープのsenderアドレスを設定するために第5引数(additional_parameters)を指定すること。しかし、X-Warningヘッダが付加されてしまうので、それを回避するためにpostfixの設定が必要。これをしないとスパム扱いされたりする。vi /path/to/main.cf ... header_checks = regexp:/path/to/header_checks ...
vi /path/to/header_checks ... /^X-Authentication-Warning:/ IGNORE