Данную статью я хочу посвятить одному интересному нововведению в PHP 5.2 (с версии 5.3 входит в стандартную поставку PHP) — PHAR.

PHAR — это утилита для создания исполняемых архивов в PHP, аналог JAR в Java.
PHAR ползволяет упаковать много файлов в один, в результате чего Ваше приложение может работать с целой библиотекой, как с одним файлом.
PHAR умеет создавать, читать, записывать и конвертировать такие форматы, как TAR, ZIP и, собственно, PHAR.
Доступ к файлам в архиве осуществляется напрямую, без необходимости распаковки архива, через PHP Stream Wrapper, тоесть с файлами из архива работают все функции, которые поддерживают PHP Stream Wrapper.
Для того, чтобы работать с архивами PHAR Вам нужен PHP не ниже версии 5.2 с расширениями PHAR, zlib и bzip2 (если у Вас PHP 5.3, то PHAR уже установлен по умолчанию ).
Безопасность
По умолчанию, к PHAR архивам есть только доступ на чтение. При желании, можно установить phar.readonly = 0 в php.ini.
Кроме того, PHAR архивы могут исполняться только PHP интерпретатором
Создаем архив с текстовым файлом:
А теперь считываем его содержимое:
“Заглушка” — это файл, который читается первым при подключении PHAR-архива, это своего рода Bootstrap. Этот файл интерпретируется только в том случае, если архив подключен полностью. Если же скрипт использует только конкретные файлы из архива — файл-заглушка не интерпретируется.
Посмотрим пример:
При создании файла-заглушки используйте вызов __HALT_COMPILER() в конце файла.
Доступ к файлу-заглушке можно получить вызовом метода getStub(), как в примере:
Для установки файла-заглушки по умолчанию нужно использовать метод setDefaultStub():
ВАЖНО: установите phar.readonly = 0 в php.ini
Существует несколько способов записи содержимого:
Несколько примеров:
Как и с записью, существует несколько способов:
Сигнатура используется для проверки достоверности данных.
PHAR поддерживает четыре алгоритма для создания сигнатур:
Для установки сигнатуры следует использовать метод Phar::setSignatureAlgorithm(), который принимает два параметра:
Пример кода:
и для OpenSSL:
PHAR поддерживает чтение ZIP и TAR архивов. При этом чтение происходит так будто это обычный PHAR архив. Однако, следует помнить о том, что длина названия не должна превышать 255 байт, включая путь к файлу, а также, что для того, чтобы архив был исполняемым, он должен содержать в своем названии ‘.phar’ (например, habr.phar.gz)
Сжатие архивов производится одним из двух алгоритмов: gzip или bzip2.
Обратите внимание, что ZIP и TAR архивы могут быть созданы даже если phar.readonly = 1 в php.ini, но в таком случае не могут содержать файл-заглушку или ‘.phar’ в названии.
Конвертация форматов архива
Конвертацию архива можно проделать двумя способами:
1. Phar::ConvertToData(), который принимает три параметра: формат (Phar::TAR, Phar::ZIP), сжатие(Phar::NONE, Phar::GZ, Phar::BZ2) и расширение(.tar, .tar.bz2, .tar.gz, .zip).
2. Phar::ConvertToExecutable(), который принимает все те же параметры за исключением последнего — расширения. Тут доступно гораздо больше вариантов, которые все же основываются на форматах PHAR, ZIP или TAR соответственно: .phar, .phar.gz, .phar.bz2, .phar.tar, .phar.tar.gz, .phar.tar.bz2, .phar.zip
Как я уже написал выше — доступно два способа сжатия: Gzip и Bzip2, при этом сжимать можно как сам архив, так и файлы внутри него.
Для сжатия архива нужно использовать метод compress(), который принимает два параметра — тип сжатия и расширение файла:
Для сжатия файлов — compressFiles() с одним параметром — тип сжатия:
При использовании APC производительность PHAR вырастает до 6 раз.
Без кеширования — почти не отличается от варианта без использования PHAR.
И так, подведем итоги:

PHAR — это утилита для создания исполняемых архивов в PHP, аналог JAR в Java.
PHAR ползволяет упаковать много файлов в один, в результате чего Ваше приложение может работать с целой библиотекой, как с одним файлом.
PHAR умеет создавать, читать, записывать и конвертировать такие форматы, как TAR, ZIP и, собственно, PHAR.
Доступ к файлам в архиве осуществляется напрямую, без необходимости распаковки архива, через PHP Stream Wrapper, тоесть с файлами из архива работают все функции, которые поддерживают PHP Stream Wrapper.
Требования
Для того, чтобы работать с архивами PHAR Вам нужен PHP не ниже версии 5.2 с расширениями PHAR, zlib и bzip2 (если у Вас PHP 5.3, то PHAR уже установлен по умолчанию ).
Безопасность
По умолчанию, к PHAR архивам есть только доступ на чтение. При желании, можно установить phar.readonly = 0 в php.ini.
Кроме того, PHAR архивы могут исполняться только PHP интерпретатором
Пример
Создаем архив с текстовым файлом:
$phar = new Phar('test.phar'); $phar[hello_habr.txt] = 'Hello Habr!';
А теперь считываем его содержимое:
echo file_get_contents('phar://test.phar/hello_habr.txt');
Файл-заглушка
“Заглушка” — это файл, который читается первым при подключении PHAR-архива, это своего рода Bootstrap. Этот файл интерпретируется только в том случае, если архив подключен полностью. Если же скрипт использует только конкретные файлы из архива — файл-заглушка не интерпретируется.
Посмотрим пример:
//файл-заглушка будет прочитан include_once(‘some_archive.phar’); //файл-заглушка прочитан не будет include_once(‘phar://some_archive.phar/somefile.php’);
При создании файла-заглушки используйте вызов __HALT_COMPILER() в конце файла.
Доступ к файлу-заглушке можно получить вызовом метода getStub(), как в примере:
$phar = new Phar(‘some_archive.phar’); $stub = $phar->getStub();
Для установки файла-заглушки по умолчанию нужно использовать метод setDefaultStub():
$phar = new Phar(‘some_archive.phar’); $phar->setDefaultStub('cli.php', 'web/index.php');
Создание содержимого архива
ВАЖНО: установите phar.readonly = 0 в php.ini
Существует несколько способов записи содержимого:
- через свойство объекта
- Phar::addFile()
- Phar::addFromString()
- Phar::addEmptyDir()
- Phar::buildFromDirectory()
- Phar::buildFromIterator()
Несколько примеров:
$phar = new Phar(‘habr.phar’); $phar[‘index.php’] = file_get_contents(‘some/path/to/file.php’); // через свойство объекта в виде доступа к элементам массива (ArrayAccess)
$phar = new Phar(‘habr.phar’); $phar->addFile(‘http://habrahabr.ru’, ‘HabrHomePage.html’); $phar->addFromString(‘HabrHomePage’, file_get_contents(‘http://habrahabr.ru’)); $phar = new Phar(‘habr.phar’); $phar->addEmptyDir(‘temporary/’); $phar->buildFromDirectory(‘some_directory/’);
$phar = new Phar(‘habr’); $dir = ‘somedir/’; $phar->buildFromIterator( new RecursiveDirectoryIterator($dir) );
Чтение из архива
Как и с записью, существует несколько способов:
- PHAR stream wrapper (phar://)
- прямое подключение
- Phar::extractTo()
- Итерация по инстансу 'Phar'
Сигнатура PHAR архива
Сигнатура используется для проверки достоверности данных.
PHAR поддерживает четыре алгоритма для создания сигнатур:
- MD5
- SHA1
- SHA256
- SHA512
Для установки сигнатуры следует использовать метод Phar::setSignatureAlgorithm(), который принимает два параметра:
- Тип сигнатуры:
- Phar::MD5
- Phar::SHA1
- Phar::SHA256
- Phar::SHA512
- Phar::OPENSSL
- Приватный ключ — тоесть OpenSSL private key
Пример кода:
$phar=new Phar('habr.phar'); $phar->buildFromDirectory('habr/'); $signatures=Phar::getSupportedSignatures(); if (in_array(PHAR::SHA512,$signatures)) { $phar->setSignatureAlgorithm(PHAR::SHA512); } elseif (in_array(PHAR::SHA256,$signatures)) { $phar->setSignatureAlgorithm(PHAR::SHA256); } elseif (in_array(PHAR::SHA1,$signatures)) { $phar->setSignatureAlgorithm(PHAR::SHA1); } elseif (in_array(PHAR::MD5,$signatures)) { $phar->setSignatureAlgorithm(PHAR::MD5); }
и для OpenSSL:
$phar=new Phar('habr.phar'); $phar->buildFromDirectory('habr/'); $OSSLPrivateKey=openssl_get_privatekey(file_get_contents('private.pem')); $OSSLPKey=''; openssl_pkey_export($OSSLPrivateKey,$OSSLPKey); $phar->setSignatureAlgorithm(Phar::OPENSSL,$OSSLPKey);
ZIP и TAR
PHAR поддерживает чтение ZIP и TAR архивов. При этом чтение происходит так будто это обычный PHAR архив. Однако, следует помнить о том, что длина названия не должна превышать 255 байт, включая путь к файлу, а также, что для того, чтобы архив был исполняемым, он должен содержать в своем названии ‘.phar’ (например, habr.phar.gz)
Сжатие архивов производится одним из двух алгоритмов: gzip или bzip2.
Обратите внимание, что ZIP и TAR архивы могут быть созданы даже если phar.readonly = 1 в php.ini, но в таком случае не могут содержать файл-заглушку или ‘.phar’ в названии.
Конвертация форматов архива
Конвертацию архива можно проделать двумя способами:
1. Phar::ConvertToData(), который принимает три параметра: формат (Phar::TAR, Phar::ZIP), сжатие(Phar::NONE, Phar::GZ, Phar::BZ2) и расширение(.tar, .tar.bz2, .tar.gz, .zip).
2. Phar::ConvertToExecutable(), который принимает все те же параметры за исключением последнего — расширения. Тут доступно гораздо больше вариантов, которые все же основываются на форматах PHAR, ZIP или TAR соответственно: .phar, .phar.gz, .phar.bz2, .phar.tar, .phar.tar.gz, .phar.tar.bz2, .phar.zip
Сжатие
Как я уже написал выше — доступно два способа сжатия: Gzip и Bzip2, при этом сжимать можно как сам архив, так и файлы внутри него.
Для сжатия архива нужно использовать метод compress(), который принимает два параметра — тип сжатия и расширение файла:
$phar=new Phar('habr.phar'); $phar->buildFromDirectory('habr/'); if (Phar::canCompress(Phar::GZ)) { $phar->compress(Phar::GZ,'.phar.gz'); } else if (Phar::canCompress(Phar::BZ2)) { $phar->compress(Phar::BZ2,'.phar.bz2'); }
Для сжатия файлов — compressFiles() с одним параметром — тип сжатия:
$phar=new Phar('habr.phar'); $phar->buildFromDirectory('habr/'); if (Phar::canCompress(Phar::GZ)) { $phar->compressFiles(Phar::GZ); } else if (Phar::canCompress(Phar::BZ2)) { $phar->compressFiles(Phar::BZ2); }
Производительность
При использовании APC производительность PHAR вырастает до 6 раз.
Без кеширования — почти не отличается от варианта без использования PHAR.
Итоги
И так, подведем итоги:
- PHAR легко устанавливается, а если точнее — он входит в стандартную поставку PHP 5.3.
- Его легко использовать.
- Легко разворачивать — всего один файл.
- Он хорошо защищен — сигнатуры, OpenSSL.
- Обладает высокой производительностью.
