Quickly create phar files using Box
Phar
Is an analogue jar
from the Java world, but only in relation to PHP. Phar
packs project files into a special archive and makes it easy to transfer and install the application without manipulating the project itself as an executable program.Description of phar from official documentation
Phar archives are best characterized as a convenient way to group several files into a single file. As such, a phar archive provides a way to distribute a complete PHP application in a single file and run it from that file without the need to extract it to disk. Additionally, phar archives can be executed by PHP as easily as any other file, both on the commandline and from a web server. Phar is kind of like a thumb drive for PHP applications.
For creating phar files in PHP, there is a rather branchy API , but there is a simpler and more convenient way - to use the Box project .
JSON file format
The Box project allows you to describe the process of creating a phar file in a convenient JSON format.
The simplest file looks like this:
{
"files": ["src/Put.php"],
"main": "bin/main",
"output": "example.phar",
"stub": true
}
where
files
are the files that should be included in the phar main
- the file that will be executed when the phar file output
is called - the name of the final phar
file stub
- for console applications is set to true
Here you can see the process of creating a phar file using an example of a simple project.
It contains a list of all possible parameters
box.json
with comments. Let's try to build a phar file using an example of a real project. Take the Nasgrate database migration system as an example .. “Traditionally,” this system is installed either through cloning the repository from GitHub, or through Composer. We will try to make a separate utility that you can simply download and start using without knowing anything about PHP at all.
Create
box.json
at the root of the project{
"chmod": "0755",
"directories": ["src","app"],
"files": ["README.md"],
"main": "bin/nasgrate",
"output": "nasgrate.phar",
"stub": true
}
directories
- this parameter contains a list of directories that will be entirely included in the project (in this case, the directory src
and app
). files
- if you need to include any specific files, list them here. We could for example rewrite box.json as follows
{
"chmod": "0755",
"directories": ["src"],
"files": ["app/console.php", "app/index.php", "README.md"],
"main": "bin/nasgrate",
"output": "nasgrate.phar",
"stub": true
}
In addition to these two recording options, it is also possible to selectively include files in the project based on filters. For example, if external libraries were actively used in the project and they were located in a folder
vendors
, we would like to include the files of these libraries in the project, but exclude, for example, all tests. Then the file would look like this{
"chmod": "0755",
"directories": ["src"],
"files": ["app/console.php", "app/index.php", "README.md"],
"finder": [
{
"name": "*.php",
"exclude": [
"tests",
"test"
],
"in": "vendor"
}
],
"main": "bin/nasgrate",
"output": "nasgrate.phar",
"stub": true
}
the section
finder
in this case says: “include all files with the extension *.php
from the directory vendor
except the folders tests
and test
“. chmod
- allows you to set phar
file permissions . In this case, we set 0755
to make the file executable. The remaining parameters were described above.
Box Installation
The easiest (and recommended) installation method
$ curl -LSs https://box-project.github.io/box2/installer.php | php
then appears in the current directory
box.phar
. You can run it as
php box.phar
, or assign execution rights chmod 755 box.phar
, rename it to box mv box.phar box
and transfer it to /usr/local/bin
. Then it can be launched from anywhere just like that box
. Alternative installation via Composer
$ composer global require kherge/box --prefer-source
or add it to an existing project
{
"require-dev": {
"kherge/box": "~2.5"
}
}
Check the installation
$ box -v
should display a description of the program and a list of possible options.
Next, you need to check that in your
php.ini
file the parameter is phar.readonly
in 0
, Off
or false
. We find out where our file is located, which is relevant for the console (if you run phpinfo (); through Apache, it will show you another php.ini):
$ php -i | grep php.ini
>> Configuration File (php.ini) Path => /usr/local/php5/lib
>> Loaded Configuration File => /usr/local/php5/lib/php.ini
Next, find the parameter
phar.readonly
and put it in Off
.[Phar]
; http://php.net/phar.readonly
phar.readonly = Off
Project compilation
We go into the folder with the project (to the level where ours lies
box.json
) and start compilation$ box build -v
The flag
-v
allows us to see what happens during the compilation Removing previously built Phar...
* Building...
? Output path: /Users/dlevsha/Sites/nasgrate/nasgrate.phar
? Adding directories...
+ /Users/dlevsha/Sites/nasgrate/src/config.php
+ /Users/dlevsha/Sites/nasgrate/src/Driver/Base/Dump.php
+ /Users/dlevsha/Sites/nasgrate/src/Driver/Base/Generator.php
+ /Users/dlevsha/Sites/nasgrate/src/Driver/Base/Helper.php
+ /Users/dlevsha/Sites/nasgrate/src/Driver/Base/Migration.php
+ /Users/dlevsha/Sites/nasgrate/src/Driver/Mysql/Dump.php
+ /Users/dlevsha/Sites/nasgrate/src/Driver/Mysql/Generator.php
+ /Users/dlevsha/Sites/nasgrate/src/Driver/Mysql/Helper.php
+ /Users/dlevsha/Sites/nasgrate/src/Process/Base.php
+ /Users/dlevsha/Sites/nasgrate/src/Process/Console.php
+ /Users/dlevsha/Sites/nasgrate/src/Process/Server.php
+ /Users/dlevsha/Sites/nasgrate/src/template.sql
+ /Users/dlevsha/Sites/nasgrate/src/Util/Console.php
+ /Users/dlevsha/Sites/nasgrate/src/Util/Db.php
+ /Users/dlevsha/Sites/nasgrate/app/console.php
+ /Users/dlevsha/Sites/nasgrate/app/index.php
? Adding files...
+ /Users/dlevsha/Sites/nasgrate/README.md
? Adding main file: /Users/dlevsha/Sites/nasgrate/bin/nasgrate
? Generating new stub...
? Setting file permissions...
* Done.
After that, a file will appear in the project directory
nasgrate.phar
. Check that everything compiled fine.
$ ./nasgrate.phar
will display a description of the utility
Nasgrate is a console utility that let you organise database schema migration process at a consistent and easy way.
It supports mysql, mssql, postgresql, oracle and other databases
Usage:
php nasgrate [command] [options]
Command:
status - displays migration status
generate - creates new migration (migration file)
up:show - displays (but not executes) SQL-query, executed by migration update
...
Work with external resources
A feature of the work
phar
is that he is looking for all the resources inside his archive. In most cases, this is not a problem, because it was for this that we phar
did it so that it was independent of the environment. But there are a number of cases when resources inside the phar
archive need to work with external files. For example, Nasgrate - you need to read the configuration from a file
.environment
, write migration files and status files to an external directory. If we try to specify a relative path inside the project, for example, how
../.environment
, an error is generated, since there is phar
no such file inside . There are two options for solving this problem:
The first option is to map the external file to the internal space of the
phar
file.Phar::mount('phar://.environment', '/etc/nasgrate/.environment');
The problem is that you need to know exactly the absolute path to the file.
The second option is to specify the path from the current location of the
phar
file. Like that:define(DIR_RUN, dirname(Phar::running(false)));
Next, you either use Phar :: mount to map it into the internal space
phar
or simply specify the absolute path to the configuration file. Assume the configuration file is in the same folder asphar
define(DIR_RUN, dirname(Phar::running(false)));
Phar::mount('phar://.environment', DIR_RUN.'/.environment');
and then refer to it as a local file, or always refer to the absolute path.
There is one remark, I do not know whether this is a bug or a feature, but all directories connected through
Phar::mount
are in readonly mode and how to change this is not very clear. When addressing the absolute path, such problems do not arise.Another one seems like an obvious point, but which is worth paying attention to. The phar file contains the resources of your project and does not regulate the presence of connected libraries to php itself, its version, etc. That is, if you use some kind of php extension, for example PDO, or even install something from PECL, or use some features of a specific version of php, your phar will not contain information about the runtime. If you use for example traits from PHP 5.4, and the user has 5.3, then an error will be generated. You must check all required dependencies inside your application.
Related links: