<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/phar.using.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ja',
  ),
  'this' => 
  array (
    0 => 'phar.using.intro.php',
    1 => 'Phar アーカイブの使用法: 導入',
    2 => 'Phar アーカイブの使用法: 導入',
  ),
  'up' => 
  array (
    0 => 'phar.using.php',
    1 => 'Phar アーカイブの使用法',
  ),
  'prev' => 
  array (
    0 => 'phar.using.php',
    1 => 'Phar アーカイブの使用法',
  ),
  'next' => 
  array (
    0 => 'phar.using.stream.php',
    1 => 'Phar アーカイブの使用法: phar ストリームラッパー',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ja',
    'path' => 'reference/phar/using.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="phar.using.intro" class="section">
 <h2 class="title">Phar アーカイブの使用法: 導入</h2>
 <p class="para">
  Phar アーカイブは Java の JAR アーカイブと似た概念のものですが、
  PHP アプリケーションで使用する際に必要な機能をより柔軟に使用できるよう改良しています。
  Phar アーカイブを使用すると、PHP アプリケーションやライブラリを
  ひとつのファイルにまとめて配布できるようになります。
  Phar アーカイブ形式のアプリケーションは、その他の PHP
  アプリケーションとまったく同様に扱えます。
 </p>
 <div class="example-contents screen">
  <div class="cdata"><pre>
php coolapplication.phar
  </pre></div>
 </div>
 <p class="para">
  Phar アーカイブ形式のライブラリを使用する方法も、
  その他の通常の PHP ライブラリとまったく同じです。
 </p>
 <p class="para">
  <div class="informalexample">
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">include </span><span style="color: #DD0000">'coollibrary.phar'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </p>
 <p class="para">
  <code class="literal">phar</code> ストリームラッパーは phar 拡張モジュールの要となるものです。
  詳細については <a href="phar.using.stream.php" class="link">こちら</a>
  で説明します。このストリームラッパーを使用すると、
  phar 内の個々のファイルに対して
  <span class="function"><a href="function.fopen.php" class="function">fopen()</a></span> や <span class="function"><a href="function.opendir.php" class="function">opendir()</a></span>
  といった標準のファイル操作関数を使用でき、
  まるで通常のファイルシステム上にあるのと同じような感覚でアクセスできます。
  <code class="literal">phar</code> ストリームラッパーは、
  ファイルやディレクトリに対する読み書き操作をすべてサポートしています。
 </p>
 <p class="para">
  <div class="informalexample">
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">include </span><span style="color: #DD0000">'phar://coollibrary.phar/internal/file.php'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">header</span><span style="color: #007700">(</span><span style="color: #DD0000">'Content-type: image/jpeg'</span><span style="color: #007700">);<br /></span><span style="color: #FF8000">// phar にアクセスするには、フルパスあるいはエイリアスを使用します<br /></span><span style="color: #007700">echo </span><span style="color: #0000BB">file_get_contents</span><span style="color: #007700">(</span><span style="color: #DD0000">'phar:///fullpath/to/coollibrary.phar/images/wow.jpg'</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </p>
 <p class="para">
  <span class="classname"><a href="class.phar.php" class="classname">Phar</a></span> クラスでは、
  ファイルへのアクセスや phar アーカイブ作成用により高度な機能も実装しています。
  Phar クラスについての説明は
  <a href="phar.using.object.php" class="link">こちら</a> をご覧ください。
 </p>
 <p class="para">
  <div class="informalexample">
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">try {<br />    </span><span style="color: #FF8000">// 既存の phar をオープンします<br />    </span><span style="color: #0000BB">$p </span><span style="color: #007700">= new </span><span style="color: #0000BB">Phar</span><span style="color: #007700">(</span><span style="color: #DD0000">'coollibrary.phar'</span><span style="color: #007700">, </span><span style="color: #0000BB">0</span><span style="color: #007700">);<br />    </span><span style="color: #FF8000">// Phar は SPL の DirectoryIterator クラスを継承しています<br />    </span><span style="color: #007700">foreach (new </span><span style="color: #0000BB">RecursiveIteratorIterator</span><span style="color: #007700">(</span><span style="color: #0000BB">$p</span><span style="color: #007700">) as </span><span style="color: #0000BB">$file</span><span style="color: #007700">) {<br />        </span><span style="color: #FF8000">// $file は PharFileInfo クラスで、これは SplFileInfo を継承しています<br />        </span><span style="color: #007700">echo </span><span style="color: #0000BB">$file</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getFileName</span><span style="color: #007700">() . </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />        echo </span><span style="color: #0000BB">file_get_contents</span><span style="color: #007700">(</span><span style="color: #0000BB">$file</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getPathName</span><span style="color: #007700">()) . </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">; </span><span style="color: #FF8000">// 内容を表示します<br />    </span><span style="color: #007700">}<br />    if (isset(</span><span style="color: #0000BB">$p</span><span style="color: #007700">[</span><span style="color: #DD0000">'internal/file.php'</span><span style="color: #007700">])) {<br />        </span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$p</span><span style="color: #007700">[</span><span style="color: #DD0000">'internal/file.php'</span><span style="color: #007700">]-&gt;</span><span style="color: #0000BB">getMetadata</span><span style="color: #007700">());<br />    }<br /><br />    </span><span style="color: #FF8000">// 新しい phar の作成 - php.ini で phar.readonly を 0 にしておく必要があります。<br />    // phar.readonly は、セキュリティ上の理由によってデフォルトで有効になっています。<br />    // 実際の運用サーバーでは、決して Phar を作成する必要はないはずで、<br />    // 単に実行できるだけでよいはずです。<br />    </span><span style="color: #007700">if (</span><span style="color: #0000BB">Phar</span><span style="color: #007700">::</span><span style="color: #0000BB">canWrite</span><span style="color: #007700">()) {<br />        </span><span style="color: #0000BB">$p </span><span style="color: #007700">= new </span><span style="color: #0000BB">Phar</span><span style="color: #007700">(</span><span style="color: #DD0000">'newphar.tar.phar'</span><span style="color: #007700">, </span><span style="color: #0000BB">0</span><span style="color: #007700">, </span><span style="color: #DD0000">'newphar.tar.phar'</span><span style="color: #007700">);<br />        </span><span style="color: #FF8000">// tar 形式の phar アーカイブを作成し、gzip で圧縮します (.tar.gz)<br />        </span><span style="color: #0000BB">$p </span><span style="color: #007700">= </span><span style="color: #0000BB">$p</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">convertToExecutable</span><span style="color: #007700">(</span><span style="color: #0000BB">Phar</span><span style="color: #007700">::</span><span style="color: #0000BB">TAR</span><span style="color: #007700">, </span><span style="color: #0000BB">Phar</span><span style="color: #007700">::</span><span style="color: #0000BB">GZ</span><span style="color: #007700">);<br /><br />        </span><span style="color: #FF8000">// トランザクションの作成 - newphar.phar には、<br />        // stopBuffering() がコールされるまで (一時的なストレージが必要となっても) なにも書き込まれません<br />        </span><span style="color: #0000BB">$p</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">startBuffering</span><span style="color: #007700">();<br />        </span><span style="color: #FF8000">// すべてのファイルを /path/to/project に追加し、プレフィックス "project" で phar に保存します<br />        </span><span style="color: #0000BB">$p</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">buildFromIterator</span><span style="color: #007700">(new </span><span style="color: #0000BB">RecursiveIteratorIterator</span><span style="color: #007700">(new </span><span style="color: #0000BB">RecursiveDirectoryIterator</span><span style="color: #007700">(</span><span style="color: #DD0000">'/path/to/project'</span><span style="color: #007700">)), </span><span style="color: #DD0000">'/path/to/'</span><span style="color: #007700">);<br /><br />        </span><span style="color: #FF8000">// 配列形式の API で新しいファイルを追加します<br />        </span><span style="color: #0000BB">$p</span><span style="color: #007700">[</span><span style="color: #DD0000">'file1.txt'</span><span style="color: #007700">] = </span><span style="color: #DD0000">'Information'</span><span style="color: #007700">;<br />        </span><span style="color: #0000BB">$fp </span><span style="color: #007700">= </span><span style="color: #0000BB">fopen</span><span style="color: #007700">(</span><span style="color: #DD0000">'hugefile.dat'</span><span style="color: #007700">, </span><span style="color: #DD0000">'rb'</span><span style="color: #007700">);<br />        </span><span style="color: #FF8000">// すべてのデータをストリームからコピーします<br />        </span><span style="color: #0000BB">$p</span><span style="color: #007700">[</span><span style="color: #DD0000">'data/hugefile.dat'</span><span style="color: #007700">] = </span><span style="color: #0000BB">$fp</span><span style="color: #007700">;<br /><br />        if (</span><span style="color: #0000BB">Phar</span><span style="color: #007700">::</span><span style="color: #0000BB">canCompress</span><span style="color: #007700">(</span><span style="color: #0000BB">Phar</span><span style="color: #007700">::</span><span style="color: #0000BB">GZ</span><span style="color: #007700">)) {<br />            </span><span style="color: #0000BB">$p</span><span style="color: #007700">[</span><span style="color: #DD0000">'data/hugefile.dat'</span><span style="color: #007700">]-&gt;</span><span style="color: #0000BB">compress</span><span style="color: #007700">(</span><span style="color: #0000BB">Phar</span><span style="color: #007700">::</span><span style="color: #0000BB">GZ</span><span style="color: #007700">);<br />        }<br /><br />        </span><span style="color: #0000BB">$p</span><span style="color: #007700">[</span><span style="color: #DD0000">'images/wow.jpg'</span><span style="color: #007700">] = </span><span style="color: #0000BB">file_get_contents</span><span style="color: #007700">(</span><span style="color: #DD0000">'images/wow.jpg'</span><span style="color: #007700">);<br />        </span><span style="color: #FF8000">// ファイルのメタデータには任意の値を保存できます<br />        </span><span style="color: #0000BB">$p</span><span style="color: #007700">[</span><span style="color: #DD0000">'images/wow.jpg'</span><span style="color: #007700">]-&gt;</span><span style="color: #0000BB">setMetadata</span><span style="color: #007700">(array(</span><span style="color: #DD0000">'mime-type' </span><span style="color: #007700">=&gt; </span><span style="color: #DD0000">'image/jpeg'</span><span style="color: #007700">));<br />        </span><span style="color: #0000BB">$p</span><span style="color: #007700">[</span><span style="color: #DD0000">'index.php'</span><span style="color: #007700">] = </span><span style="color: #0000BB">file_get_contents</span><span style="color: #007700">(</span><span style="color: #DD0000">'index.php'</span><span style="color: #007700">);<br />        </span><span style="color: #0000BB">$p</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setMetadata</span><span style="color: #007700">(array(</span><span style="color: #DD0000">'bootstrap' </span><span style="color: #007700">=&gt; </span><span style="color: #DD0000">'index.php'</span><span style="color: #007700">));<br /><br />        </span><span style="color: #FF8000">// phar アーカイブをディスクに保存します<br />        </span><span style="color: #0000BB">$p</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">stopBuffering</span><span style="color: #007700">();<br />    }<br />} catch (</span><span style="color: #0000BB">Exception $e</span><span style="color: #007700">) {<br />    echo </span><span style="color: #DD0000">'Phar をオープンできません: '</span><span style="color: #007700">, </span><span style="color: #0000BB">$e</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </p>
 <p class="para">
  さらに、phar ファイルの中身の検証を行うこともできます。対称型ハッシュアルゴリズム
  (MD5、SHA1、SHA256、そしてもし ext/hash が有効ならさらに SHA512) のいずれか、
  あるいは OpenSSL を使用した非対称公開鍵/秘密鍵ペアによる署名のいずれかを使用します。
  OpenSSL による署名を使用するには、
  まず公開鍵/秘密鍵のペアを作成し、秘密鍵を使用して
  <span class="function"><a href="phar.setsignaturealgorithm.php" class="function">Phar::setSignatureAlgorithm()</a></span> で署名を行います。
  公開キーによる展開はこのようなコードで行います。
  <div class="example-contents">
   <div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$public </span><span style="color: #007700">= </span><span style="color: #0000BB">openssl_get_publickey</span><span style="color: #007700">(</span><span style="color: #0000BB">file_get_contents</span><span style="color: #007700">(</span><span style="color: #DD0000">'private.pem'</span><span style="color: #007700">));<br /></span><span style="color: #0000BB">$pkey </span><span style="color: #007700">= </span><span style="color: #DD0000">''</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">openssl_pkey_export</span><span style="color: #007700">(</span><span style="color: #0000BB">$public</span><span style="color: #007700">, </span><span style="color: #0000BB">$pkey</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
  </div>

  公開鍵は phar アーカイブと同じ場所、名前でなければなりません。つまり、phar アーカイブの保存先が
  <code class="literal">/path/to/my.phar</code> の場合は公開鍵を
  <code class="literal">/path/to/my.phar.pubkey</code> としなければなりません。
  そうしないと、OpenSSL 署名の検証ができなくなります。
 </p>
 <p class="para">
  <span class="classname"><a href="class.phar.php" class="classname">Phar</a></span> には 3 つのstaticメソッド
  <span class="function"><a href="phar.webphar.php" class="function">Phar::webPhar()</a></span>、
  <span class="function"><a href="phar.mungserver.php" class="function">Phar::mungServer()</a></span> そして <span class="function"><a href="phar.interceptfilefuncs.php" class="function">Phar::interceptFileFuncs()</a></span>
  が追加されました。これは、通常のファイルシステム用あるいはウェブアプリケーション用の
  PHP アプリケーションのパッケージを作成する際に重要となります。
  <span class="function"><a href="phar.webphar.php" class="function">Phar::webPhar()</a></span> は、HTTP のコールを phar
  アーカイブ内の特定の場所に転送するフロントコントローラを実装します。
  <span class="function"><a href="phar.mungserver.php" class="function">Phar::mungServer()</a></span> は
  <var class="varname"><a href="reserved.variables.server.php" class="classname">$_SERVER</a></var> 配列の中身をうまく変更して
  アプリケーションでその値を使えるようにします。
  <span class="function"><a href="phar.interceptfilefuncs.php" class="function">Phar::interceptFileFuncs()</a></span> は、
  <span class="function"><a href="function.fopen.php" class="function">fopen()</a></span> や <span class="function"><a href="function.file-get-contents.php" class="function">file_get_contents()</a></span>、<span class="function"><a href="function.opendir.php" class="function">opendir()</a></span>
  そしてすべての stat 系関数 (<span class="function"><a href="function.file-exists.php" class="function">file_exists()</a></span>、<span class="function"><a href="function.is-readable.php" class="function">is_readable()</a></span> など)
  のコールを Phar が横取りして、相対パスを phar アーカイブ内の適切な位置に変換するようにします。
 </p>
 <p class="para">
  たとえば、あの有名な phpMyAdmin を phar アーカイブにすることを考えてみましょう。
  必要なのは、こんな単純なスクリプトだけです。あとは、
  ユーザー名とパスワードを変更してウェブサーバー上から
  <code class="literal">phpMyAdmin.phar.tar.php</code> にアクセスするだけで利用できます。
 </p>
 <p class="para">
  <div class="informalexample">
   <div class="example-contents">
    <div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">@</span><span style="color: #0000BB">unlink</span><span style="color: #007700">(</span><span style="color: #DD0000">'phpMyAdmin.phar.tar.php'</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">copy</span><span style="color: #007700">(</span><span style="color: #DD0000">'phpMyAdmin-2.11.3-english.tar.gz'</span><span style="color: #007700">, </span><span style="color: #DD0000">'phpMyAdmin.phar.tar.php'</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$a </span><span style="color: #007700">= new </span><span style="color: #0000BB">Phar</span><span style="color: #007700">(</span><span style="color: #DD0000">'phpMyAdmin.phar.tar.php'</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$a</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">startBuffering</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$a</span><span style="color: #007700">[</span><span style="color: #DD0000">"phpMyAdmin-2.11.3-english/config.inc.php"</span><span style="color: #007700">] = </span><span style="color: #DD0000">'&lt;?php<br />/* サーバーの設定 */<br />$i = 0;<br /><br />/* Server localhost (config:root) [1] */<br />$i++;<br />$cfg[\'Servers\'][$i][\'host\'] = \'localhost\';<br />$cfg[\'Servers\'][$i][\'extension\'] = \'mysqli\';<br />$cfg[\'Servers\'][$i][\'connect_type\'] = \'tcp\';<br />$cfg[\'Servers\'][$i][\'compress\'] = false;<br />$cfg[\'Servers\'][$i][\'auth_type\'] = \'config\';<br />$cfg[\'Servers\'][$i][\'user\'] = \'root\';<br />$cfg[\'Servers\'][$i][\'password\'] = \'\';<br /><br /><br />/* サーバーの設定はここまで */<br />if (strpos(PHP_OS, \'WIN\') !== false) {<br />    $cfg[\'UploadDir\'] = getcwd();<br />} else {<br />    $cfg[\'UploadDir\'] = \'/tmp/pharphpmyadmin\';<br />    @mkdir(\'/tmp/pharphpmyadmin\');<br />    @chmod(\'/tmp/pharphpmyadmin\', 0777);<br />}'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$a</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setStub</span><span style="color: #007700">(</span><span style="color: #DD0000">'&lt;?php<br />Phar::interceptFileFuncs();<br />Phar::webPhar("phpMyAdmin.phar", "phpMyAdmin-2.11.3-english/index.php");<br />echo "phpMyAdmin is intended to be executed from a web browser\n";<br />exit -1;<br />__HALT_COMPILER();<br />'</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$a</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">stopBuffering</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </p>
</div><?php manual_footer($setup); ?>