Once you have installed phc (see Installation Instructions), run it by typing
phc --help
You should see
phc 0.2.0
Usage: phc [OPTIONS]... [FILES]...
-h, --help Print help and exit
--full-help Print help, including hidden options, and exit
-V, --version Print version and exit
GENERAL OPTIONS:
-v, --verbose Verbose output (default=off)
-c, --compile Compile (default=off)
--pretty-print Pretty print input according to the Zend style
guidelines (default=off)
--obfuscate Obfuscate input (default=off)
--run=STRING Run the specified plugin (may be specified multiple
times)
--r-option=STRING Pass option to a plugin (specify multiple flags in
the same order as multiple plugins - 1 option only
per plugin)
-d, --define=STRING Define ini entry (only affects -c and --include)
INPUT OPTIONS:
--read-xml=passname Assume the input is in XML format. Start processing
after the named pass
--include Parse included or required files at compile-time
(default=off)
COMPILATION OPTIONS:
-C, --c-option=STRING Pass option to the C compile (e.g., -C-g; can be
specified multiple times)
--extension=NAME Generate a PHP extension called NAME instead of a
standalone application
-O, --optimize=STRING Optimize (default=`0')
-o, --output=FILE Place executable into file FILE
-e, --execute Run executable after compiling (implies -c)
(default=off)
PRETTY PRINTING OPTIONS:
--next-line-curlies Output the opening curly on the next line instead of
on the same line (default=off)
--no-leading-tab Don't start every line in between with a
tab (default=off)
--tab=STRING String to use for tabs while unparsing
(default=` ')
--no-hash-bang Do not output any #! lines (default=off)Now write a very small PHP script, for example
<? echo "Hello world!"; ?>
and save it to helloworld.php. Then run phc:
phc --pretty-print helloworld.php
This should output a pretty-printed version of your PHP script back to standard output:
<?php echo "Hello world!"; ?>
You can see a list of options controlling the style of pretty printing, using the --full-help option.
phc can compile either executables or extensions. To compile an executable, phc creates C code, which it compiles and links to the PHP embed SAPI. Since it links to PHP, you have access to all of PHP's large built-in standard library. In order to compile the "hello world" executable from before, run
phc -c helloworld.php -o helloworld
This creates an executable helloworld, which can then be run
./helloworld
If you prefer to run your executable immediately after it compiles, use the -e. phc will compile your program, then immediately execute it. You can also view the C code generated by phc:
phc --generate-c helloworld.php > helloworld.c
One of the advantages of phc is that it can optimize your program. Using the -O flag, you can instruct phc to analyse your source code, and perform simple optimizations. On simple benchmarks, this can increase the speed of your application by 50%. To optimize:
phc -O2 -c helloworld.php -o helloworld
phc generates C code, which is then compiled by gcc. To see the command passed to gcc by phc, use the -v flag.
If you specify the -O flag, phc will also pass the -O flag to gcc, which will optimize your code further. The argument to the -O flag must therefore be usable by gcc, so it must be any of -O0 (default), -O1, -O2, -O3 or -Os. Consult the gcc manual for more details.
It is also possible to pass command-line arguments to gcc through phc, using the -C flag. For example, to disable inlining of the generated code by gcc, using -fno-inline:
phc -c -O2 helloworld.php -o helloworld -C-fno-inline
| Warning |
In order to compile web applications, it is currently necessary to alter your php.ini file, or have access to the root account. We welcome suggetions of a different method which avoids these requirements, especially if they would work in a shared hosting environment. |
| Warning |
This section is experimental. Please report any problems. |
We have created the command-line option --web-app, which will in the future automate the process of compiling a web application. Unfortunately, for now, please follow these steps.
We describe how to create and install an extension using the C code generated by phc. While we give an overview of creating extensions, significantly more detail can be found in the Zend Extension Writing Tutorial and in Extending and Embedding PHP.
To begin, create a new directory for the extension. We'll use ext/ in our example. Generate C code from helloworld.php using phc.
phc --generate-c helloworld.php > ext/helloworld.c
Create a new file, ext/config.m4, by copying the following, and changing instances of "helloworld" appropriately:
PHP_ARG_ENABLE(helloworld, whether to enable Hello World support, [ --enable-helloworld Enable Hello World support]) if test "$PHP_HELLOWORLD" = "yes"; then AC_DEFINE(HAVE_HELLOWORLD, 1, [Whether you have Hello World]) PHP_NEW_EXTENSION(helloworld, helloworld.c, $ext_shared) fi
In the previous section, we described using the PHP embed SAPI. If you installed a copy of PHP with --enable-embed enabled, it is important NOT to use that version for the following commands. Instead, you should the same version as your webserver uses. From the ext/ directory, run:
phpize --with-php-config=/usr/bin/php-config ./configure --enable-helloworld
Build and install the extension (if you dont have root, refer instead to Alternatives):
make sudo make install
In your web folder, replace the existing helloworld.php file contents with the following:
<?php
dl ("helloworld.so");
__MAIN__ ();
?>If the dl() function is not enabled in your php.ini file, enable it:
enable_dl = On;
Accessing helloworld.php should now work.
Instead of setting enable_dl, you can instead load the extension manually in your php.ini file:
extension=helloworld
You can also avoid installing the extension using sudo make install by adding an alternate extension directory:
extensions_dir="/full/path/to/ext"
phc can output an XML representation of the PHP script. You can use this representation if you want to process PHP scripts using tools in your desired framework, instead of using phc plugins. After processing the XML representation, phc can convert it back into PHP. To generate an XML version of a PHP script, run
./phc --dump-xml=ast helloworld.php > helloworld.xml
When reading the XML back in, all the usual features of phc are again available; in particular, it is possible to read an XML file, and write PHP syntax. To convert the XML file we just generated back to PHP syntax, run
./phc --read-xml=ast --pretty-print helloworld.xml
The generated XML should use the schema http://www.phpcompiler.org/phc-1.0. However, our XML schema is currently broken.
After parsing, phc converts a PHP script into an Abstract Syntax Tree (AST) (this is further explained in Chapter 3 in The phc Developer's Manual). This is very useful for processing PHP scripts which you wish to convert back into PHP. However, for some tasks, especially program analysis, a simpler form of the PHP script is more suitable. phc offers two other Internal Representations (IRs). The High-level Internal Representation (HIR) simplifies most expressions by assigning them to temporary variables. However, code represented in the HIR is still valid PHP. The Medium-level Internal Representation (MIR) converts HIR statements to simpler components, for example converting control-flow statements like the for-loop, into gotos. To view PHP in any of these forms, use the --dump option:
phc --dump=ast helloworld.php phc --dump=hir helloworld.php phc --dump=mir helloworld.php
Nearly all phc options work as well on the HIR and MIR as on the AST. For example, XML can be read and written:
phc --dump-xml=hir | ./myprog | phc --read-xml=hir
If you have a DOT viewer installed on your system (for example, graphviz), you can view the AST graphically. First, ask phc to output the AST in DOT format:
./phc --dump-dot=ast helloworld.php > helloworld.dot
You can then view the tree (helloworld.dot) using Graphviz. In most Unix/Linux systems, you should be able to do
dotty helloworld.dot
And you should see the tree; it should look similar to the tree shown in figure Figure 3-1.
phc has initial support for compile-time processing of PHP's include built-in. Enabling this feature inserts the included statements in the AST in the place of the include statement. Included functions, classes and interfaces become part of the file's top-level scope. In the event that phc is not able to process the include statement (for example, if the file cannot be found), a warning is issued, and the include statement is left in place. To enable this support, run
./phc --include script_with_includes.php
The include support is intended to mimic PHP's include built-in, as far as can be achieved at compile time. phc supports:
Moving included statements to the point at which include was called. Naturally, these statement's use the variable scope at the point at which they are included,
Preserving __FILE__ and __LINE__ statements,
Moving included functions to the %MAIN% class, and importing the included classes,
include, and require. If the specified file cannot be found, parsed, or if the argument to include is not a string literal, the include statement is left in place.
phc does not support:
Return values in included scripts. We intend to support these in the future. They will likely be supported in a later stage of the compilation process, instead of in the AST,
Calling include on anything other than a literal string containing the filename of a local file. This excludes variables and remote files. These may be supported when more static analyses are available,
include_once and require_once, as we cannot guarantee that the file to be included is not included elsewhere. These statements will not be processed, and combinations of include or require and include_once or require_once may cause incorrect behaviour with this option set,
Updating get_included_files() to reflect the included files.