Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Phar Laravel Package

phine/phar

phine/phar is a simple PHP library for building PHAR archives. Compile your project into a single distributable file with a fluent API, include/exclude rules, and support for Laravel-style workflows. Ideal for packaging CLI tools and standalone PHP apps.

View on GitHub
Deep Wiki
Context7

Getting Started

phine/phar is a thin object-oriented layer over PHP's built-in Phar/PharData classes. It exists to make two jobs pleasant: building a .phar from a directory tree in a build script, and unpacking an existing archive. It is archived (last release 2013-12-13, zero dependents), so treat this as a library you inherit or vendor, not one you reach for on a greenfield project.

First steps:

  1. Confirm the runtime. This targets PHP 5.3–5.6. On PHP 8.x expect deprecation noise at best and fatal errors at worst. Pin the version in composer.json (phine/phar resolves from Packagist) and run it on a PHP version you actually test against, or copy the src/ into your own namespace.
  2. Enable the phar extension (php -m | grep phar) — it's on by default but commonly disabled in hardened builds.
  3. Disable phar.readonly for any code path that writes an archive. This is the single most common reason a first attempt fails: php -d phar.readonly=0 bin/build-phar.php. Reading/extracting works with the default On.
  4. Look at the two entry points first: Phine\Phar\Builder (create/modify) and Phine\Phar\Stub (generate the bootstrap). Everything else (Phar, Manifest) is convenience.
  5. First use case: a small build script that collapses src/ + vendor/ + a bootstrap file into build/app.phar, then a smoke test that runs php build/app.phar --version.

A minimal build looks like:

use Phine\Phar\Builder;

$builder = new Builder('build/app.phar');
$builder->addDirectory('src', 'src');        // local path, in-archive path
$builder->addDirectory('vendor', 'vendor');
$builder->setStub('build/stub.php');         // must end with __HALT_COMPILER();
$builder->build();

Implementation Patterns

Build-script pattern (the main reason to use this). Wrap archive construction in a Composer script or Makefile target so developers never hand-build. The Builder accumulates files/directories, then flushes to disk once. Keep the build in a dedicated bin/build-phar.php and call it from composer run build:phar. Because phar.readonly cannot reliably be flipped with ini_set, the wrapper needs to be invoked with php -d phar.readonly=0.

Generate the stub instead of hand-writing it. Phine\Phar\Stub builds the __HALT_COMPILER(); preamble for you: bootstrap inclusion, mapPhar() for aliasing, and required-file lists. Generating it means the alias in the stub always matches the archive filename you passed to Builder. Commit the generator, not the generated stub.

Incremental/update flows. Re-opening an existing archive and adding files is supported, but prefer a clean rebuild (unlink then build) in CI — incremental updates leave orphaned entries when files are deleted from source, and phar entries don't have a "delete all" that is cheaper than rebuilding.

Extraction for deploy/inspect. The Phar wrapper exposes extractTo()-style helpers so a deploy step can unpack a shipped artifact into a release directory without shelling out to tar. Useful when your release artifact is a phar but your runtime expects loose files.

Integration with a release pipeline. Typical CI stage order: composer install --no-dev → run builder → php build/app.phar --version smoke test → sign or checksum → upload. Signing is done through the underlying \Phar::setSignature(); the package doesn't abstract it, so call it on the returned Phar object after build().

Reading manifests without executing. If you need to inspect what's inside an archive (list entries, read the stub) on a machine where you don't want to boot the app, use the manifest/read path — it opens the file without running the stub. This is the safe way to verify a build in a test.

Keep the builder isolated behind an interface. Because the library is frozen, wrap it in App\Build\PharBuilderInterface in your codebase. When you eventually migrate to humbug/box or raw \Phar, only the one adapter class changes.

Gotchas and Tips

  • phar.readonly is the whole ballgame. ini_set('phar.readonly', '0') does not work at runtime in practice — it must be set in php.ini or on the command line before the interpreter starts. Every "cannot write to phar" bug traces back here. Put the -d phar.readonly=0 in your build script shebang or Makefile so it can't be forgotten.
  • The stub must be byte-perfect. Nothing — not even a trailing newline — may follow __HALT_COMPILER();. Let Phine\Phar\Stub emit it rather than editing by hand.
  • Archived means PHP-version risk. This was written for PHP 5.3/5.4. Expect dynamic-property deprecations and possibly hard failures on PHP 8. Test on the exact PHP you deploy with, and vendor the source if you need to patch.
  • Signing needs OpenSSL. SHA-256/SHA-512 signature verification requires ext-openssl enabled on the machine that runs the phar, not just the one that builds it. Default SHA-1 signatures are fine but weak; set the signature algorithm explicitly.
  • Compression requires zlib/bz2. If you compress entries with gzip or bzip2, every consumer needs the matching extension. Don't compress CLI tools you'll ship to unknown hosts.
  • Phar caching bites during development. PHP caches the phar's file listing; edits to a rebuilt archive at the same path can appear stale. clearstatcache() plus restarting the process helps; in php-fpm, restart the pool.
  • Path separators and prefixes. addDirectory($local, $remote) maps a local tree into an in-archive prefix. A relative remote prefix that doesn't match your stub's mapPhar() alias produces confusing "file not found" errors at runtime.
  • Executable bit. A phar only runs as ./app.phar if the file mode is 0755; set it explicitly after build().
  • Don't shell out to phar commands. Everything this package does is just \Phar under the hood, so when the wrapper gives you trouble, drop to new \Phar($path) to inspect state — that's also your migration path.
  • Extension point: the builder returns the underlying Phar object; that's where you attach signatures, set metadata, and configure compression. Treat that return value as the escape hatch for anything the wrapper doesn't expose.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment