Phar — это расширение php, которое предоставляет средства для распространения кода в виде одного архива, который не нужно извлекать в папку перед использованием.
Концепция похожа на JVM Jars: каждый архив становится виртуальным каталогом, к которому можно получить доступ к файлам. Однако виртуальная папка не ограничивается загрузкой классов, но вы можете открывать и читать внутренние файлы, как если бы они были распакованы в каталог.
Phar доступен для PHP 5.3 и новее. В этой статье мы видим игрушечный пример использования Phar и реальный мир, в котором мы помещаем Doctrine 2 ORM в один файл.
Привет мир пример
В нашем игрушечном примере мы хотим упаковать этот файл как Phar ( hello.php ):
<?php echo "Hello, world of Phar!\n";
Реальное приложение будет состоять из нескольких файлов и папок, но цель этого первого примера — просто научиться работать с оборудованием.
Упаковка Phar происходит с помощью PHP-кода, который мы можем поместить в скрипт сборки ( package.php ):
#!/usr/bin/env php <?php $archive = new Phar('hello.phar', 0, 'hello.phar'); $archive->setStub('<?php Phar::mapPhar(); include "hello.php"; __HALT_COMPILER(); '); $archive['hello.php'] = file_get_contents('hello.php'); // use also $archive->buildFromDirectory(); $archive->buildFromIterator();
hello.phar — это (соответственно) путь и имя созданного архива.
Заглушка, которую мы установили как PHP-код, — это то, что будет выполняться, когда Phar будет доступен из внешнего кода; он всегда должен начинаться с Phar :: mapPhar () и всегда заканчиваться на __HALT_COMPILER (). Однако в середине заглушки мы можем делать то, что хотим, от включения файлов до настройки автозагрузки или выполнения кода.
Теперь давайте выполним наш скрипт сборки и используем новый Phar:
[10:52:02][giorgio@Desmond:~/phar_example]$ php build.php [10:52:03][giorgio@Desmond:~/phar_example]$ php hello.phar Hello, world of Phar!
Теперь наше приложение может распространяться как один файл, например, по HTTP, не беспокоясь о распаковке или правах доступа к файлу.
Практическое использование: Учение 2
Этот более практичный пример использует Phar для реального кода, состоящего из ORM Doctrine 2. В настоящее время он упакован как tarball, который перед использованием должен быть распакован; однако большая часть механизма заключается в настройке автозагрузки для различных папок внутри пакета, Doctrine / и Symfony /. Последняя папка также необъяснимо помещается в Doctrine / one, нарушая соглашение PSR-0 (так как она содержит классы Symfony \ …).
Давайте получим пакет tarball и развернем его в папку:
wget http://www.doctrine-project.org/downloads/DoctrineORM-2.1.1-full.tar.gz tar xvzf DoctrineORM-2.1.1-full.tar.gz
Теперь мы можем написать скрипт сборки phar-package.php:
<?php $archive = new Phar('doctrine-2.1.1.phar', 0, 'doctrine-2.1.1.phar'); $archive->buildFromDirectory('doctrine-orm', '/Doctrine\/(Common|DBAL|ORM)/'); $archive->buildFromDirectory('doctrine-orm/Doctrine', '/Symfony/'); $archive->setStub(file_get_contents('phar-bootstrap.php'));
Этот скрипт будет включать код из заглушки для выполнения при включении Phar-phar-bootstrap.php:
<?php Phar::mapPhar(); $basePath = 'phar://' . __FILE__ . '/'; require $basePath . 'Doctrine/Common/ClassLoader.php'; $classLoader = new \Doctrine\Common\ClassLoader('Doctrine', $basePath); $classLoader->register(); $classLoader = new \Doctrine\Common\ClassLoader('Symfony', $basePath); $classLoader->register(); __HALT_COMPILER();
Пример использования Doctrine 2 в качестве Phar намного проще, чем настройка автозагрузки:
<?php include_once 'doctrine-2.1.1.phar'; var_dump(class_exists('Doctrine\ORM\EntityManager', true)); var_dump(class_exists('Symfony\Component\Console\Application', true));
Я поместил сценарии на Github для вашего удобства. Я последовал примеру упаковочного кода Эрика Клеммонса для доктрин-миграций .
Хочу больше?
Phar не ограничивается архивированием файлов. Он предлагает больше функций, таких как сжатие на основе формата zip или хэширование архива с MD5 или SHA1 с автоматической проверкой.
Поскольку упакованный в Phar код работает из архива, он не может легко создавать временные файлы, что усложняет использование этого метода для приложений. Это также требует другого способа доступа к файлам для чтения и выполнения, вставляя перед ними префикс phar: //archive.phar /.
Однако мне кажется, что это действительно практичный способ распространения библиотек или утилит командной строки, которые можно просто загрузить и включить без проблем, связанных с include_path или автозагрузкой. Фактически, установщик PEAR2 распространяется как Phar.