April 2007

Entries Title

Dreamhost で php.ini を設定する方法

Date
2007-04-28 (Sat)
Category
php

追記事項があります。

Dreamhost には Wiki があって、たいていの情報はそこに集まっています。php.ini に関しては、以前にコメント欄で教えてもらって以来、ずっと使っていたんですが、今回もう一度自分で設定する機会があったので、まとめ直しておきます。前述の Wiki には、2つ項目があってだいたい同じような事が書いてあります。それらの訂正なども含めて。あと あなたの知らない PHP 5つの秘密。 なんて記事を訳した手前、PHP4 に関しては、スルーしておきます。

wiki.dreamhost.com : Custom PHP.ini
wiki.dreamhost.com : PHP.ini

手順

自分の設定を書いた php.ini を使いたいドメインの document root に cgi-bin というディレクトリを作ります。以下では dreamhost というログインネームで bash を使っていて、dreamhost.com を運用していると仮定します。

$ pwd
/home/dreamhost
$ cd dreamhost.com
$ mkdir cgi-bin

次に php の cgi バイナリと php.ini ファイルをコピーします。

$ cp /dh/cgi-system/php5.cgi $HOME/dreamhost.com/cgi-bin/php5.cgi
$ cp /etc/php5/cgi/php.ini $HOME/dreamhost.com/cgi-bin/php.ini

ここで php.ini を更新しましょう。FastCGI 経由で起動されるとはいえ、php のスクリプトが起動されるたびに読み込まれてるはず、なので、短い方がいいと思います(が、どうなのだろう?また今度調べましょう)。僕はコメントなどは全部削除して、5KB くらいにしました。

ここで、.htaccess ファイルを作成して、document root 以下にある .php ファイルでは、全てこの cgi-bin 以下にある php バイナリを経由するようにします。

$ pwd
/home/dreamhost/dreamhost.com
$ vi .htaccess

.htaccess

AddHandler php-cgi .php
Action php-cgi /cgi-bin/php5.cgi

ここで5分くらいハマりました。僕はものぐさなので、cp するとき php5.cgi の名前を php.cgi に変えませんでした(Terminal では tab キーで directory 名の補完をしてしまうので)。上記の wiki にある .htaccess をコピペしたら

Not Found
The requested URL /cgi-bin/php.cgi/php/script.php was not found on this server.

と、404 がでてしまいます。なぜかというと、Action の deploy 先が php5.cgi ではなく php.cgi だったからです。というわけで、上記の .htaccess では php5.cgi としておきました。

次に permission の設定を正しくします。

$ chmod 644 $HOME/dreamhost.com/.htaccess
$ chmod 755 $HOME/dreamhost.com/cgi-bin
$ chmod 700 $HOME/dreamhost.com/cgi-bin/php5.cgi
$ chmod 600 $HOME/dreamhost.com/cgi-bin/php.ini

上記 wiki よりだいぶ厳しい permission ですが、dreamhost では CGI がユーザ権限で起動しているので(というか CGI がユーザ権限で起動しているのか)動きます。

<?php
echo `whoami`;
?>

とかすれば、どのユーザで実行されているかわかるはず。

最後に、php のバイナリを dreamhost で使われている最新に追随させるためのスクリプトを書きましょう。

$ pwd
/home/dreamhost/dreamhost.com
$ cd ..
$ mkdir bin
$ vi bin/php-copy

php-copy

#!/bin/sh
CGIFILE="$HOME/dreamhost.com/cgi-bin/php.cgi"
rsync -a /dh/cgi-system/php5.cgi "$CGIFILE"

wiki.dreamhost.com : PHP.ini では .ini をいちいち正規表現で処理していますが、それはアフォらしいので省きました。っつぅか、php.ini はそんなに書き換えないでしょう。あとは 上記ファイルを cron で回します。

$ crontab -e
@weekly /home/dreamhost/bin/php-copy

あえてもう一個ハマりどころを上げるとすると、僕は error を別ファイルに書き出して、display_errors は off にする人なので、error_log に指定したファイルを作っておく事でしょうか。permission の所に書いた通り、php はユーザ権限で起動しているので、chmod 600 php-error.log でいいはずです。それとその log は document root より上に置くべきということも。

追記 on June 3, 2007:ここに挙げた設定に加えて、Dreamhost で php.ini を設定する方法 続き に書いた内容ももれなくやっておいた方が、セキュリティ上好ましいでしょう。

How-to: Linux talks to Microsoft SQL Server by PHP Data Objects (PDO) その2

Date
2007-04-18 (Wed)
Category
php

How-to: Linux talks to Microsoft SQL Server by PHP Data Objects (PDO) その2

前回に引き続き、Linux 上の PHP から、PDO を使って、Micrsoft SQL server に接続する方法を解説します。

unixODBC と FreeTDS の設定

Relationship between conf files

自分でやっているときは、異常にワケがわからなくて、いらだっていた設定ファイルの関係なんですが、わかってみて、絵にしてみたら、全然複雑じゃないですね。実際 FreeTDS のユーザーガイドをしっかり読めば…少なくとも 3. Install FreeTDS4. Preparing ODBC を読んでおけばどうなっているかは理解できるはずです。実際の設定内容は以下の通り。

odbcinst.ini

[FreeTDS]
Driver = /usr/local/lib/libtdsodbc.so

odbc.ini

[ODBC Data Sources]
MY_DSN_NAME = MSSQL

[MY_DSN_NAME]
Driver = /usr/local/lib/libtdsodbc.so
Description = MSSQL
Trace = No
Servername = MY_HOST_NAME
Database = MY_DB_NAME

[Default]
Driver = /usr/local/lib/libtdsodbc.so

freetds.conf

[MY_HOST_NAME]
host = MY_HOST_IP
port = MY_HOST_PORT_NO
tds version = 7.0

これらの設定は、unixODBC パッケージに付属の odbcinst コマンドで確認できます。

# odbcinst -q -d
[FreeTDS]
# odbcinst -q -s [MY_DSN_NAME] [Default]

ここで、まずは FreeTDS パッケージに付属の tsql コマンドを使って、FreeTDS の接続がうまく行くか試してみましょう。

# tsql -S MY_HOST_NAME -U USERNAME -P PASSWORD
locale is "en_US.UTF-8"
locale charset is "UTF-8"
1>

1> 以降は、改行を押すたびに 2> 3> と数が増えますが、それ以上何の反応もないです。1> も出ない/エラーが出る、ということは、サーバと接続できていません。サーバーの IP がリーチャブルかとか、Port があってるかとか試してみてください。IP と Port に関しては telnet コマンドで

#telnet MY_HOST_IP MY_HOST_PORT_NO
Trying MY_HOST_IP...
Connected to MY_HOST_IP.
Escape character is '^]'.

とか出れば、リーチャブルなのでしょう。あとは TDS のバージョンを変えてみるとか。

tsql がうまく言ったら今度はいよいよ実際に SQL を投げてみましょう。unixODBC パッケージに isql というコマンドがあり、これは SQL のインタラクティヴシェルです。

# isql -v MY_DSN_NAME USERNAME PASSWORD
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL>

SQL 文を発行してみて、内容を確認してみてください。もし connected と出ない場合は、おそらく DSN の設定がおかしいです。isql を -v で起動すると verbose モードで、いろいろエラーが出ていると思うので、内容をググって見てください。7. Troubleshooting の内容も役に立つでしょう。

PDO のインストール

PDO ではクラスメソッドが統一されていて、どのデータベースを使っていようと、同じ操作感を提供する、というのが売りです。で、違いはインスタンス作成時の DSN の呼び方で、実際にどのクラスを使うのかを分けます。僕は正直ってここにハマっていました。ODBC を使っているので、てっきり ODBC だと思い込み、ひたすら PDO_ODBC をビルド/インストールしては動かない、なんでだろう?を繰り返していました。6. How to get what works with it working:: PHP にも ODBC って書いてあるし(db-lib とも書いてありますけど、まぁ焦っているとわからないものです)。

大きな声で言っておきます。PHP で FreeTDS を扱えるのは PDO_DBLIB です。っつぅかね、マニュアルにもでかでかと XCI. Microsoft SQL Server および Sybase 関数 (PDO_DBLIB) って書いてあるしね…やっぱ RT*M だね。。。

でももし PDO が shared module じゃなくて、static link だったら、この PDO の設定を変えるたびに PHP 全体を再ビルドしなくちゃいけなかったわけで、shared module にしておいてよかったよかった。やり方自体は全然簡単で、PHP 本体の ./configure の時に option で --disable-pdo を一言追加。後は pecl コマンドを使って、pecl install PDO_DRIVER とかする。

今回は設定を一応確認しながらやりたかったので、pecl のやってる事を手動でやってみました。

  1. PECL サイトにて PDO_DBLIB パッケージのアーカイヴをダウンロード
  2. アーカイヴを展開して ( tar -zxvf PDO_DBLIB-1.0.tgz ) PDO_DBLIG のディレクトリに移動
  3. phpize コマンドを実行
  4. ./configure コマンドを実行
  5. make && make install
  6. すると no-debug-XXXXXXXXX とかいうディレクトリ名で pdo_dblib.so とかいうファイルが出来ているはずなので、extension_dir でなければ、extension_dir に移動させる。
  7. php.ini の中にある Dynamic Extensions 項に extension=php_dblib.so を一行追加。extension_dir からの相対パスになるのも注意
  8. Apache を再起動して、p h p i n f o () を確認する

僕が確認している事項

  • PDO で FreeTDS を使用する DSN suffix (DSN接頭辞) は今の所 dblib です。マニュアル:PDO_DBLIB DSN には以下のようにありますが、今の所実装とは異なります。
    PDO_DBLIB が FreeTDS ライブラリに対してリンクされている場合は DSN 接頭辞は sybase: です。 Microsoft SQL Server ライブラリに対してリンクされている場合は mssql:、それ以外の DB-lib に対してリンクされている場合は dblib: となります。
  • そして DSN 名による接続はできません。以下のように必ず host:port を使う必要があります。
    $PDO = new PDO('dblib:host=IP_ADDRESS:PORT_NO;dbname=DB_NAME','USERNAME','PASSWORD');
    上記マニュアルページのコメント欄にありますが、Windows システムでは IP_ADDRESS:PORT_NO という指定は出来ず IP_ADDRESS,PORT_NO となるらしいですが、僕は試してません。
  • datetime 型 の値が結構変わってしまうかもしれません。おそらく FreeTDS の locales.conf がやってる部分だと思うのだけれど、まだよくわかってません。

まとめ

以上で PHP の PDO を使って FreeTDS 経由で、MSSQL サーバーに接続する事が出来ました。PDO のマニュアルもしっかり整備されてないし、実装が変わる可能性もいっぱいありそうですが、FreeTDS 自体の提供する接続は結構安定しているし、使えそうだと思います。

あとは PDO_ODBC だと思い込んで、コンパイルして PHP が無言で Segment Fault を頻発したときは血の気が引きましたが、要するにマニュアルとソースを嫁!という普通の事を再確認しました。

How-to: Linux talks to Microsoft SQL Server by PHP Data Objects (PDO) その1

Date
2007-04-17 (Tue)
Category
php

Linux で走る PHP のアプリケーションサーバーから Microsoft SQL Server (以下 MSSQL ) に接続したい機会って、あまりないんでしょうか? Web で探しても余り出てこなかったので、メモしておきます。

PHP で今や PHP Data Objects (以下 PDO) を使わない Database 開発はあり得ない、とまでは言わないけど、新しく始めるのに PDO を使わない手はないと思います。ので、今回は背景の説明で力つきましたが、次回にて Linux 上で走る PHP から PDO を使って MSSQL に接続する方法を解説します。加えて PDO を共有モジュールとして組み込んでおけば、こういう時にデータベースドライバを組み込めばいいだけで簡単に始められるので、pecl コマンドを使った PDO のコンパイルも簡単に説明します。

必要なもの

MSSQL サーバー (DB)
TCP 接続を受け付ける設定
ODBC 接続の UID と PWD
Linux サーバー (Application Server)
コンパイルできる環境
PHP5
unixODBC
FreeTDS

まずは使うソフトウェアの説明。以下の図をご覧あれ。

Database Software Chains

Database と通信するソフトウェアは、これらパーツの組み合わせだと思います。一番 Typical なのは、一つのマシンに MySQL と Apache と PHP が一緒に走っていて、開発機だったら Client である Browser も走っているかもしれません。そこでの処理の流れは Browser ⇔ Apache ⇔ PHP ⇔ Database となります。また PHP と Database (は MySQL だと仮定して、そ) の間だけ注目すると PHP ⇔ MySQL 関数 ⇔ MySQL ライブラリ ⇔ unix socket コネクション ⇔ MySQL Server というつながりになります。これが Application と Database が別れたマシンだと、Connection Protocol の部分から、例えば TCP/IP 上を流れる、ということです。

今回、使いたい

Application:
PHP on Linux (CentOS)
Database:
MSSQL on Windows Server 2003

だと、Connection Protocol は ODBC で、Driver は FreeTDS というのを使います。(もちろん他にも選択肢はあります)

unixODBCFreeTDS のインストール

CentOS なので yum を使って unixODBC と unixODBC-devel をインストールしました。正直に言うとソースからのインストールも試みたのですが、Qt ライブラリがないというエラーで ./configure から先に進みませんでした。Web サイトによると Qt は設定用の GUI に必要で、なければ無視して先に進むとあったのですが… 一応 "--witout-x --without-qt-dir --without-qt-libraries --without-qt-programs"とかは試したんですけど。unixODBC-devel は PDO をコンパイルする時に必要になります。

副次的に rpm -qs unixODBC というコマンドで、何処にどのファイルがインストールされたか一目瞭然で、これが後で結構役にたちました。

FreeTDS は自分でビルドしました。./configure --with-opeenssl とだけして、後はそのまま make && make install で /usr/local 以下にインストールされました。

猛烈に眠くなったので、また明日。How-to: Linux talks to Microsoft SQL Server by PHP Data Objects (PDO) その2へ続く。。。

[memo]Twitter on...

Date
2007-04-13 (Fri)
Category
Sticky Memo

5 Question Interview with Twitter Developer Alex Payne によると Twitter って Ruby on Rails なんだそうですね。って、ホントかよ!?

というわけで、調べてみました。Firefox の LiveHTTPHeader で、出てくる Server の名前。ちなみに先にいっておきますが、このエントリはオチなし、多分に正確でない情報を含んでいる可能性があります。

  • BIG-IP
    ロードバランサ
  • Joyent Web(!!)
    この間ちょっこっと書いた、Slingshot の開発もやってるところだね。スゴいな。
  • LiteSpeed
    Static contents の delivery ホストで聞いた事はあったけど、リンク先によると RoR が動くって書いてあるね。実際 Twitter でも assets* というドメイン下で、基本的に .css / .jpg / .png / .ico / .gif など static コンテンツを配信してるみたい。

ところで、要望を何処へ送ればいいのかわからなかったので、とりあえず、Contact の Support からメールを送ってみました。help / FAQ は別ドメインの help.twitter.com となっていて、そこはなんと!! IIS で動いてますな。Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET, PHP/5.2.2-dev だって。

どうやら support はチケットシステムを使っているみたいで、すぐ帰ってきたメールの差出人が twttr.com となってる。へぇ〜。と思って調べると、そこは Server: Apache/2.2.3 (Unix) PHP/5.1.6 SVN/1.4.0 DAV/2 また別のサーバーが走ってる、と。どうも helpspot.com ? とかいうところのサービスを使ってるみたい? でもなんで PHP なんだろ?なんとなく、 screenshots は Joyent の slingshot の違うスキンのように見えるけど…どっちにせよ Ruby は今暑いってことだね。

Apollo on Mac OS X: adt コマンドを使った配布パッケージの作成

Date
2007-04-11 (Wed)
Category
AIR / ActionScript

Apollo を Mac OS X で開発するための記録です。今回は Adobe の sample ページにあるような、.air ファイルの配布パッケージの製作をやってみます。

コマンド実行時 (adl とか adt ) にエラーが出る、という場合は 前回の記事 を参考にしてみてください。

Continue reading

Apollo on Mac OS X: Install(完成版)

Date
2007-04-11 (Wed)
Category
AIR / ActionScript

昨日に引き続き、Apollo を Mac OS X で開発するための記録です。今回はインストールを完了して、(あまりに長くなったので)次エントリで Adobe の sample ページにあるような、.air ファイルの配布パッケージの製作をやってみます。

最初に、この本はダウンロードしましょう。

Apollo:Books:Apollo for Adobe Flex Developers Pocket Guide

僕もやってる事はここに書いてある事です。加えて開発環境 (Flex Builder) を買わないで、無料で何処までできるか、というのがこの記事の目的です。

Continue reading

Install Apollo on Mac OS X (ver. 0)

Date
2007-04-10 (Tue)
Category
Web

そろそろ Apollo でもやってみようか、と思い立ち、ファイルを用意しようと思った所、Macromedia クオリティにやられました。っていうか Mac OS X 版、インストーラついてねぇし。ファイル配置をデヴェロッパに考えさせる Framwork って…21世紀に入ってもまだ Macromedia は Macromedia だな!!とか言ってみる。まぁ Beta なので、その辺は目をつむりましょう。

もう激しく眠いので、詳しくはまた近いうちに書き直しますが、(ってそれより先に Adobe/MM がもうちょっとましな Mac 版 SDK を用意する事をキボンヌな感じですけど…)要点は、Apollo は Flex の機能拡張だということかしら。以下に手順をごく簡単にまとめます。

  1. Apollo Runtime をインストール
  2. Flex2 SDk と Apollo SDK をダウンロード
  3. Flex2 SDK を解凍
  4. shell 変数に FLEX_HOME を設定
  5. Apollow SDK を解凍
  6. 両 SDK 内の bin 以下 .exe / .bat でないものに、ユーザの path を通す
  7. Apollo フォルダ内のほぼ全てから Symlink を Flex 内に貼る
  8. Apollo/framework/apollo.xml と flex2/framework/flex-config.xml をマージ

かな。長い。また書きます。

Processing: AlphaBlend

Date
2007-04-05 (Thu)
Category
Processing

Processing を久々にやっているので、ピクセル処理でいつも忘れるのでメモ。

image() っていつも思うが、なぜキャンバスに直接しかかけないのだろうか。 PImage 同士の合成ができてもいいじゃん!という事で書いたのがこれです。ポイントは AlphaBlend でしょうか…

void compositeImage (PImage top, int x, int y, PImage base) {
  int curX = 0;
  int curY = 0;
  for (int i = 0; i < top.pixels.length; i++) {
    curX = x + iToX(i, top.width);
    curY = y + iToY(i, top.width);
    if ((curX < base.width) && (curY < base.height)) {
      base.pixels[xyToI(curX, curY, base.width)] = blendByPixel(top.pixels[i], base.pixels[xyToI(curX, curY, base.width)]);
    }
  }
}
int blendByPixel (int top, int bottom) { int result = 0; int tA = (0xFF000000 & top) >>> 24;
if (tA == 255) { result = top; } else if (tA != 0) { result = alphaBlend(top, bottom, tA); } else { result = bottom; } return result; }
int alphaBlend(int fg, int bg, int a) {
int fR = (0x00FF0000 & fg) >>> 16; int fG = (0x0000FF00 & fg) >>> 8; int fB = 0x000000FF & fg;
int bR = (0x00FF0000 & bg) >>> 16; int bG = (0x0000FF00 & bg) >>> 8; int bB = 0x000000FF & bg;
int rR = (((fR - bR) * a) >>> 8 ) + bR; int rG = (((fG - bG) * a) >>> 8 ) + bG; int rB = (((fB - bB) * a) >>> 8 ) + bB;
return 0xFF000000 | (rR << 16) | (rG << 8) | rB; }
int iToX (int i, int w) { return i % w; }
int iToY (int i, int w) { return i / w; }
int xyToI (int x, int y, int w) { return (w * y) + x; }

Return to Page Top