DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
11 Monitoring and Observability Tools for 2023
Learn more
  1. DZone
  2. Coding
  3. Languages
  4. Phar: PHP libraries included with a single file

Phar: PHP libraries included with a single file

Giorgio Sironi user avatar by
Giorgio Sironi
·
Sep. 22, 11 · Interview
Like (0)
Save
Tweet
Share
21.18K Views

Join the DZone community and get the full member experience.

Join For Free

Phar is a php extensions that provides the means for distributing code as a single archive, that does not have to be extracted to a folder before usage.

The concept is similar to JVM Jars: each archive becomes a virtual directory where files can be accessed. However, the virtual folder is not limited to class loading, but you can open and read internal files as if it were decompresse into a directory.

Phar is available for PHP 5.3 and newer. In this article we see a toy example of Phar usage, and a real world one where we put the Doctrine 2 ORM into a single file.

Hello world example

In our toy example, we want to package this file as a Phar (hello.php):

<?php
echo "Hello, world of Phar!\n";

A real application would consist of multiple files and folders, but the purpose of this first example is just to get our teeth on the machinery.

Phar packaging happens with PHP code, which we can put in a build script (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 is (respectively) the path and the name of the created archive.

The stub we set as PHP code is what will be executed when the Phar is accessed by external code; it should always start with Phar::mapPhar() and always terminate with __HALT_COMPILER(). We can however do what we want in the middle of the stub, from including files to setup autoloading or executing code.

Now let's execute our build script, and use the new 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!

Now our application can be distributed as a single file, for example over HTTP, without worrying about decompression or file permissions.

Practical usage: Doctrine 2

This more practical example uses Phar on real code, consisting of the ORM Doctrine 2. It is currently packaged as a tarball, which should be decompressed before usage; however most of the machinery is in setting up autoloading for the different folders inside the package, Doctrine/ and Symfony/. The latter folder is also inexplicably put under the Doctrine/ one, violating the PSR-0 convention (since it contains Symfony\... classes).

Let's obtain the tarball package and expand it to a folder:

wget http://www.doctrine-project.org/downloads/DoctrineORM-2.1.1-full.tar.gz
tar xvzf DoctrineORM-2.1.1-full.tar.gz 

Now we can write a build script, 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'));

This script will include the code from a stub to execute at inclusion of the 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();

An example of using Doctrine 2 as a Phar is much simpler than setting up autoloading:

<?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));

I've put the scripts on Github for your convenience. I followed the example of the packaging code of Eric Clemmons for doctrine-migrations.

Want more?

Phar is not limited to archiving of files. It offers more features, such as compression based on the zip format, or hashing of the archive with MD5 or SHA1 with automated verification.

Since Phar-packaged code works from an archive, it cannot easily create temporary files, a fact that makes using this method for applications more complex. It also requiresa different way of accessing files for reading and execution, by inserting before them with the phar://archive.phar/ prefix.

However it seems to me a really practical way for distributing libraries or command line utilities, which can be just downloaded and included without issues regarding the include_path or autoloading. In fact, PEAR2's installer is being distributed as a Phar.

PHP

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Top 10 Best Practices for Web Application Testing
  • How To Build an Effective CI/CD Pipeline
  • Little's Law and Lots of Kubernetes
  • 10 Easy Steps To Start Using Git and GitHub

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: