php-idnkit について

JPNIC が配布しています「国際化ドメイン名ツールキット(idnkit)」を PHP から利用できる拡張モジュールです。 idnkit ライブラリ(libidnkitlite)を利用して UTF-8 と Punycode とを相互変換できます。

モジュール作成方法

php-idnkit は libidnkitlite を利用しますので、まずは idnkit のインストールを行います。 idnkit のダウンロードは、idnkit download からダウンロードできますので、ダウンロード後インストールを行ってください。

idnkit のインストールが完了したら、php-indkit を PHP に組み込みます。 php-idnkit は、php-idnkit 2003/12/04 版 をダウンロードしてください。
ダウンロードした php-idnkit は PHP のソースディレクトリ中の ext ディレクトリに展開します。 展開後、configure スクリプトに php-idnkit を反映させるために buildconf を実行します。 あとは、configure スクリプト実行時に --with-idnkit[=DIR] を追加して実行し、make/make install を行ってください。

たとえば、

$ gunzip -c php-4.x.y.tar.gz | tar xf -
$ cd php-4.x.y/ext
$ gunzip -c php-idnkit-20031204.tar.gz | tar xf -
$ cd ..
$ ./buildcond --force
$ ./configure --with-idnkit --with-apxs
$ make
$ make install
のような手順になります。
なお、idnkit のインストール先が /usr, /usr/local 以外の場合には、インストール先ディレクトリを指定することができます。

使い方

定義済みの定数

バージョン情報
IDNKIT_VERSIONidnkit ライブラリのバージョン番号を表現した文字列

動作フラグ
定数対応する idnkit ライブラリの動作フラグ
IDNKIT_DELIMMAPIDN_DELIMMAP
IDNKIT_LOCALMAPIDN_LOCALMAP
IDNKIT_MAPIDN_MAP
IDNKIT_NORMALIZEIDN_NORMALIZE
IDNKIT_PROHCHECKIDN_PROHCHECK
IDNKIT_UNASCHECKIDN_UNASCHECK
IDNKIT_BIDICHECKIDN_BIDICHECK
IDNKIT_ASCCHECKIDN_ASCCHECK
IDNKIT_IDNCONVIDN_IDNCONV
IDNKIT_LENCHECKIDN_LENCHECK
IDNKIT_RTCHECKIDN_RTCHECK
IDNKIT_UNDOIFERRIDN_UNDOIFERR
IDNKIT_ENCODE_QUERYIDN_ENCODE_QUERY
IDNKIT_DECODE_QUERYIDN_DECODE_QUERY
IDNKIT_ENCODE_APPIDN_ENCODE_APP
IDNKIT_DECODE_APPIDN_DECODE_APP
IDNKIT_ENCODE_STOREDIDN_ENCODE_STORED
IDNKIT_DECODE_STOREDIDN_DECODE_STORED
IDNKIT_NAMEPREPIDN_NAMEPREP
IDNKIT_ENCODE_APP_ERR IDN_DELIMMAP | IDN_LOCALMAP | IDN_MAP | IDN_NORMALIZE | IDN_PROHCHECK | IDN_BIDICHECK | IDN_ASCCHECK | IDN_IDNCONV | IDN_LENCHECK
IDNKIT_DECODE_APP_ERR IDN_DELIMMAP | IDN_MAP | IDN_NORMALIZE | IDN_PROHCHECK | IDN_BIDICHECK | IDN_IDNCONV | IDN_RTCHECK | IDN_ASCCHECK

リザルトコード
定数対応する idn_result_t 型の値
IDNKIT_SUCCESSidn_success
IDNKIT_NOTFOUNDidn_notfound
IDNKIT_INVALID_ENCODINGidn_invalid_encoding
IDNKIT_INVALID_SYNTAXidn_invalid_syntax
IDNKIT_INVALID_NAMEidn_invalid_name
IDNKIT_INVALID_MESSAGEidn_invalid_message
IDNKIT_INVALID_ACTIONidn_invalid_action
IDNKIT_INVALID_CODEPOINTidn_invalid_codepoint
IDNKIT_INVALID_LENGTHidn_invalid_length
IDNKIT_BUFFER_OVERFLOWidn_buffer_overflow
IDNKIT_NOENTRYidn_noentry
IDNKIT_NOMEMORYidn_nomemory
IDNKIT_NOFILEidn_nofile
IDNKIT_NOMAPPINGidn_nomapping
IDNKIT_CONTEXT_REQUIREDidn_context_required
IDNKIT_PROHIBITEDidn_prohibited
IDNKIT_FAILUREidn_failure

定義される関数

string idnkit_encodename(string name [, int actions] )
ドメイン名のエンコードを行います。UTF-8 文字列 name を Punycode 文字列に変換した文字列を返します。
エンコードでエラーが発生した場合には FLASE を返します。 実行結果に関しては、idnkit_errno() および idnkit_error() 関数により取得できます。
actions には idnkit の動作フラグに対応する定義済み定数が指定できます。 省略した場合には、IDNKIT_ENCODE_APP_ERR が指定されたものとして動作します。
例)
echo idnkit_encodename(mb_convert_encoding("日本語JPドメイン名.jp", "UTF-8", "auto"));

string idnkit_decodename(string name [, int actions] )
ドメイン名のデコードを行います。Punycode 文字列 name を UTF-8 文字列に変換した文字列を返します。
デコードでエラーが発生した場合には FLASE を返します。 実行結果に関しては、idnkit_errno() および idnkit_error() 関数により取得できます。
actions には idnkit の動作フラグに対応する定義済み定数が指定できます。 省略した場合には、IDNKIT_DECODE_APP_ERR が指定されたものとして動作します。
例)
echo mb_convert_encoding(idnkit_decodename( $_SERVER["HTTP_HOST"] ), "EUC-JP", "UTF-8");
int idnkit_errno()
idnkit_encodename()/idnkit_decodename() で直前に実行した実行結果のリザルトコードを返します。
返されたリザルトコードは定義済み定数により判別可能です。

string idnkit_error()
idnkit_encodename()/idnkit_decodename() で直前に実行した実行結果のリザルトコードに対応するメッセージ文字列を返します。
内部的には、idnkit の idn_result_tostring() 関数を呼び出します。

注意事項

php-idnkit では、libidnkitlite が提供している機能のうち api モジュールに含まれる idn_encodenameidn_decodename を利用できます。ただし、以下の制限があります。

終わりに

とりあえず、PHP 4.2.3 と PHP 4.3.3 でテストをしています。
複雑な処理をしているわけではないので、PHP 4.2.x および PHP 4.3.x では使えると思いますが、うまくコンパイルできない場合にはご連絡ください。

libidnkit では iconv を利用してコード変換をするため、PHP で標準的に使われている mbstring モジュールと変換ルールが異なると混乱するかと思い、UTF-8 と Punycode との相互変換のみを扱うようにするため libidnkitlite を利用しています。

2003/12/03 版では、idn_* で関数を定義していましたが、GNU IDN Library を利用した PHP-IDN が idn_* となっていましたので、idnkit_* の関数名に変更しました。

おまけ

勢いで、Ruby 用の拡張モジュール、ruby-idnkit 2003/12/08 版 も作ってみました。興味のある人はどうぞ。 2003/12/05 版では、ruby 1.6 系ではエラーとなるようなので、ちょっと関数(マクロ)を差し替えました。
ちなみに、UTF-8 <=> Punycode の相互変換のみなんで、UTF-8 へは自力で変換してください。


Presented by Kazuhiko Iwama.