Home arrow Support arrow Documentation arrow PHK Builder's Guide
Login Form
 : 
 : 

Lost Password?
No account yet? Register
Also listed on
PHK Builder's Guide

Views : 2286    


1. What you need
     1.1. PHP interpreter
     1.2. PHK_Creator
2. The Package Specification File
     2.1. Structure
     2.2. Subfile paths
     2.3. The command section
          2.3.1. Syntax
          2.3.2. Variables
               2.3.2.1. Pre-defined variables
                    2.3.2.1.1. PSF_DIR
                    2.3.2.1.2. Command arguments
          2.3.3. Modifiers
          2.3.4. Target syntax
          2.3.5. Commands
               2.3.5.1. add
               2.3.5.2. merge
               2.3.5.3. modify
               2.3.5.4. mount
               2.3.5.5. remove
               2.3.5.6. set
     2.4. The 'options' section
          2.4.1. Syntax
          2.4.2. Embedding an URL in a string
          2.4.3. PSF options
               2.4.3.1. author
               2.4.3.2. auto_umount
               2.4.3.3. crc_check
               2.4.3.4. compress_min_size
               2.4.3.5. compress_max_size
               2.4.3.6. compress_ratio_limit
               2.4.3.7. cli_run_script
               2.4.3.8. copyright
               2.4.3.9. distribution
               2.4.3.10. help_prefix
               2.4.3.11. include_path
               2.4.3.12. icon
               2.4.3.13. icon_bgcolor
               2.4.3.14. icon_width
               2.4.3.15. info_script
               2.4.3.16. lib_run_script
               2.4.3.17. license
               2.4.3.18. license_prefix
               2.4.3.19. max_php_version
               2.4.3.20. mime_types
               2.4.3.21. min_php_version
               2.4.3.22. mount_script
               2.4.3.23. name
               2.4.3.24. packager
               2.4.3.25. phpunit_package
               2.4.3.26. phpunit_test_package
               2.4.3.27. plain_prolog
               2.4.3.28. plugin_class
               2.4.3.29. release
               2.4.3.30. required_extensions
               2.4.3.31. requires
               2.4.3.32. summary
               2.4.3.33. tabs
               2.4.3.34. test_script
               2.4.3.35. umount_script
               2.4.3.36. url
               2.4.3.37. version
               2.4.3.38. web_access
               2.4.3.39. web_main_redirect
               2.4.3.40. web_run_script
          2.4.4. Options reference table
3. Building the package
4. Registering Automap symbols
     4.1. PHP source files detection
     4.2. Advanced directives
          4.2.1. declare
          4.2.2. ignore
          4.2.3. no-auto-index
          4.2.4. skip-blocks
5. Meta-packages
     5.1. Autoloading sub-packages
6. Examples
     6.1. PHPUnit
     6.2. The Zend Framework library
     6.3. The Zend Framework documentation
     6.4. Smarty

This document explains how to build a PHK package. If you just want to use an existing PHK package, refer to the PHK user's guide.

As this document is a reference guide, you may want to read this basic tutorial first.

Here is a global view of the build process :

1 - What you need

1.1 - PHP interpreter

In order to create a PHK package, you first need a PHP CLI interpreter, version 5.1.0 or more.

The PHP CLI interpreter is generally found in the bin subdirectory, under the PHP installation directory, or in /usr/bin. Its name is php on Unix/Linux, and php.exe on Windows.

In order to determine if your installation is suitable to build a PHK package, run the 'php -v' command in a shell. In the output, the first line must display version 5.1.0 or more, followed with the '(cli)' string.

1.2 - PHK_Creator

Then, you need the package creation software. It is provided as one file, named 'PHK_Creator.phk', which can be downloaded here (choose 'PHK Creator', then 'PHK Creator package').

There is no installation procedure for this file, as it is itself a PHK package. It can be saved anywhere in your file system, and does not have to be in your include path, nor in the shell's path. When building your package, you will just specify its absolute path on the command line.

2 - The Package Specification File

Now that your platform is ready, you will create a Package Specification File. This file is interpreted by the PHK_Creator software and contains every information PHK_Creator needs to build the package.

:note In the whole PHK documentation, PSF stands for Package Specification File.

2.1 - Structure

The PSF is a text file, created using any text editor (both Windows/CR-LF and Unix/LF line terminations are supported).

It is made up of two parts :

  • the command section, mandatory,
  • and the options section, optional.

2.2 - Subfile paths

Basically, a package contains a tree of virtual or pseudo files, called subfiles. The subfile tree is made up of directories and files, as a usual file system. In this tree, each node can be accessed through a unique canonical path (no symbolic link). This path is expressed using a Unix-like syntax :

  • the root path is known as '/'
  • The subdirectories are separated by '/' characters. In order to keep the compatibility with software using the DIRECTORY_SEPARATOR constant, the '\' character is also accepted as separator in subfile paths, but the PHP API will always return paths separated with '/' chars.

You will use this syntax when adding files to the archive and when specifying paths in options like '{cli/web/lib}_run_script' and others.

:note This 'Unix-like' syntax is used in every environment, even on Windows and other non-Unix ones.

2.3 - The command section

The first part in a PSF is the 'command section'. This section defines which files to include in the package.

2.3.1 - Syntax

Here is the syntax for the command section :

  • Commands are composed of words, separated by spaces or tabs.
  • The first word on a line is the command to run. The other words are modifiers and arguments.
  • Commands, modifiers, and arguments cannot contain any space or tab character.
  • Anything following a '#' char is considered as a comment and ignored.
  • A line can be continued by setting a '\' as its last character.

2.3.2 - Variables

Variables can be set, and then used in any subsequent command. Values are strings.

A variable is set through the 'set' command described below. Environment variables from the calling environment are also available in the PSF (the order is to search first in the internal table, then in the environment).

A variable's value can be used and substituted anywhere, using a Makefile-like syntax :

$(variable)

Example of using an environment variable : As you can see in its building kit, the PHPUnit API is built in 2 steps : first, we build the tree with phpdoc, and we build a PHK package from this tree. The location of this source tree is provided by the Makefile variables. So, the PSF receives this location through an environment variable. The Makefile runs this command :

TMP_DIR=$(TMP_DIR) php PHK_Creator.phk build PHPUnit_api.phk PHPUnit_api.psf

and the PSF contains this line :

merge -strip=true -compress=gzip / $(TMP_DIR)

2.3.2.1 - Pre-defined variables

The following predefined variables can be used in the command section :

2.3.2.1.1 - PSF_DIR

The PSF_DIR variable contains the name of the directory where the PSF lies.

You can use it to compose paths relative to the PSF location, avoiding to use an absolute path in your PSF. This way, you can move your source file tree without needing to modify your PSF, if the relative path remains the same.

2.3.2.1.2 - Command arguments

The command arguments are the arguments present on the command line after the PSF file name. If present, these arguments can be retrieved using a $(<number>) syntax, where <number> starts at 1.

Example, when running this command :

# php PHK_Creator.php build example.phk example.psf foo bar

every occurences of $(1) in the example.psf file will be replaced with 'foo' and $(2) will be replaced with 'bar'.

2.3.3 - Modifiers

Some commands support modifiers. Modifiers are strings of the form :

-<modifier>=<value>

They must be located between the command and its arguments. Modifiers are always optional (although a 'modify' command without modifiers is useless).

Here are the supported modifiers, their possible values, and their meanings :

Modifier Value Default  
-autoload true true When true, PHP source file(s) are scanned for symbols to populate the automap.
false
-strip true false When true, PHP source file(s) are stripped (filtered through php_strip_whitespace()) before being stored into the archive. Makes the package slightly faster and much smaller.
false
-compress none none The compression type to apply to the file(s). 
gzip
bzip2

:note The 'autoload' and 'strip' modifiers have an effect only for files which are identified as PHP source files at package creation time. For more information about this detection mechanism, see the 'Identifying PHP source files' chapter below.

:note The 'compress' modifier sets only the way the file will be stored in the package. When this file is read at runtime, it is transparently uncompressed. So, the 'compress' modifier's only effect is to reduce the package size, at the expense of a slower access to the file at runtime. You may also note that, at runtime, if a supported PHP cache system is present, the compression flag does not reduce the performance anymore, as the data is uncompressed only once to populate the cache. The only (minor) remaining drawback, in this case, is that it requires the corresponding extension (zlib and/or bzip2) in the runtime PHP interpreter.

Example:

# Under /foo/bar, every file will be gzip-compressed and PHP sources will be stripped

modify -compress=gzip -strip=true /foo/bar

2.3.4 - Target syntax

In the add and merge commands, the first argument is the virtual path where files will be added/merged. It can contain some (generally one) '&' character(s). Every occurence of a '&' in the target path will be replaced by the 'basename' of the corresponding source path (for unix admins, think of an automount table).

Example :

# This line defines these files in the virtual tree :
#    - /tests/test1.php
#    - /tests/parameters
#    - /tests/run.php

add /tests/& /sources/test1.php /etc/parameters /other/dir/run.php

:note The PSF supports file globbing. So, you can use specifications containing '*' and '?' characters as source paths.

:note There is no 'mkdir' command, as virtual directories are automatically created when needed by the add or merge commands.

2.3.5 - Commands

2.3.5.1 - add

add [modifiers] <virtual-path> <source-path1> [<source-path2> ... ]

Adds files or directories to the virtual tree, as <virtual-path>. If the source path is a directory, this directory and its content are recursively included.

Examples :

#-- Creates /info/help.txt and /info/help.htm

add /info/& $(SOURCE)/etc/help.txt $(SOURCE)/etc/help.htm

#-- Adds a whole source tree as /src

add /src $(SOURCE_DIR)

:note Adding a directory as virtual root (/) is not supported. Use the merge command instead.

2.3.5.2 - merge

merge [modifiers] <virtual-dir> <source-dir1> [<source-dir2> ... ]

Similar syntax to the add command but, here, we deal with directories, as source and target to merge together. Merging a source directory to an existing virtual one, consists of adding its content to the existing content, eventually replacing nodes when they already exists in the virtual tree.

Examples :

# Merges 2 source dirs together

merge / $(SOURCE1) $(SOURCE2)

:note When some parts of the source paths overlap, the order of source path specifications determines what the virtual tree will contain at last.

2.3.5.3 - modify

modify <modifiers> <virtual-path1> [<virtual-path2> ... ]

This command is used to change the modifiers associated with a part of the virtual tree. When <virtual-path> is a virtual directory, the modifiers are recursively applied.

:note Modifiers are used only after the whole PSF is processed. So, adding files with a given modifier is exactly the same as adding them without the modifier and then using modify to set it.

Example :

#-- Insert a source tree

merge / $(SOURCE)

#-- The params subdir is excluded from the automap and its files are compressed.

modify -autoload=false -compress=gzip /params

2.3.5.4 - mount

mount <mount-variable> <path of phk-archive>

This command is used when you want to copy some data from an existing package to a new one.

The <mount-variable> is the name of a variable which will receive the package's mount point. This mount point is computed by the mount process and will be used to access its subfiles. You can mount an unlimited number of existing packages at the same time, providing a different mount-variable for each.

After mounting a PHK package, its subfiles will be referred as 'phk:://$(mount-variable)/<path> in the subsequent add and merge commands.

An example will make it clearer :

#-- I want to extract the /etc virtual tree from an existing package,
#-- and insert this subtree as /params in a new one :

mount first_package /path/to/existing/package.phk

add /params phk://$(first_package)/etc

2.3.5.5 - remove

remove <virtual-path1> [ <virtual-path2> ... ]

Removes a part of the virtual tree we are currently building.

Why would we need to destroy something we are building ? Generally to implement an exclusion, when we want to include 'everything except...'.

Example:

#-- I want to include everything except the doc which is in $(SOURCE)/documentation.
# If the $(SOURCE) directory contains a lot of entries, it is easier to include everything,
# and then remove what we don't want.

merge / $(SOURCE)

remove /documentation

:note Removing a non-existent directory is useless, but accepted.

:note Trying to remove the virtual root ('remove /') is forbidden and triggers a fatal error.

2.3.5.6 - set

set <name> <value>

Sets a variable to be used in the rest of the command section.

Example :

set doc_dir $(PSF_DIR)/doc

add /documentation $(doc_dir)

2.4 - The 'options' section

This section, as its name implies, contains the packages's options. PSF generally contain an options section, even if not mandatory.

2.4.1 - Syntax

The section's start is identified by a line starting with '%options'. The section contains some PHP code, without the leading '<?php' and trailing '?>. This code can contain anything, but, at the end, it must return an array, with option names as keys, and option values as array values.

Example of an options section (excerpt from PHPUnit's PSF) :

#-- The command section

merge $(FLAGS) / $(PSF_DIR)/source

%options    #-- The package's options

return array(
    'name' => 'PHPUnit',
    'version' => '3.0.0',
    'release' => '6',
    'license' => 'BSD License <http://www.opensource.org/licenses/bsd-license.php>',
    'copyright' => 'Sebastian Bergman <http://sebastian-bergmann.de/>',
    'url' => 'http://www.phpunit.de',
    'packager' => 'F. Laupretre <mailto:francois@tekwire.net>',
    'icon' => '/phpunit-logo.gif',
    'license_prefix' => '/license',
    'test_script' => '/tests/test.phk'
    );

#-------- EOF --------

2.4.2 - Embedding an URL in a string

As you may see in the previous example, in option values, the strings displayed in webinfo mode only, like the license, author, packager, etc, can embed an URL, using the following syntax :

# Specify the URL between '<' and '>' characters

string <url>

When the string is displayed in HTML mode, the URL is extracted and displayed as an hypertext link.

Example :

'packager' => 'F. Laupretre <mailto:francois@tekwire.net>'
'license' => 'New BSD License <http://framework.zend.com/license>'

will give the following webinfo output :

Packager:  F. Laupretre
License:  New BSD License

2.4.3 - PSF options

  • The options which can contain an URL are flagged as 'string with optional URL'.
  • The options which don't have any impact on the package's behavior, except when displayed in webinfo mode, are flagged as '(Information only)'.

2.4.3.1 - author

Type: string with optional URL

The package's author (Information only)

2.4.3.2 - auto_umount

Type: Boolean - Default=false.

This parameter is used with the script referenced in the 'lib_run_script' option. When it is true, the PHK archive is automatically unmounted after the 'lib_run_script' is run, and the include/require returns null.

Using this parameter allows to define some kind of 'volatile' packages: they are available just the time to do what they have to, and then, they disappear.

Example : this parameter is used in the unit tests in the demonstration packages. We use the following architecture :

  • the test code is put in a PHK package, and this package is itself embedded in a higher level PHK package (with an 'autoload=false' modifier),
  • the test package is defined as the 'test_script' in the 1st level package,
  • in the tests package, AllTests.php is defined as 'lib_run_script' and auto_umount is set to true.

The result is that, when we request a '@test' on the main package :

  • the main package includes the test package because it is defined as its 'test_script',
  • once the tests package is mounted, it runs its 'lib_run_script' (AllTests.php) and executes the unit tests,
  • When the tests are complete, because of the auto_umount option, the tests package is unmounted.

2.4.3.3 - crc_check

Type: Boolean (default = false)

If set, a CRC check will be forced every time the package is mounted. By default, as it is too expensive, the CRC is checked only when accessing the webinfo mode, or before executing a built-in CLI command.

:note The file size is checked each time a package is run, as it allows to detect typical erroneous FTP ascii/binary conversions. Please note that PHK packages, even if they can be considered as PHP scripts and run as such, must never be modified by an external tool, such as a transfer conversion. So, when transferring a PHK file through FTP, you must use the binary mode.

:note As there is only one global CRC for the whole package, checking the package's CRC implies temporarily reading the whole package file in memory.

2.4.3.4 - compress_min_size

Type: numeric. Default = 0.

This parameter is used when building the package, and for every subfile with a compression flag. If the file size (before compression) is lower than this value, the file is not compressed.

2.4.3.5 - compress_max_size

Type: numeric. Default = no limit.

This parameter is used when building the package, and for every subfile with a compression flag. If the size of the file (uncompressed) is greater than this parameter's value, the file is not compressed. This parameter allows to avoid compressing files whose size makes them too heavy for on-the-fly decompression.

:note Remember that, when the PHK runtime environment contains a supported PHP cache, on-the-fly decompression does not reduce the performance anymore.

2.4.3.6 - compress_ratio_limit

Type: numeric (0-100), default=90

This parameter is used when building the package, and for every subfile with a compression flag. If the file's compression ratio is greater than this value, the file is left uncompressed.

Compression ratio = 100 * <compressed size> / <uncompressed size>

The primary purpose, here, is to avoid compressing already compressed files, compressed pictures, or very small files.

:note The default value is not 100% because :

  • 1. we consider that, when compressing a file, if the resulting compressed size is more than 90% of the original size, the gain in space is not worth the CPU power that will be consumed at decompression time.
  • 2. it allows to filter out some 'basic-RLE' compressed files (pictures generally), whose gzip-compressed size is still slightly smaller than their original size. There, again, we consider that a double compression scheme is not worth the CPU it will use.

2.4.3.7 - cli_run_script

Type: Subfile path

The script to run when the package is run in CLI mode.

2.4.3.8 - copyright

Type: string with optional URL

Copyright notice (Information only)

2.4.3.9 - distribution

Type: string with optional URL

Self-explanatory. Information only

2.4.3.10 - help_prefix

Type : Subfile path without suffix.

The 'help_prefix' option is used when searching for the help file to display (webinfo 'Help' page or CLI '@help' built-in command). In HTML, PHK looks for a subfile with a suffix of '.htm' or '.html'. If not found, it tries to find a file with a '.txt' suffix or with no suffix.

Example: if you give '/etc/help' as 'help_prefix', PHK will look in turn for these filenames:

In HTML :

  • 1. /etc/help.htm
  • 2. /etc/help.html
  • 3. /etc/help.txt
  • 4. /etc/help

In CLI mode :

  • 1. /etc/help.txt
  • 2. /etc/help

:note As a text file can be used in both mode, and an HTML file can be used only in HTML mode, provide a text file first and, optionally, an HTML file.

2.4.3.11 - include_path

:warn This feature is inhibited until a solution is found to the 'include path' issue.

2.4.3.12 - icon

Type: Subfile path

Defines the path of the subfile to take as the package's icon. In webinfo mode, this image is displayed on every page. When the user clicks on this image, he goes to the address specified with the url option.

:note If your image subfile's suffix is not defined in the PHK default mime table, you must provide its mime type using the mime_types option.

2.4.3.13 - icon_bgcolor

Type: String / HTML color spec

The background color to set around the icon in webinfo mode (see figure above).

This parameter can contain any value suitable for a '<td bgcolor=...' element.

2.4.3.14 - icon_width

Type: HTML cell width specification. Default = 150 pixels.

The width of the cell containing the icon in webinfo mode (see figure above).

This parameter can contain any value suitable for a '<td width=...' element (absolute, percentage, etc).

2.4.3.15 - info_script

Type: Subfile path

The script to run when the webinfo Home page is displayed, instead of the default information.

:note As any PHP script, this subfile can contain PHP code or just some static HTML content.

2.4.3.16 - lib_run_script

Type: Subfile path

The script to run when the PHK archive is included from another PHP script.

2.4.3.17 - license

Type: string with optional URL

Information only. This parameter contains the license's name and, by convention, should contain an URL to the license home page.

Example:

'license' => 'New BSD License <http://framework.zend.com/license>'

2.4.3.18 - license_prefix

Type : Subfile path without suffix.

The same as 'help_prefix', but for the license.

2.4.3.19 - max_php_version

Type: String

The maximum PHP version this package supports.

2.4.3.20 - mime_types

Type: Array

This array contains additonal mime types to associate with file suffixes. These mime types are used in webinfo mode when displaying a subfiles's content, and in execution mode when accessing subfiles directly through the web (direct web access).

By default, PHK knows the following suffixes :

Suffix Mime type
gif image/gif
jpeg image/jpeg
jpg image/jpeg
png image/png
psd image/psd
bmp image/bmp
tif image/tiff
tiff image/tiff
iff image/iff
wbmp image/vnd.wap.wbmp
ico image/x-icon
xbm image/xbm
txt text/plain
htm text/html
html text/html
css text/css
php application/x-httpd-php
phk application/x-httpd-php
pdf application/pdf
js application/x-javascript
swf application/x-shockwave-flash
xml application/xml
xsl application/xml
xslt application/xslt+xml
mp3 audio/mpeg
ram audio/x-pn-realaudio
svg image/svg+xml

:note Through this option, you can redefine suffixes from the default mime table.

Example: if you want to access some MS Word™ and MS Excel™ documents via direct web access, you will need to set the following option :

...
'mime_types' => array('doc' => 'application/msword',
                      'xls' => 'application/vnd.ms-excel'),
...

2.4.3.21 - min_php_version

Type: String

The minimum PHP version this package supports.

2.4.3.22 - mount_script

Type: Subfile path

This script is called at the end of the mount process.

If the 'mount_script' decides that the package cannot run in this environment, for any reason, it can 'refuse' the mount by throwing an exception.

:note When the 'mount_script' is run, the plugin object, if any, is not created yet, so it cannot be called.

2.4.3.23 - name

Type : String

The package's name (Information only)

2.4.3.24 - packager

Type: string with optional URL

The package's builder (Information only)

2.4.3.25 - phpunit_package

Type: Subfile path

This option is used, along with phpunit_test_package, when the PHPUnit test package does not contain the PHPUnit package. In this case, the container package must contain the PHPUnit package, generally flagged as 'autoload=false', not to uselessly export the PHPUnit symbols to the container's automap. In this case, you must explicitely define where the PHPUnit package lies through this option.

:note You can build the PHPUnit package yourself or download it from the download area.

2.4.3.26 - phpunit_test_package

Type: Subfile path

This option, introduced with PHK 1.4, should be used when your unit tests use PHPUnit, instead of the older test_script option.

This option contains the path of a subpackage containing your test file tree.

When using this option, you should not set the test_script option.

2.4.3.27 - plain_prolog

Type: Boolean - Default=false

When creating a package, this parameter defines if we strip the PHP prolog (e.g. run it through php_strip_whitespace()), which is the default, or if we keep it as-is.

This flag is used when encountering a bug in the PHK runtime code because code stripped through php_strip_whitespace() does not return valid line numbers in error messages. If you get an error located in the PHK runtime layer (by opposition to virtual files whose paths start with 'phk://'), regenerate your package with this flag on and reproduce your error. Now, your error message should display a valid line number. Without this number, it will be very hard for us to investigate the problem.

Except in this case, this parameter should not be set as it makes the generated PHK archive larger and slower.

2.4.3.28 - plugin_class

Type : class name.

For more information on this parameter, please read this document.

2.4.3.29 - release

Type : String

Self-explanatory. Information only.

2.4.3.30 - required_extensions

Type: Array

A list of PHP extensions required by the package. Each time the package is run, PHK checks that all these required extensions are present or can be loaded by dl(). If it is not the case, it triggers a fatal error.

This behavior was chosen because we consider it cleaner than getting a cryptic error message when a missing function or class is called. The philosophy here is : if your package is not compatible with your runtime environment, you must know it as early as possible (without having to test every features).

:note If some of the package's subfiles are compressed, the corresponding extensions ('zlib' and/or 'bz2') are automatically appended to the list of required extensions.

:note As of PHK 1.4.0, subpackage's required extensions are automatically recursively added to the list of required extensions in the container package(s).

:note The extensions listed here are 'universal' extensions names, without file suffixes (ex: 'iconv', 'gd', etc.). PHK automatically determines the filename to dl().

2.4.3.31 - requires

Type: String

What the package requires to run (Information only).

2.4.3.32 - summary

Type: String

Self-explanatory. Information only

2.4.3.33 - tabs

Type Array.

Additional tabs to display in webinfo mode.

Each array element corresponds to one additional tab. The key is the string to display in the tab, and the value gives the action to associate with this tab.

To be completed... For a list of the supported actions, see the PHK_Webinfo.php file in the PHK_Creator building kit, and view an example in the Smarty demonstration package and Smarty PHK building kit.

2.4.3.34 - test_script

Type: Subfile path

A script to call when the user displays the webinfo 'test' page, or when it runs the '@test' built-in command.

:note This is the low-level interface to the unit tests feature. As of PHK 1.4, you can use a new mechanism, specifically intended for PHPUnit tests, via the phpunit_test_package and phpunit_package options.

2.4.3.35 - umount_script

Type: Subfile path

This script is called just before a PHK archive is unmounted.

When it is run, the plugin object, if any, is already unset, but the automap is still active.

:note This script is called only when explicitely calling PHK_Mgr::umount(). When the program ends, no umount script is executed.

2.4.3.36 - url

The URL to call when the user clicks on the package's icon in webinfo mode.

2.4.3.37 - version

Type: String

Self-explanatory. Information only.

2.4.3.38 - web_access

Type: Array of subfile paths

A list of subfile paths authorized for web direct access.

If an authorized path is a directory, everything under this node is authorized. So, putting '/' in the list gives an open access to the whole file tree.

2.4.3.39 - web_main_redirect

Type: Boolean - Default=false.

In web direct access mode, when the URL we receive does not contain any subfile path, or if the requested subfile path is not authorized, PHK tries to execute the script defined by the 'web_run_script' option. Then :

  • If the 'web_main_redirect' option is set, PHK returns an HTTP 301/Redirect with the URL of the web_run_script, so that the browser does a redirection.
  • If the 'web_main_redirect' option is not set, the web_run_script is transparently executed. In this case, the browser has no way to know which 'real' URL was executed.

The choice of the value to give to this parameter depends on the software you package. If the web_run_script uses relative links, it may be better to set the web_main_redirect option, as relative links are resolved by the browser, but there is no simple rule for this.

2.4.3.40 - web_run_script

Type: Subfile path

The script to run, in web direct access mode, when :

  • the URL we receive does not contain any subfile path,
  • or when the requested subfile path is not authorized (by the 'web_access' option).

2.4.4 - Options reference table

Option name Type Default Info
only
Expert
only
Comments
authorString (URL) Empty :check  
auto_umountBoolean False  
crc_checkBoolean False  
test_scriptSubfile path <none>  
cli_run_scriptPath <none>  
compress_max_sizeInteger No limit  Unit = bytes
compress_min_sizeInteger 0  Unit = bytes
compress_ratio_limitPercentage 90  
copyrightString (URL) Empty :check  
distributionString (URL) Empty :check  
help_prefixSubfile path <none> :check  
iconSubfile path <none> :check  
icon_bgcolorHTML color spec <auto> :check  
icon_widthHTML width spec <auto> :check  
info_scriptPath <none> :check  
lib_run_scriptSubfile path <none>  
licenseString (URL) Empty :check  
license_prefixSubfile path <none> :check  
max_php_versionString <none>   
mime_typesArray Empty  Keys=suffix ; values=mime types
min_php_versionString <none>   
mount_scriptSubfile path <none> :check  
nameString <auto> :check  Default = PHK file name
packagerString (URL) Empty :check  
phpunit_packageSubfile path <none>     
phpunit_test_packageSubfile path <none>     
plain_prologBoolean False :warn
plugin_classClass name <none>  
prolog_code_creatorBoolean False :warn
releaseString Empty :check  
required_extensionsArray Empty  Extension names without file suffix
requiresString + URL Empty :check  
summaryString + URL Empty :check  
tabsArray Empty :check  Key=String to display in tab;
Value = Subfile path
umount_scriptSubfile path <none>  
urlURL<none> :check  
versionString Empty :check  
web_accessArray Empty  Array of subfile paths
web_main_redirectBoolean False  
web_run_scriptSubfile path <none>  

3 - Building the package

PHK packages are built in command-line mode. On Unix, you use a shell command. On windows, you start a command window.

The syntax to build a package is :

php <path to PHK_Creator.phk> build  <dest-file> <PSF> [args]

where :

  • <path to PHK_Creator.phk> is the absolute path to the PHK_Creator.phk file,
  • <PSF> is the path to the PSF you just created,
  • <dest-file> is the path where the new PHK package will be created (if a previous file exists with the same name, it will be overwritten),
  • [args] are optional arguments the PSF can retrieve using the $(<number>) syntax.

if the PHP interpreter is not in your path, you must replace 'php' with its absolute path.

During the build process, PHK_Creator displays some information. Here is some typical output :

Processing /license.txt
    Compressing (zlib)
Processing /smarty-logo-orange.gif
    Compressing (zlib)
    No compression: Compression ratio exceeded (100%)
Processing /libs/Config_File.class.php
    Registering Automap symbols
    Stripping source
Processing /libs/Smarty.class.php
    Registering Automap symbols
    Stripping source
Processing /libs/Smarty_Compiler.class.php
    Registering Automap symbols
    Stripping source
Processing /libs/debug.tpl
...
Processing /tabs/TODO
    Compressing (zlib)
--- Sections
Processing /FTREE
Processing /AUTOMAP
Processing /STATIC/tabs/left.gif
Processing /STATIC/tabs/right.gif
Processing /STATIC/tabs/bottom.gif
Processing /STATIC/tabs/tabs.css.php
Processing /STATIC/phk_logo.png
Processing /OPTIONS
Processing /BUILD_INFO
Writing PHK file to Smarty.phk

For more examples, see the 'hello, world' tutorial and the demo packages' building kits.

4 - Registering Automap symbols

In most cases, symbol registration is a transparent process and you don't have to care about it. The following information can be used for troubleshooting or for advanced cases.

4.1 - PHP source files detection

When creating the package, PHK_Creator needs to determine which files must be considered as PHP source files. Only these files will be scanned for symbols, except if they were flagged as '-autoload=false' in the PSF.

The default rule is to consider as PHP source files :

  • the files whose suffix contains the 'php' string,
  • and the files whose mime type is explicitely set to 'application/x-httpd-php'.

So, if you want to force registration on PHP source files with unusual suffixes, add these suffixes to the mime-types option in the PSF, and give them an 'application/x-httpd-php' mime type. Then, PHK will consider them as PHP sources.

:note When embedding a PHK package (see 'Meta-packages' below), this is detected and PHK packages are handled in a specific way (direct transfer between symbol maps).

4.2 - Advanced directives

These directives are considered as 'advanced' as, in most cases, the registration process is transparent and does not need any explicit configuration. But, for special cases, it is possible to force or inhibit the declaration of a symbol in a script file.

These directives can be added to PHP source files as specially formatted comments. The syntax is :

// *<Automap>: command arguments

Note that :

  • there must be exactly one space between '//' and '*'.
  • The directive can appear anywhere on any line in the file, as they are all read before the scan starts.

4.2.1 - declare

Explicitely declares a symbol as defined by this source file.

Syntax :

// *<Automap>: declare <type> <symbol>

where <type> is a letter from this list :

  • 'F' : function
  • 'C' : Constant
  • 'L' : Class or interface

Examples :

#-- Declares a class named 'MyClass'

// *<Automap>: declare L MyClass

#-- Declares a constant

// *<Automap>: declare C A_NEW_CONSTANT

4.2.2 - ignore

This directive will instruct the registration process to explicitely ignore a symbol that it would normally register. Use this when you don't want a specific symbol to go to the automap.

The syntax is similar to 'declare' :

// *<Automap>: ignore <type> <symbol>

4.2.3 - no-auto-index

This directive does not take any argument. When present in a file, the file is not scanned for symbols.

Usage :

// *<Automap>: no-auto-index

4.2.4 - skip-blocks

The default behavior of the registration process is to extract the symbols from the code, even if they are inside a conditional block.

When the 'skip-blocks' directive is present in a file, the conditional blocks are not searched for symbols any more.

Example :

# Here the MyClass class won't be registered.

// *<Autoload>: skip-blocks

if (!class_exists('MyClass',false))
{
class MyClass {}
}

:note Symbols defined inside a function or class are always ignored by the registration process, as including the file does not always declare the symbol. If you want these embedded symbols to be in the map, declare them explicitely using '<Automap>:declare' statements.

Example :

// In the following code, the 'define_foo_gateway' function will
// be registered, but not the 'foo_gateway' class.

function define_foo_gateway()
{
if (!class_exists('foo_gateway',0)) {
    class foo_gateway
    {
    ...

5 - Meta-packages

Meta-packages are PHK packages including another package as a subfile.

There are several cases where meta-packages are interesting :

  • When embedding unit tests with a package, it allows to keep the code and automaps separate. With such an approach, embedding the unit tests does not imply any speed penalty when running the package as, until the tests are executed, the test package is totally ignored. Separating automaps is most important point here, too.
  • You may group several PHK packages, with or without dependencies. This way, as they are merged in a single package file, it is easier to maintain, distribute, install, etc. It is also faster because they won't be mounted until one of their symbols is required, and only the needed packages will be loaded.
  • In a similar way, it can allow to package an application with its dependencies.
  • And probably a lot of other cases, as it is a very powerful feature.

5.1 - Autoloading sub-packages

You can specify whether an embedded package exports its symbols to the higher-level map or not, using the 'autoload' modifier on the embedded package's entry. By default, the symbols are exported to the upper-level package.

When symbols are exported, the including package will automatically mount an embedded package when one of its symbols is referenced. So, as this feature is recursive, by default, every symbol of every embedded package is present in the upper-layer map and can be autoloaded, even if the corresponding package is not currently mounted.

Sometimes (for instance when embedding a package containing unit tests), you don't want the embedded package's symbols to be merged into the main map (see the Zend framework library and PHPUnit demonstration packages for examples). In such cases, you will include the embedded packages with a '-autoload=false' modifier.

6 - Examples

The building kits for these packages are available here.

6.1 - PHPUnit

PHPUnit was the first candidate, as it is used by other demonstration packages to run their unit tests.

PHPUnit is a well programmed, clean OO software. So, it is easy to package. Here are the main steps :

  • PHPUnit is totally OO except a single function, named PHPUnit_Util_ErrorHandler. So, we had to explicitely require it through Automap::require_function() before it is referenced in Framework/TestResult.php.
  • We don't include the '/Samples' subdirectory'.
  • We exclude files in /Util/Skeleton to be scanned for symbols as they are just templates.
  • We filter every file through a very basic filter to :
    • remove most 'require' directives,
    • transform 'class_exists(...,false)' calls to 'class_exists(...,true)'.
    • Transform 'realpath(__FILE__)' to '__FILE__' (realpath() does not support stream wrappers).

6.2 - The Zend Framework library

The process is essentially the same as for PHPUnit, except a pair of code changes to make it compatible with PHK.

We also had to modify the Loader method to call Automap before trying a filename-based search.

The unit tests are included as an embedded package. It allows to keep them separate from the main code, and to load the unit tests package only when we want to run them. In such a case, it is essential to keep symbols in separate maps, and the unit tests package must not export its symbols to the main map. This example is especially interesting as the test package itself includes the PHPUnit package, providing a three-level meta-package.

:note Please note that some unit test fail, when run under PHK, mostly because the PHK virtual tree is read-only, and some tests try to create temporary files in this tree.

The test package is built with uncompressed subfiles. Then we compress it as a whole when we insert it in the main package. This way, the resulting package is smaller and faster.

6.3 - The Zend Framework documentation

The documentation was split in API and reference, and then by language. As a result, we get 6 independant packages.

These packages are quite basic and support web direct access mode only.

6.4 - Smarty

Quite the same as ZF and PHPUnit, except :

  • Smarty.class.php needs a small change because we want PHK URIs to be considered as absolute paths.
  • the package can be used as an example of webinfo tab addition.

Last update : Saturday, 19 January 2008

   
Quote this article in website
Print
Send to friend
Related articles
Save this to del.icio.us

Users' Comments  RSS feed comment
 

Average user rating

   (0 vote)

 


Add your comment
Name
E-mail
Title  
 
Comment
  Available characters:  
   Notify me of follow-up comments
  This image contains a scrambled text, it is using a combination of colors, font size, background, angle in order to disallow computer to automate reading. You will have to reproduce it to post on my homepage
Enter what you see:

   
   

No comment posted



mXcomment 1.0.3 © 2007-2010 - visualclinic.fr
License Creative Commons - Some rights reserved
 

All site content is (C) F. Laupretre (wishlist) - Unauthorized reproduction forbidden without express written permission.
Joomla! is Free Software released under the GNU/GPL License. - Original template design: JLM@joomlabox