SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

PHPエクステンションの作り方

PHPで外部ライブラリ(libzip)を組み込んで利用する

PHPエクステンションの作り方 第5回

  • X ポスト
  • このエントリーをはてなブックマークに追加

libzipの組み込み

 今回は、ZIPファイルの読み込み用のネイティブライブラリとしてlibzipを組み込みます。libzipとは、PHPでのZip関数、ZipArchiveクラスを実装しているライブラリと同様です。しかし現在、PHPのZip機能は古いバージョンを想定されているために、libzipの新しい機能が使えません。

 特にパスワード付きZIPファイルの読み込みは必要になる場合があるものの、PHPで標準で備えていないので、このサンプルを通じて、libzipでパスワード付きZIPファイルを読めるサンプルを作成します。

libzipのインストール

 PHPでは、libzipはPHPのソースに含まれており、共有としては使いにくい部分があります。また、他のライブラリに影響を与えないように、ここでは、ソースコードからインストールします。

libzipのインストール
$ 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を認識できているか確認します。

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ファイルを作成するための設定です。今回は、すでにインストールされていることが前提なので、比較的簡単な記述ですみます。

config.m4の一部
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が提供している関数を利用できます。ここで、実際に今回のサンプルで利用する関数の一覧を紹介します。

今回利用する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

次のページ
クラスのインスタンスを返す方法と引数として利用する方法

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
PHPエクステンションの作り方連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、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本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/7524 2013/12/20 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング