ダウンロード サンプルファイル (9.7 KB)
libzipの組み込み
今回は、ZIPファイルの読み込み用のネイティブライブラリとしてlibzipを組み込みます。libzipとは、PHPでのZip関数、ZipArchiveクラスを実装しているライブラリと同様です。しかし現在、PHPのZip機能は古いバージョンを想定されているために、libzipの新しい機能が使えません。
特にパスワード付きZIPファイルの読み込みは必要になる場合があるものの、PHPで標準で備えていないので、このサンプルを通じて、libzipでパスワード付きZIPファイルを読めるサンプルを作成します。
libzipのインストール
PHPでは、libzipはPHPのソースに含まれており、共有としては使いにくい部分があります。また、他のライブラリに影響を与えないように、ここでは、ソースコードからインストールします。
$ wget http://www.nih.at/libzip/libzip-0.11.1.tar.gz $ tar xvfz libzip-0.11.1.tar.gz $ cd libzip-0.11.1 $ sudo -s # ./configure; make; make install
これで、/usr/local/にlibzipがインストールされました。
pkg-configの確認
pkg-configとは、ライブラリをコンパイル、リンクする際のオプション設定を取得するプログラムです。さまざまなライブラリがpkg-config形式に対応しており、ライブラリを組み込む際に便利なので、このpkg-configを利用することを前提にconfig.m4ファイルを編集します。
先ほどインストールしたlibzip用のpkg-configのファイルは/usr/local/lib/pkgconfig/libzip.pcにインストールされます。しかし、デフォルトでは、pkg-configはこのファイルを検索しません。そこで、PKG_CONFIG_PATH=/usr/local/lib/pkgconfigの環境変数を設定します。
また、pkg-configを利用することで、他の利用者がコンパイルする場合にはシステムでインストールされている場所を探し出し、環境に依存しないビルド環境を設定することも容易です。以下のように、pkg-configが正常にlibzipを認識できているか確認します。
$ export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig $ pkg-config --modversion libzip 0.11.1
バージョン番号が合っていれば問題ありません。もし、違うバージョンが表示された場合には、すでにインストールされているlibzipを参照していますので、PKG_CONFIG_PATHのサーチパスの順番や、正しくパスが設定されているかなど確認してください。
config.m4を変更する
config.m4ファイルは、configureファイルを作成するための設定です。今回は、すでにインストールされていることが前提なので、比較的簡単な記述ですみます。
if test "$PHP_PZIP" != "no"; then
AC_MSG_CHECKING(for pkg-config)
if test ! -f "$PKG_CONFIG"; then
PKG_CONFIG=`which pkg-config` //……(1)
fi
PHP_NEW_EXTENSION(pzip, pzip.c pzip_file.c pzip_entry.c pzip_stream.c,$ext_shared)
PHP_SUBST(PZIP_SHARED_LIBADD)
if test -f "$PKG_CONFIG"; then
AC_MSG_RESULT(found pkg-config)
if $PKG_CONFIG --exists libzip; then // ……(2)
AC_MSG_RESULT(pzip : found libzip)
ZIP_LIBS=`$PKG_CONFIG --libs libzip` // ……(3)
ZIP_INCS=`$PKG_CONFIG --cflags-only-I libzip` // ……(4)
AC_MSG_RESULT(libzip includes : $ZIP_INCS) // ……(5)
AC_MSG_RESULT(libzip links : $ZIP_LIBS)
PZIP_LIBS="$LDFLAGS $ZIP_LIBS" // ……(6)
PZIP_INCS="$CFLAGS $ZIP_INCS" // ……(7)
PHP_EVAL_INCLINE($PZIP_INCS) // ……(8)
PHP_EVAL_LIBLINE($PZIP_LIBS, PZIP_SHARED_LIBADD) // ……(9)
else
AC_MSG_RESULT(not found libzip)
fi
fi
fi
(1)では、pkg-configの場所を確認しています。次に(2)で、libzipがpkg-configで見つかった場合の処理の処理です。(3)では、リンク時のオプションの取得、(4)では、コンパイル時に必要なincludeするファイルのパスを取得します。(5)のようにAC_MSG_RESULTで、それまでの設定をconfigure時に出力できますので、デバッグ時などに利用できます。また、(6)、(7)ではすでにリンク時のオプションやinclude時のオプションが登録されている場合がありますので、それらを含めた形で再度、変数を作成します。次に、エクステンションのコンパイル時のincludeパスの指定を(8)のPHP_EVAL_INCLINEマクロで行い、(9)のPHP_EVAL_LIBLINEマクロでリンク時のオプションを設定します。
実際に利用する関数の紹介
上記の設定が完了すると、libzipが提供している関数を利用できます。ここで、実際に今回のサンプルで利用する関数の一覧を紹介します。
| 関数名 | 説明 | 利用しているソース |
|---|---|---|
| zip_open | ZIPファイルをオープンするときに関数 | pzip_file.c |
| zip_close | ZIPファイルをクローズするときに関数 | pzip_file.c |
| zip_get_num_files |
ZIPファイルの中にいくつのエントリー(ファイル)が 含まれているかの数を取得する関数 |
pzip_file.c |
| zip_discard | zip_openで取得したメモリを解放するための関数 | pzip_file.c |
| zip_stat | ZIPファイルのエントリー情報をファイル名から取得する関数 | pzip_file.c |
| zip_stat_index |
ZIPファイルのエントリー情報を インデックス(何番目)から取得する関数 |
pzip_file.c |
| zip_fopen_index |
ZIPファイル内のファイルディスクリプタを インデックスから取得する関数 |
pzip_file.c |
| zip_fopen_index_encrypted |
ZIPファイル内の暗号化されたファイルの ファイルディスクリプタをインデックスから取得する関数 |
pzip_file.c |
| zip_fread |
zip_fopen_xxxxxで取得したファイルディスクリプタから データを読みこむ関数 |
pzip_stream.c |
この記事は参考になりましたか?
- PHPエクステンションの作り方連載記事一覧
-
- PHPエクステンションのエラー処理
- PHPでのストリーム処理の実装
- PHPで外部ライブラリ(libzip)を組み込んで利用する
- この記事の著者
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)
< WINGSプロジェクト について> 有限会社 WINGSプロジェクト が運営する、テクニカル執筆コミュニティ(代表 ...
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
