PreparedなINSERT文を簡単に作る方法

PHPでWebアプリケーションなどを開発していて、SQL文を発行する際に、セキュア面や利便性などから、ADODBPDOなどを用いて、Prepared Statementを使うSQLを書くこともあると思います。

その際、特にINSERT文などはカラムの数だけVALUESの中に ? が並ぶことになるかと思います。


-- 例:
INSERT INTO
`persons` (`id`, `name`, 'age`, `birthday`, `mailaddress`, `phone`, `zipcode`, `address`)
VALUES (?, ?, ?, ?, ?, ?, ?, ?);


このとき、 ? がひたすら並んでいるだけとなると非常に見づらく、INSERTする情報が多くなってくると、指定したカラム数と VALUESの ? の数が一致せず、

Number of variables doesn't match number of parameters in prepared statement

といったエラーに遭遇したことが一度はあるかと思います。
特に、プログラムの改修をする際などは、カラム名だけ追加して、うっかり VALUESの ? だけ追加のし忘れなどをしてしまうことなんかも。。。

そこで、Prepared Statementを作る際のINSERT文のSQLを簡単で分かりやすくしたいと思います。


< ?php
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';

try {
$db = new PDO($dsn, $user, $password);

// INSET対象となるカラム名を指定
$columns = array(
'id',
'name',
'age',
'birthday',
'mailaddress',
'phone',
'zipcode',
'address',
);

$binds = array(
1 => 'anon',
2 => 'anon',
3 => '25',
4 => '1984-05-02',
5 => 'root@example.com',
6 => '03-xxxx-xxxx',
7 => 'xxxxxx',
8 => 'Tokyo',
);

$sql = 'INSERT INTO persons '
. implode(', ', $columns)
. ') VALUES ('
. implode(', ', array_fill(0, count($columns), '?'))
. ')'
;

/*
// またはテーブル名やカラム名を明示的にクオートする場合はこちら
$sql = 'INSERT INTO `persons` '
. '`' . implode('`, `', $columns) . '`'
. ') VALUES ('
. implode(', ', array_fill(0, count($columns), '?'))
;
*/

$stmt = $db->prepare($sql);

foreach($binds as $key => $value){
$stmt->bindValue($key, $value);
}

return $stmt->execute();

} catch (Exception $e) {
error_log('[' . get_class($e) . '] ' . $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine());
}


要点は、 $columnsという配列にカラム名を配列で持たせ、Prepared INSERT文を発行する際に、implode()関数でそのカラム名をカンマ区切りで連結、VALUESの ? は array_fill()関数で、カラム名の配列の値の数だけ ? で埋めた配列を作成し、さらにそれをimplode()関数で連結していく。

というだけです。

バインドの個所は今回手抜きにしてしまいました。
本当はバインドも同じようにもう少し見直せばもっと分かりやすく、簡潔にできると思うのですが、
いい書き方が浮かびませんでした。。。

Windows 7 をアンインストールしてみた

先日発売された Windows 7 Professional を早速インストールし、その直後にアンインストールしてみました。

…というのも、インストール時に、複数ある物理ドライブのうち、本来インストールしたかったドライブとは別のドライブ(データ領域として利用していたところ)にインストールしてしまったためです。。。

で、今回は早速のアンインストールを実施してみました。


まずは ブートマネージャのリストからの削除。

Windows 7 RC を削除する方法:bcdedit - Windows Vista とのデュアルブート
http://seawind.air-nifty.com/day/2009/07/windows-7-rc-bc.html


上記の記事や、ほかにもググるといくつかブートマネージャからの削除方法が既に書かれています。
このあたりはこの通りやればできるので、今回割愛します。


続いて、OS本体のアンインストール(削除)
上記の作業だけだと、OS本体は残ったままなのでOSも消しましょう。

方法についてはマイクロソフトからも

Windows 7 のアンインストール方法
http://support.microsoft.com/kb/971762/ja

というアナウンスがされています。
今回の場合は、上記の記述の中の「状況 2」のケースに近いのですが、残念ながらデータ領域であったため、「空の領域」ではなかったんですね。
で、データの量も多いため、データを別の領域に待避して、クリーンインストールとかフォーマットとかはなるべくしたくないんです。。。


そこで Windows の削除です。
今回のインストールで作成された領域は、ドライブ直下にある

  • Program Files

  • Program Files (x86)

  • ProgramData

  • Windows

  • Windows.old

  • Users



のみ。("Program Files (x86)"は64ビット版のみ)

これらを削除したいのですが、通常通りに削除しようとすると、OSの権限などによって削除することができません。
(たとえ起動中のOS領域とは別のところにあっても)

そこで、いくつかの手順を踏んでがんばって削除してみました。


root ユーザで rm -rf / してみた

Linux OS環境にて、絶対実行してはいけないけど、一度でいいからしてみたい。
rm -rf / を実行してみた。

rm -rf とは…
rm とは removeの略で、取り除く、除去、削除といった意味。ここではファイルを削除するコマンドとなる。

-rf とは、rm コマンドのオプションで、 -r が Recursive の頭文字で「再帰的に」を表す。この場合、再帰的にファイル(とディレクトリ)を削除する。

-f は Force の頭文字で、「強制的に」を表す。通常はファイルを消す際に、消していい?と確認されるが、このオプションを付けると有無をいわず削除を行う。

最後の / は削除の対象となるパス。 / はUnixにシステムにおけるルートパス。Windowsでいう C:\ を表すのと同じようなもの。

つまり、このコマンドの指す意味は、 / (ルートパス)以下の全てのファイルとディレクトリを強制的に削除するという恐ろしいコマンド。

通常は、一般ユーザで実行しても、ファイルの所有権限などの制限により、システム的に必要なファイルが消えることがないように設計、設定されているが、今回はUnixシステム上最高特権となる root (Windowsで言うとAdministrator相当)ユーザでこれを実行してみる。


php の memory_limit の制限

ネタメモ:
php の memory_limit は K、M、Gの単位で設定できる。
メモリをいくらか使う処理の中で、処理に余裕を持たせるため、memory_limit を 2G として設定した。
2G にした理由は ini_set('memory_limit', '1G'); と指定したにもかかわらず、ini_set() の設定が有効に働かず、デフォルトの 128MB で動作していたため。

2G に指定した際の php の設定情報では
$ php -i | grep memory_limit
memory_limit => 2G => 2G

となっていた。
プログラムを実行しようとすると
PHP Fatal error: Allowed memory size of 262144 bytes exhausted at /usr/local/src/php-5.2.6/Zend/zend_opcode.c:48 (tried to allocate 311296 bytes) in /home/user/bin/foo.php on line 476
で止まる。
プログラムの476行目を見ても何の変哲もないただの処理。 if( $value === FALSE) といった処理。

仕舞いには
$ php -l /home/user/bin/foo.php
を実行しただけで
Error parsing /home/user/bin/foo.php
を返し、エラーログには同様のエラーを表示していた。

現象が掴めないままいると、memory_limit に指定できるメモリ上限は 1G までであることが判明。
それ以上を指定しても、phpのシステム内で決定されている最小メモリ数(256K)に自動的に割り当てられるということらしい。

ちなみに 使用していた PHP のバージョンは PHP 5.2.6 (cli)

iPhone OS 3.0 提供開始!

ついに一般向けアップデート提供開始来ました!

その内容は既に発表済みでありますが、以下のものとなっているようです。


iPhone OS 3.0 ソフトウェア・アップデート

このアップデートには、以下の機能を含む、100 以上の新機能が含まれています:

• カット、コピー&ペースト、シェイクによる取り消し
• 主要アプリケーションにおける横表示キーボード
• SMS/MMS アプリケーションの強化
- 写真、連絡先、オーディオファイル、および位置情報を MMS で送受信*
- メッセージを 1 つずつ、または複数まとめて転送および削除
• メール、カレンダー、メモ、および iPod 内の検索機能を追加
• iPhone 全体を Spotlight 検索
• カレンダーで CalDAV およびカレンダーの登録をサポート
• Safari の改良
- パフォーマンス
- HTML 5 をサポート
- オーディオおよびビデオの HTTP ストリーミング
- ユーザ名とパスワードの自動入力
• 新しいボイスメモアプリケーション
• Mac または PC と、iTunes 経由でメモを同期
• USB および Bluetooth 経由でインターネットテザリング*
• iTunes Store からムービー、テレビ番組、オーディオブックをブラウズおよびダウンロード**
• ステレオ Bluetooth***
• Wi-Fi 自動ログイン
• 株価アプリケーションの強化
• アプリケーション、ミュージック、ムービー、およびテレビ番組のより詳細なペアレンタルコントロールオプション
• iTunes アカウントの作成およびログイン**
• YouTube アカウントのログインおよび、登録チャンネル、レート、お気に入りへのアクセス**
• シェイクでシャッフル
• 新しい言語、辞書、およびキーボード
• MobileMe で利用可能な“iPhone を探す”および“リモートワイプ”(登録が必要)**
• より多くの Exchange ポリシーをサポート
• Exchange のミーティングの招待を作成および送信
• サーバ上のメールを検索(Exchange Server 2007 およびサポートされている IMAP サーバ)
• LDAP カンパニーディレクトリを検索
• VPN オンデマンドおよび VPN プロキシをサポート
• 暗号化された構成プロファイル
• 暗号化された iTunes バックアップ
• 以下を含む、1,000 におよぶデベロッパ API:
- アプリケーション内での購入
- Apple Push Notification Service(プッシュ通知サービス)
- アクセサリサポート
- ピアツーピア接続
- 地図の埋め込み
- iPod ライブラリのアクセス
• 不具合の修正

このソフトウェア・アップデートと互換性のある製品:
• iPhone
• iPhone 3G
• iPhone 3G S

* iPhone 3G および iPhone 3G S のみ対応。お使いのワイヤレスプロバイダによるサポートも必要。
** 一部の地域や言語では利用できません。
*** iPhone 3G および iPhone 3G S のみ対応。

機能の説明と詳しい手順については、次の Web サイトでお使いの iPhone のユーザガイドを参照してください:
<http://www.apple.com/jp/support/manuals/iphone>

iPhone について詳しくは、次の Web サイトを参照してください:
<http://www.apple.com/jp/iphone>

お使いの iPhone の問題を解決する、または追加のサポート情報を確認するには、次の Web サイトを参照してください:
<http://www.apple.com/jp/support/iphone>

このアップデートのセキュリティに関する内容について詳しくは、次の Web サイトにアクセスしてください:
<http://support.apple.com/kb/HT1222?viewlocale=ja_JP>


目玉はコピー&ペースト、MMSサポート、Push Notification Service (アプリ経由でのポップアップ通知)、 メモとメールでのランドスケープ入力対応、Spotlight検索、テザリング機能などです。
テザリングについては残念ながら日本国内においてはソフトバンクが現時点で提供の予定なしとのことですが、MMSについては既存の携帯電話サービス同様に提供されるようで、メールアドレスも @softbank.ne.jp のアドレスを付与されるようです。
さり気なく Wi-Fi 自動ログイン機能や、オートフィル機能、YouTubeのアカウント連携、Bluetoothのプロファイルの追加などなど、便利そうな更新が含まれています。

EeePC 1000HE購入後レビュー

昨日(4月4日)、昨日発売したばかりの ASUS EeePC 1000HE を買ってきました。

というわけで開封の様子から…。








まず見た目。デザインなど。
今回はカラーはシルバーを購入。今までのEeePCシリーズは基本的に白か黒しかなかったけれど、今回のものは日本限定でシルバーが加わっています。
限定だからというわけではないのだけれど、シルバーではちょっと見た目がアルミ風なものとなっていて、見た目の重量感が増して、いい感じ。
それと、今までのEeePCは、液晶のフレーム部分がつや消しのプラスチックだったりして、見た目的にどうも安っぽさが抜けないため(実際安いのだけど)それでEeePCはあまり好きではなかったというのが正直合った。
けど、今回のはどれもつやありのフレームになったし、本体も全体的に変わって、今までに比べて高級感が増してるのがよかった。

ただ、シルバーはよく見ると実際にはアルミではなく、"アルミ風"な塗装が施されているだけ。実際にアルミ素材使ってたらもと高くなってるか。

キータッチについてはキーの感覚が広くなって、ボタンとボタンの間が空いているため、文字の打ち間違いも軽減できると思う。
ただ、キータッチが荒い(力強い)人が使うと、キーボードが若干ゆがみそう。(当たり前か)

少々気にしていたものとして、YouTubeなどの動画サイトを見た際に動画がカクカクしてしまわないかということがあったのだけれど、HD画質動画を見ても全く問題ないレベルだったのでここも満足。
ただ、さすがにニコニコはコメントが大量に流れてくると若干カク付き始めるかな。


そうそうあと、今回はOfficeなしモデルを買ったけど、後から別途購入済みのOffice 2007を入れたりもしました。
Officeについてはまだちゃんと使用していないため、使用感のレビューは後ほど書けたら書きます。


あとはメモリー。環境を作っていっていろいろと入れていって、デスクトップとほぼ同じくらいまでの環境を整えてみましたが、それだけでメモリーを760MBほど使用する状態にまでしてました。
なので使っていないIMなどを終了させてみたもののまだ530MBほど使用している。
やはりFirefoxのメモリー消費量が激しいか。と思ってみたものの、Firefox自体はそのうちの116MBしか使ってなかった。
ということは別の何かが残り400MB使っていると思うのだけど、それ以外に大量に目盛りを消費しているものはプロセス上からは確認することが出来なかった。

なので余裕を見越してメモリーはやっぱり2GBに転載しておいた方がいいかも。


というわけでざっくりなレビューもどきを書いてみました。
バッテリーの持ちなどはまだ体感的なものは確認できていないため、また書けそうなものがあったら追記してみたいと思います。

ウェブページをリニューアルしました+近況

かなり久しぶりのブログ更新です。 タイトルの通りですが、約6年ぶりにウェブページを刷新しました。 ウェブページを更新しました 前回は2018年頃に、Zend Frameworkをベースに作っていたのをLaravelベースのサーバーに置き換え、AppEngineで動かす形にしていま...