/
fileformat.xml
515 lines (514 loc) · 16 KB
/
fileformat.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<chapter xml:id="phar.fileformat" xmlns="http://docbook.org/ns/docbook">
<title>What makes a phar a phar and not a tar or a zip?</title>
<section xml:id="phar.fileformat.ingredients" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Ingredients of all Phar archives, independent of file format</title>
<para>
All Phar archives contain three to four sections:
<orderedlist>
<listitem>
<para>a stub</para>
</listitem>
<listitem>
<para>a manifest describing the contents</para>
</listitem>
<listitem>
<para>the file contents</para>
</listitem>
<listitem>
<para>[optional] a signature for verifying Phar integrity (phar file format only)</para>
</listitem>
</orderedlist>
</para>
</section>
<section xml:id="phar.fileformat.stub" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Phar file stub</title>
<para>
A Phar's stub is a simple PHP file. The smallest possible stub follows:
</para>
<para>
<programlisting role="php">
<![CDATA[<?php __HALT_COMPILER();]]>
</programlisting>
</para>
<para>
A stub must contain as a minimum, the <literal>__HALT_COMPILER();</literal> token
at its conclusion. Typically, a stub will contain loader functionality
like so:
</para>
<para>
<programlisting role="php">
<![CDATA[
<?php
Phar::mapPhar();
include 'phar://myphar.phar/index.php';
__HALT_COMPILER();
]]>
</programlisting>
</para>
<para>
There are no restrictions on the contents of a Phar stub, except for the requirement
that it conclude with <literal>__HALT_COMPILER();</literal>. The closing PHP tag
<literal><![CDATA[?>]]></literal> may be included or omitted, but there can be
no more than 1 space between the <literal>;</literal> and the close tag
<literal><![CDATA[?>]]></literal> or the phar extension will be unable
to process the Phar archive's manifest.
</para>
<para>
In a tar or zip-based phar archive, the stub is stored in the
<literal>.phar/stub.php</literal> file. The default stub for phar-based
Phar archives contains approximately 7k of code to extract the contents
of the phar and execute them. See <function>Phar::createDefaultStub</function>
for more detail.
</para>
<para>
The phar alias is stored in a tar or zip-based phar archive in the
<literal>.phar/alias.txt</literal> file as plain text.
</para>
</section>
<section xml:id="phar.fileformat.comparison" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Head-to-head comparison of Phar, Tar and Zip</title>
<para>
What are the good and the bad things about the three supported file formats in
the phar extension? This table attempts to address that question.
<table>
<title>Feature matrix: Phar vs. Tar vs. Zip</title>
<tgroup cols="4">
<thead>
<row>
<entry>Feature</entry>
<entry>Phar</entry>
<entry>Tar</entry>
<entry>Zip</entry>
</row>
</thead>
<tbody>
<row>
<entry>Standard File Format</entry>
<entry>No</entry>
<entry>Yes</entry>
<entry>Yes</entry>
</row>
<row>
<entry>Can be executed without the Phar Extension
<link linkend="phar.fileformat.phartip">[1]</link>
</entry>
<entry>Yes</entry>
<entry>No</entry>
<entry>No</entry>
</row>
<row>
<entry>Per-file compression</entry>
<entry>Yes</entry>
<entry>No</entry>
<entry>Yes</entry>
</row>
<row>
<entry>Whole-archive compression</entry>
<entry>Yes</entry>
<entry>Yes</entry>
<entry>No</entry>
</row>
<row>
<entry>Whole-archive signature validation</entry>
<entry>Yes</entry>
<entry>Yes</entry>
<entry>Yes</entry>
</row>
<row>
<entry>Web-specific application support</entry>
<entry>Yes</entry>
<entry>Yes</entry>
<entry>Yes</entry>
</row>
<row>
<entry>Per-file Meta-data</entry>
<entry>Yes</entry>
<entry>Yes</entry>
<entry>Yes</entry>
</row>
<row>
<entry>Whole-Archive Meta-data</entry>
<entry>Yes</entry>
<entry>Yes</entry>
<entry>Yes</entry>
</row>
<row>
<entry>Archive creation/modification
<link linkend="phar.fileformat.phartip2">[2]</link>
</entry>
<entry>Yes</entry>
<entry>Yes</entry>
<entry>Yes</entry>
</row>
<row>
<entry>Full support for all stream wrapper functions</entry>
<entry>Yes</entry>
<entry>Yes</entry>
<entry>Yes</entry>
</row>
<row>
<entry>Can be created/modified even if phar.readonly=1
<link linkend="phar.fileformat.phartip3">[3]</link>
</entry>
<entry>No</entry>
<entry>Yes</entry>
<entry>Yes</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para xml:id="phar.fileformat.phartip">
<tip>
<para>
[1] PHP can only directly access the contents of a Phar archive
without the Phar extension if it is using a <literal>stub</literal>
that extracts the contents of the phar archive. The stub
created by <function>Phar::createDefaultStub</function> extracts
the phar archive and runs its contents from a temporary directory
if no phar extension is found.
</para>
</tip>
</para>
<para xml:id="phar.fileformat.phartip2">
<tip>
<para>
[2] All write access requires <literal>phar.readonly</literal> to
be disabled in php.ini or on the command-line directly.
</para>
</tip>
</para>
<para xml:id="phar.fileformat.phartip3">
<tip>
<para>
[3] Only tar and zip archives without <literal>.phar</literal> in their
filename and without an executable stub <literal>.phar/stub.php</literal>
can be created if phar.readonly=1.
</para>
</tip>
</para>
</section>
<section xml:id="phar.fileformat.tar" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Tar-based phars</title>
<para>
Archives based on the tar file format follow the more modern USTAR
file format. The design of the tar file header makes them more efficient
to access than the zip file format, and almost as efficient as the phar
file format. File names are limited to 255 bytes, including
full path within the phar archive. There is no limit on the number of files
within a tar-based phar archive. These archives can fully compressed in
gzip or bzip2 format and still be executed by the Phar extension.
</para>
<para>
There is limited support for reading tarballs in pax interchange format,
but all recognized pax headers (currently, typeflag <literal>x</literal> and
<literal>g</literal>) are silently ignored.
There is also limited support for GNU Tar Archives;
currently, <literal>././@LongLink</literal> headers are resolved.
</para>
<para>
To compress an entire archive, use <function>Phar::compress</function>.
To decompress an entire archive, use <function>Phar::decompress</function>.
</para>
</section>
<section xml:id="phar.fileformat.zip" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Zip-based phars</title>
<para>
Archives based on the zip file format support several features built into
the zip file format. Per-file and whole-archive metadata is stored in
the zip file comment and zip archive comment as a serialized string. Pre-existing
zip comments will be successfully read as a string. Per-file compression
read/write is supported with zlib DEFLATE compression, and read access is supported
with bzip2 compression. There is no limit on the number of files
within a zip-based phar archive. Empty directories are stored in the zip archive
as files with a trailing slash like <literal>my/directory/</literal>
</para>
</section>
<section xml:id="phar.fileformat.phar" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Phar File Format</title>
<para>
The phar file format is literally laid out as stub/manifest/contents/signature, and
stores the crucial information of what is included in the phar archive in its
<literal>manifest</literal>.
</para>
<para>
The Phar manifest is a highly optimized format that allows per-file
specification of file compression, file permissions, and even user-defined
meta-data such as file user or group. All values greater than 1 byte are stored
in little-endian byte order, with the exception of the API version, which
for historical reasons is stored as 3 nibbles in big-endian order.
</para>
<para>
All unused flags are reserved for future use, and must not be used
to store custom information. Use the per-file meta-data facility
to store customized information about particular files.
</para>
<para>
The basic file format of a Phar archive manifest is as follows:
</para>
<para>
<table>
<title>Global Phar manifest format</title>
<tgroup cols="2">
<thead>
<row>
<entry>Size in bytes</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>4 bytes</entry>
<entry>Length of manifest in bytes (1 MB limit)</entry>
</row>
<row>
<entry>4 bytes</entry>
<entry>Number of files in the Phar</entry>
</row>
<row>
<entry>2 bytes</entry>
<entry>API version of the Phar manifest (currently 1.0.0)</entry>
</row>
<row>
<entry>4 bytes</entry>
<entry>Global Phar bitmapped flags</entry>
</row>
<row>
<entry>4 bytes</entry>
<entry>Length of Phar alias</entry>
</row>
<row>
<entry>??</entry>
<entry>Phar alias (length based on previous)</entry>
</row>
<row>
<entry>4 bytes</entry>
<entry>Length of Phar metadata (<literal>0</literal> for none)</entry>
</row>
<row>
<entry>??</entry>
<entry>Serialized Phar Meta-data, stored in <function>serialize</function> format</entry>
</row>
<row>
<entry>at least 24 * number of entries bytes</entry>
<entry>entries for each file</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
</section>
<section xml:id="phar.fileformat.flags" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Global Phar bitmapped flags</title>
<para>
Here are the bitmapped flags currently recognized by the Phar extension
for the global Phar flat bitmap:
</para>
<para>
<table>
<title>Bitmap values recognized</title>
<tgroup cols="2">
<thead>
<row>
<entry>Value</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>0x00010000</literal></entry>
<entry>If set, this Phar contains a verification signature</entry>
</row>
<row>
<entry><literal>0x00001000</literal></entry>
<entry>
If set, this Phar contains at least 1 file that
is compressed with zlib DEFLATE compression
</entry>
</row>
<row>
<entry><literal>0x00002000</literal></entry>
<entry>
If set, this Phar contains at least 1 file that
is compressed with bzip2 compression
</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
</section>
<section xml:id="phar.fileformat.manifestfile" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Phar manifest file entry definition</title>
<para>
Each file in the manifest contains the following information:
</para>
<para>
<table>
<title>Phar Manifest file entry</title>
<tgroup cols="2">
<thead>
<row>
<entry>Size in bytes</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>4 bytes</entry>
<entry>Filename length in bytes</entry>
</row>
<row>
<entry>??</entry>
<entry>Filename (length specified in previous)</entry>
</row>
<row>
<entry>4 bytes</entry>
<entry>Un-compressed file size in bytes</entry>
</row>
<row>
<entry>4 bytes</entry>
<entry>Unix timestamp of file</entry>
</row>
<row>
<entry>4 bytes</entry>
<entry>Compressed file size in bytes</entry>
</row>
<row>
<entry>4 bytes</entry>
<entry>CRC32 checksum of un-compressed file contents</entry>
</row>
<row>
<entry>4 bytes</entry>
<entry>Bit-mapped File-specific flags</entry>
</row>
<row>
<entry>4 bytes</entry>
<entry>Serialized File Meta-data length (<literal>0</literal> for none)</entry>
</row>
<row>
<entry>??</entry>
<entry>Serialized File Meta-data, stored in <function>serialize</function> format</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
Note that as of API version 1.1.1, empty directories are stored as filenames
with a trailing slash like <literal>my/directory/</literal>
</para>
<para>
The File-specific bitmap values recognized are:
</para>
<para>
<table>
<title>Bitmap values recognized</title>
<tgroup cols="2">
<thead>
<row>
<entry>Value</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>0x000001FF</literal></entry>
<entry>
These bits are reserved for defining specific file permissions
of a file. Permissions are used for <function>fstat</function>
and can be used to recreate desired permissions upon extraction.
</entry>
</row>
<row>
<entry><literal>0x00001000</literal></entry>
<entry>
If set, this file is compressed with zlib DEFLATE compression
</entry>
</row>
<row>
<entry><literal>0x00002000</literal></entry>
<entry>
If set, this file is compressed with bzip2 compression
</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
</section>
<section xml:id="phar.fileformat.signature" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Phar Signature format</title>
<para>
Phars containing a signature always have the signature appended to the
end of the Phar archive after the loader, manifest, and file contents.
The signature formats supported at this time are MD5, SHA1, SHA256, SHA512,
and OPENSSL.
</para>
<para>
<table>
<title>Signature format</title>
<tgroup cols="2">
<thead>
<row>
<entry>Length in bytes</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>varying</entry>
<entry>
The actual signature, 20 bytes for an SHA1 signature,
16 bytes for an MD5 signature, 32 bytes for an SHA256 signature,
and 64 bytes for an SHA512 signature. The length of an OPENSSL
signature depends on the size of the private key.
</entry>
</row>
<row>
<entry>4 bytes</entry>
<entry>
Signature flags. <literal>0x0001</literal> is used to
define an MD5 signature, <literal>0x0002</literal> is used
to define an SHA1 signature, <literal>0x0003</literal> is used
to define an SHA256 signature, and <literal>0x0004</literal> is
used to define an SHA512 signature. The SHA256 and SHA512 signature
support is available as of API version 1.1.0.
<literal>0x0010</literal> is used to define an OPENSSL signature, what
is available as of API version 1.1.1, if OpenSSL is available.
</entry>
</row>
<row>
<entry>4 bytes</entry>
<entry>
Magic <literal>GBMB</literal> used to define the presence of a signature.
</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
</section>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->