Пользователь
0,0
рейтинг
28 апреля 2011 в 01:01

Разработка → .phar — исполняемые PHP-архивы

PHP*
Данную статью я хочу посвятить одному интересному нововведению в PHP 5.2 (с версии 5.3 входит в стандартную поставку PHP) — PHAR.
image
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.
  • Обладает высокой производительностью.
Виталий @icegreenberry
карма
66,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (80)

  • –32
    egg в Python, имхо, реализованы в 100500 раз удобнее. Про Jar ничего не знаю.
    • +1
      Не посещать топики с таким названием в 100500 раз удобнее. Не придется тратить время на тролинг.
  • +32
    Было бы здорово включить в статью элементарное объяснение зачем это нужно. Кроме очевидного «один файл вместо кучи». Спасибо.
    • +1
      Для инсталяторов, нет?
    • +2
      Если учесть, что производительность от этого не страдает, то этого, по-моему, вполне достаточно.
    • –3
      А Вам даже этого разве мало?
      Так же можно сказать о чем угодно:
      — зачем использовать ORM, кроме очевидного «данные из БД представлены в ввиде объектов»?
      — зачем нужны акселераторы, кроме очевидного «ускорение исполнения скрипта»?
      — …

      Использовать PHAR, или нет — решать Вам. Если чувствуете, что удобно — используете, если нет — никто не заставляет :)
      • +4
        Я не говорил мало это или много. Я просил описать проблемы, которые решает phar. Если это только количество файлов, то так и написать. Я нигде не написал что этого недостаточно, вы нафантазировали. Просто не увидел других очевидных преимуществ и попросил подсказать.
        • –1
          Не принимайте мой комментарий в штыки, пожалуйста.
          • +4
            А штыки я чем показал? Запятую где-то пропустил? Или восклицательный знак поставил? Вы меня изначально неправильно поняли. Я прошу описать преимущества подхода, а вы воспринимаете это как сарказм. Далее пишу о том, что я не шучу, мне действительно интересно зачем, и, опять, меня не понимают. Я не пришел потроллить на тему «ещё одна бесполезная фича», я хочу узнать зачем это нужно. «Один файл вместо 1000» — это хорошо, но об этом я и сам догадался. Хотел услышать что-то ещё, если это есть.
    • 0
      1) чтобы закачивать по (s)ftp меньше файлов;
      2) запаковать нечто, имеющее конкретную версию и не подлежащее изменению в рамках этой версии (библиотека, модуль, cms, и т.п.).
    • 0
      Например клиент для работы с каким-либо API сервером из консоли. Очень удобно имея один псевдобинарник.
  • +7
    А можно реальные ситуации где это надо? А если еще и бенчмарки выложите… :)
    • +5
      Вот зачем нужно:  http://habrahabr.ru/blogs/symfony/118011/
      Ну или:           http://silex-project.org/installation
      • 0
        Спустя два месяца:

        Using the Silex phar file is deprecated. You should use Composer instead to install Silex and its dependencies or download one of the archives.

        silex.sensiolabs.org/doc/phar.html
        • 0
          Спустя два месяца:

          год и два месяца=)

          Я всего лишь показал возможности использования .phar.
    • +6
      например, у вас есть модульная cms и модули к ней удобно делать в виде phar
      • 0
        Более того, и ядро в phar запихнуть, при условии версионности ядра.

        Спасибо за статью, добавил в избранное, буду использовать
  • 0
    > метода getSub()
    плиз, поправьте на getStub()
    опечатались
  • –74
    Когда же php пройдет уже…
    • +49
      Когда же идиоты пройдут уже…
    • –32
      Сколько ненависти то в PHP разработчиках, бедняги.
    • –33
      Уже больше 30 человек не хотят чтобы он проходил )). Что ж, я рад за вас, потому что это значит что вы встречаете только лаконичный, грамотный и чистый php код, написаный профессионалами, и всегда верный. Или вы очень терпимы к ошибкам школьников и т.д., примеры которых предостаточно везде.
      Было бы вас побольше таких, тогда бы не было комментариев по типу моего.
      А я перехожу в node.js. Всем удачи.
      • +15
        Быдло код можно встретить где угодно.
        Пишите грамотно и коллег заставляйте. Что ныть то?
      • +6
        > Или вы очень терпимы к ошибкам школьников

        Смена ЯП каким-то волшебным образом вправляет мозги школьникам?
        • 0
          Считается, что есть такая гипотеза :)
          • 0
            Ты про порог вхождения?
            • 0
              Ну, можно и про него :)
        • 0
          Например, паскаль изначально создавался именно для этих целей.
    • 0
      Когда mod_wsgi/mod_rack/… будут ставиться всеми хостерами по дефолту за те же деньги, что сейчас ставят mod_php. Когда для типовых задач будут готовые решения (причём по 100500 на каждую задачу на любой вкус) по принципу «закачал по ftp, прописал доступ к БД (также по ftp) и работает», а то и просто «поставил галочку в админке аккаунта». Когда будут простые (для «веб-мастеров») CMS типа, прости господи, WordPress или Joomla. И т. д., и т. п.

      Языки типа python/ruby или Java/C# не сложнее, а во многом и проще PHP, имхо. Но вот пресловутый порог входа для создания своих или использования готовых веб-приложений, имхо, явно выше у них. Хотя бы потому, что сам язык является мини-фреймворком, абстрагирующим детали реализации HTTP, а для других языков нужно или эти фреймворки устанавливать (ещё выбирать, потом изучать), или реализовывать HTTP самому.
  • 0
    > он должен местить в своем названии

    украинизм
    • +1
      Исправил, спасибо.
  • +1
    аналог JAR в Java

    Т.е. вместо десятка директорий (=пространств имен) содержащих по несколько сотен директорий и файлов можно положить всего десяток phar архивов и подключать файлы из них? Производительность при этом не пострадает? Или phar все же больше предназначен для создания инсталяторов (=распаковать файлы в нужно место)?
    • 0
      именно так, можно вообще ничего явным образом не подключать.

      В статье действительно очень хорошо описано как распаковывать и запаковывать, но вот люди не знакомые с джавой могут перепутать с эгами или гемами:) Использование именно для инсталяторов мне видится сомнительным, уверен есть решения получше и для визардов установки и темболее для деплоймента. А вот упаковать проект всеми либами и фреймворками нужных версий от которых он зависит с такой штукой намного проще.

      Все это добро должно разворачиваться во временные каталоги, т.е. производительность при подключении напрямую теряться не должна
      • 0
        С jar-ами то все понятно — они изначально были для упаковки классов и ресурсов, а вот с phar-ами не совсем, т.к. если производительность теряется, то в большинстве случаев смысла в них нет (упаковывать лучше и проще в архивы).

        В статье действительно очень хорошо описано как распаковывать и запаковывать

        А это не первая статья про phar на хабре в которой подробно описаны действия с архивами, но нет столь же подробного объяснения зачем они нужны. Отсюда и вопросы.
        • 0
          The phar extension provides a way to put entire PHP applications into a single file called a «phar» (PHP Archive) for easy distribution and installation. In addition to providing this service, the phar extension also provides a file-format abstraction method for creating and manipulating tar and zip files through the PharData class, much as PDO provides a unified interface for accessing different databases.

          ru.php.net/manual/en/intro.phar.php

          т.е. мнению разработчиков фар является штукой для удобной инсталяции и дистрибуции и вдобавок является хорошей абстракцией для работы с архивами

          phar.cache_list this INI setting was added in phar 2.0.0 Allows mapping phar archives to be pre-parsed at web server startup, providing a performance improvement that brings running files out of a phar archive very close to the speed of running those files from a traditional disk-based installation.

          www.slideboom.com/presentations/26182/PHP-5.3-Part-3---Introducing-PHAR

          т.е. если чуть подшаманить в приложении или настройках сервера то уступать будет совсем немного, как обычно вобщем:)

  • НЛО прилетело и опубликовало эту надпись здесь
    • +10
      Да за 2-е я бы сам пальчики ломал.
      • НЛО прилетело и опубликовало эту надпись здесь
      • +1
        Кстати говоря, иногда удобно «быстро поправить».

        Например, локально все работает, вылили на devel сервак, а там — ошибка.

        Подумали, поправили локально, закоммитили, вылили… Все равно ошибка!

        Или же просто зайдем на сервак, правим один файл, находим проблему и уже делаем правльный deploy.
        • –1
          Да, иногда такое бывает. Но если честно, от этого нужно уходить, точнее даже убегать. Убивайте проблему на корню, где-то проблема в конфигах/версиях. Лучше один раз это исправить и потом каждый коммит будет так же работать, как и локально.
          • НЛО прилетело и опубликовало эту надпись здесь
  • +6
    Ещё в использовании .phar есть одна классная фишка: можно вшивать в него autoload-еры для классов. Пример реализации:
    $phar->setStub('<?php

    Phar::mapPhar("Lagger");
    function autoloadLaggerByDir($class) {
    if(strpos($class, "Lagger_") === 0) {
    require_once("phar://" . str_replace("_", DIRECTORY_SEPARATOR, $class) . ".php");
    }
    }
    spl_autoload_register("autoloadLaggerByDir");
    __HALT_COMPILER();

    ');


    Полную версию примера см. тут.
  • –2
    Расширение phar использует т. н. «перехватчики» функций, в том числе функций ядра. Я сталкивался со случаем, когда в одной из ранних версий phar сломали функцию is_file(), и с тех пор как-то настороженно отношусь к этому расширению, и предпочитаю его не включать.
  • +6
    "… длина названия не должна превышать 255 бит"
    Штоу? Может байт?
  • 0
    Если изначально делать веб приложение в одном архиве, то переносить на другой хостинг будет на много быстрее.
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        В зависимости как у вас процесс деплоя устроен. Самый простой сценарий: кодите как обычно без phar, комит, какой-нить ci сервер подхватывает новую ревизию, пакует в phar, деплой.
        • НЛО прилетело и опубликовало эту надпись здесь
          • +2
            Архивом проще оперировать, чем деревом каталогов и файлов. В принципе можно обойтись и простым tar.gz при деплое, я не спорю, но такой архив нужно распаковать при деплое. phar будет достаточно подменить.
            Я написал всего лишь один из юс-кейсов. Другой вариант деплоя, билд можно и локально организовать. Написали код, пускаете phing, он вам все тесты прогоняет, стиль кодинга проверит, нагенерит миграций и упакует все в phar. Дальше делайте с ним что хотите: лейте по фтп, высылайте по мылу или еще что.
            В общем, пусть человек который видит выгоду в phar использует его, если выгоды не видно, то можно и по-старинке, раньше ж как-то выживали :)

            P.S. Сразу видно кто имел дело с java и их jar, а кто нет ;)
            • 0
              > Архивом проще оперировать, чем деревом каталогов и файлов

              На этом можно было остановиться. Остальное просто вода.
              В большинстве случаев jar именно поэтому и используется. И мы можем забыть про чексуммы, цифровые подписи, манифесты и прочие плюшки jar — это все ни к месту здесь и из другой оперы.

              > P.S. Сразу видно кто имел дело с java и их jar, а кто нет ;)

              и это все ни к месту и указывает лишь на узкость вашего мышления. когда же люди научатся комментарии давать по существу?

              Действительный итог: Архивом проще оперировать, чем деревом каталогов и файлов.
              Все остальные плюшки реализуются не jar'ом, а инструментами. Jar = обычный zip архив.
              • 0
                Опять же, модули и плагины для CMS (выше писали). Тот же WordPress сам качает zip-архив и распаковывает его. А так — один файл, он качается, и он же работает. Выгода не столь очевидная, но свои плюсы, несоменно, имеются. Сама CMS может состоять из модулей (например, один архив — ядро, другой — шаблонизаторы и пр.), к тому же подписи — дополнительная защита от взлома и модификации файлов.
                • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              Offtopic: Перечитал комментарий с точки зрения «простого смертного». Много думал.
  • +3
    Было бы здорово включить в статью элементарное объяснение зачем это нужно. Кроме очевидного «один файл вместо кучи»

    Это кстати решит проблемы с туевой кучей инклюдов для CMF типа Zend Framework. Никто не в курсе, кстати, есть ли zf-phar упакованный вариант?
    • +2
      Сам спросил, сам нашёл :-) Вот и вот.
      • 0
        Пригодилось. :)
  • 0
    Прикольно. Надо будет попробовать. Кстати там сказано что производительность ПОЧТИ не меняется без кэширования. И все же на сколько меняется?
    • +1
      Лично я не измерял, но измерял один из разработчиков: «the results are so close that it's pointless mentioning them here».
      • 0
        А ну ясно. В любом случае спасибо — реально полезная штуковина )
  • +2
    Phar::ConvertToData(), который принимает три параметра: формат (Phar::TAR, Phar::ZIP), сжатие (Phar::NONE, Phar::GZ, Phar::BZ2) и расширение (.tar, .tar.bz2, .tar.gz, .zip).
    Вот это обстоятельство вызывает мои наибольшие опасения. Формат JAR, по крайней мере, всегда был переименованным ZIPом, так что от него было ясно, чего ждать. А тут получается, что пакет PHAR может даже иметь расширение .zip, но при этом внутренний формат сжатия — gzip или bzip2 (но ни в коем случае не ZIP — так, что ли?). Вот это они не по-доброму удумали. Или я чего-то упускаю из виду?
    • 0
      Может быть все-таки если выбран TAR, то учитывается второй параметр. Если выбран ZIP, то понятно, что второй параметр ни на что не влияет.
      • +1
        По-Вашему получается, что Phar::TAR и Phar::NONE даёт расширение .tar,

        Phar::TAR и Phar::BZ2 даёт расширение .tar.bz2,

        Phar::TAR и Phar::GZ даёт расширение .tar.gz,

        Phar::ZIP даёт расширение .zip.

        Однако тогда не очень понятно, чего им было городить огород с тремя параметрами. Достаточно было бы и одного — расширения.

        Это беспокоит меня. Как бы не вышло так, что можно выбрать формат и сжатие одним способом, а расширение другим способом, и получить нечитаемый файл. Где защита от дурака?
        • 0
          дает не расширение, а подрасширение.
          ну, к примеру файл some.tar.phar или some.zip.phar

          Phar::isCompressed ( void )

          Замечание: This method requires the php.ini setting phar.readonly to be set to 0 in order to work for Phar objects. Otherwise, a PharException will be thrown.

          Returns Phar::GZ or PHAR::BZ2 if the entire phar archive is compressed (.tar.gz/tar.bz and so on). Zip-based phar archives cannot be compressed as a file, and so this method will always return FALSE if a zip-based archive is queried.


          php5.kiev.ua/manual/phar.iscompressed.html
        • +3
          Прочитал пособие.

          Вот оно что!

          На самом деле ни один из этих трёх параметров не обязателен.
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      В случае с cms-ками будет один файл кода и туча графики с css-ками.
      Если, конечно, не сделают для апача модуль для ссылок типа example.com/lib.phar/style/main.css
      • 0
        Не надо такого. А чтобы меньше css-ок было, надо вёрстку оптимизировать по запросам. Или вообще html offline apps использовать.
    • 0
      Вот, ловите, если ещё нужно. ZF1 и ZF2 в Phar. Вчера испёк :)
  • +2
    Еще бы менеджер пакетов нормальный, а не убогий PEAR
    • 0
      Ivy+ant не подойдут?
      • 0
        нет, хочется как rubygems или easy_install/pip
  • 0
    pyrus, не?
  • 0
    include_once(‘some_archive.phar’);

    а что собственно происходит при таком вызове? Чисто вызов заглушки?
    • +1
      Да, а что-то еще нужно? В любом случае должен быть некий bootstrap, который и include_once сделает и создаст экземпляры нужных классов и вызовет какие нужно методы. ИМХО, в большинстве случаев, в заглушке самое то держать autoload для классов конкретного phar, который добавляется в цепочку других autoload. Это позволит в самом приложении оперировать самими классами абстрагируясь от того, где они физически находятся, в phar'e (каком либо из нескольких) или в простых приинклуженных php. А это ведет за собой еще одну выгоду: с минимальными изменениями кода можно будет развернуть такое (использующее phar) приложение на платформе со старым РНР, который не поддерживает phar, всего лишь распаковав всё содержимое архивов и переписав логику автолоадов.
  • 0
    Что не понял — так это зачем изобретать свой формат архива. Могли бы тот же tar использовать и какой-нить файлик манифеста. А так не имея под рукой PHP даже содержимого этого phar не посмотришь…
    • 0
      Ну, на ваше восклицание о том «зачем изобретать свой формат» есть строчки из документации:
      Lastly, the Phar extension is security-conscious, and disables write access to executable phar archives by default, and requires system-level disabling of the phar.readonly php.ini setting in order to create or modify phar archives.

      Лично я во всём этом вижу (поправьте меня если я не прав) шаг в сторону защиты авторских прав исключая использование дорогостоящих Zend Guard и прочих сопутствующих продуктов от Zend.
      • +1
        Сомневаюсь по-поводу замены ZendGuard. Наверное это что-то в стиле «Если ваш сервер ломанули, то встроить эксплоит в .phar они не смогут...» как с .DEB пакетами — там тоже цифровая подпись используется для защиты от модификации.
  • –1
    Целая цмс сделанная в одном phar архиве http://mpak.su/ бонус — база данных sqlite лежит вместе с файлом цмс в одном директории
    • 0
      Вам подробно рассказали что не так с вашей поделкой, почему она опасна и т.п.
      Вы решили потеряться, и когда о вас забыли — обнулить карму, и опять начать рекламировать свое поделие. Теперь от статьи перешли к спаму. Прекрасно.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.