php-makephar/doc/PHAR-APPS.md

2.5 KiB

Phar Applications

This guide explains how to make single-file executables using MakePhar.

The workflow

  1. Make sure you have a native php loader, in this example src/stub.php. If you include a bin, such as bin/myapp make sure it wraps the native loader or the shebang (#!/usr/bin/env php or similar) will be output during load.
  2. Set up the makephar.sdl file. You can copy and modify the example in this doc, the makephar.sdl.dist from the source package, or simply use makephar -n > makephar.sdl to have a template generated for you.
  3. Call on makephar to generate the output file.

Example files

src/stub.php

<?php

require_once __DIR__."/../vendor/autoload.php";
$app = new MyApp\MyApp();
$app->run();

makephar.sdl

phar "myapp.phar" {
    stub "src/stub.php";
    include {
        dir "src";
        dir "vendor";
    }
    exclude {
        dir ".git";
    }
}

Problems and Solutions

Getting the directory of the running phar

You can get the path of the command invoked using $_SERVER['SCRIPT_NAME']:

$root = dirname($_SERVER['SCRIPT_NAME']);

Note that the script can be a symbolic link, in which case you need to call on readlink before you call dirname:

// Get the path of the script, eg. /usr/bin/myapp
$root = $_SERVER['SCRIPT_NAME'];
// Unwrap the links, eg. /usr/bin/myapp -> ~/myapp/myapp.phar
while (readlink($root)) {
    $root = readlink($root);
}
// Finally get the directory (~/myapp)
$root = dirname($root);

Use this to locate your plugins.

Find out if running from within a Phar

You can easilly find out if running from within a .phar archive by calling Phar::running().

if (Phar::running()) { inside_phar(); }

This doesn't make sense to use in phar plugins, as the main application can also be in a phar, in which case it will be true even for non-phar plugins.

Including the Git revision etc

Use the props for this. If you have an executable file, say build/genprops that look like this...

#!/bin/bash
printf "GIT_REVISION=%s" "$(git describe --tags)"

...then you can define it in your makephar.sdl to be evaluated when the phar is being built:

phar "output.phar" {
    ...
    stub exec="build/genprops";
    ...
}

When running from within the built phar, the define GIT_REVISION will be available:

if (defined('GIT_REVISION')) {
    echo "Git Revision: ".GIT_REVISION."\n";
}