おぎろぐはてブロスマートフォン用の表示で見るおぎろぐはてブロなんだかんだエンジニアになって10年以上この広告は、90日以上更新していないブログに表示しています。PHP5.3PHP5から追加された機能として、SimpleXMLとかSPLなど、動作的にユーザレベルでは実現できないおもしろい動きをするものがあります。5.3から標準モジュールとなったpharも同じように結構見えないところでPHP本体の動きを変えるような実装をしているので、調べてみました。以下の部分に大きく分けています。いったファイルにアクセスすることができます。同様で、抽象化してアクセスできるようになるしくみです。中で構造体が宣言されています。見てわかるように、各ファイル操作に対して、関数を定義しています。wrapperの定義をします。始まるストリームにアクセスする際に、各関数が呼ばれます。}読み込みの部分は長ったらしいので省略。phar://でpharファイルにアクセスするときには、phar_wrapper_open_url()が呼ばれ、開いたあとは、php_stream_allocでストリームの動作の定義をします。pharのものに差し替えています。wrapperが役目を担っています。できるのと同じ仕組みです。compile_fileでは、include/requireされたスクリプトをコンパイルする役割を持ちます。wrapperがやってくれるので、普通は、ここを差し替える必要はありません。スタブ部分はpharアーカイブの先頭から__halt_compiler()までの部分に含まれるので、普通にincludeするだけで実行されます。ここを差し替えているのは例えばAPCなどのコンパイルキャッシュ系のモジュールです。ファイルにアクセスしてコンパイルする代わりに、キャッシュしたコンパイル結果を返します。含まないファイルについて読み込みを行い、圧縮ファイルであった場合にpharとして読み込み処理を行っています。hogehoge.phar.bz2とかコマンドラインで圧縮されたpharを起動する場合に対応します。書かれていたら、そのままでは普通にファイルを探そうとしてしまいます。そのため、PHPがパスを解決する部分に手が入れられています。(拡張モジュールが初期化されるときに呼ばれる関数)で、pharのモジュールの初期化のタイミングで以下のことをやっています。}pharのアーカイブ内で、相対パスで同じくアーカイブ内のファイルをincludeするようなことがあると思います。図のような構成になっているpharアーカイブのとき。ディレクトリを辿るような場合、通常のパス解決をすると、当然ファイルが見つかりません。これを解決するための実装で、PHP本体の仕様が異なることからバージョンに応じて変えている感じです。zend_resolve_pathの差し替えPHP5.3以降では、zend_resolve_pathをpharのものに差し替えています。pathを参照して、渡されたfilenameのrealpathを返却する関数です。展開することでファイルの参照を可能としています。}と、phar内の相対パスを良きに計らう関数に渡して、パス解決をしています。これは、ストリームをオープンするための関数です。呼んでパス解決しています。ファイルアクセス関数の差し替えpharには、Phar::interceptFileFuncsという、ファイルアクセス関連の関数をpharに横取りさせるメソッドがあります。アーカイブ内のファイルへのアクセスに変更されます。絶対パスの場合は、ファイルシステム上の外部ファイルを指すものとみなされます。Manualこのメソッドを実現するため、モジュール初期化時に元の関数をphar関数に差し替えます。関数を呼んだときに差し替えるのではなく、最初に全部差し替えちゃっている感じです。マクロでざっくりと、ファイルアクセス系関数を差し替えます。差し替えという感じに。突っ込み直しているだけ。関数はこういう実装になっていて、interceptがオフのときは、さっくりとgotoして、元の関数を呼び出します。PHP内部に特殊な動きを組み込んでいることが分かった感じです。使わないともったいないですね!というのと、phar使わないから無駄な処理省きたいという場合は、phar拡張を抜くというのもありかと思います。そんなに変わらないと思いますが。entriesはてなブログをはじめよう!i_ogiさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。