Symisc PH7 Engine
An Embeddable PHP5 Engine

A Very quick introduction to PH7.

PH7 is a in-process software library that implements a highly-efficient embeddable bytecode compiler and a virtual machine for the PHP programming language. In other words, PH7 is a PHP engine which allow the host application to compile and execute PHP scripts in-process. PH7 is to PHP what SQLite is to SQL.

PH7 is the ideal library for enhancing your application (i.e: SCM, Server, CMS, Control panel, Search engine, etc.) or device (i.e: router, set-top box, etc.) with dynamic web interfaces, with all benefits and power of the PHP(5) programming language without the overhead uncured by the insecure CGI mechanism and it's high costs such as process creation (fork(), exec()) since PH7 run in-process.

As an embedded interpreter, it allows multiple interpreter states to coexist in the same program, without any interference between them. Programmatically, foreign functions in C can be added and values can be defined in the PHP environment. Being a quite small program, it is easy to comprehend, get to grips with, and use.

PH7 is 100% hand-coded, written in ANSI C, thread-safe, full reentrant, compiles unmodified and should run in any platform including restricted embedded device with a C compiler. PH7 is extensively tested on Windows and UNIX systems especially Linux, FreeBSD, Oracle Solaris and Mac OS X.

PH7 in 5 minutes or less

Here is what you do to start experimenting with the PH7 engine without having to do a lot of tedious reading and configuration:

download The Code

Get a copy of the last public release of the PH7 engine (A single 1.9MB C file). Visit the download page for more information.

Write Programs That Use PH7

Below is a simple C program that demonstrates how to use the C/C++ interface to PH7. This program compile and execute the following PHP script.

   echo 'Welcome guest'.PHP_EOL;
   echo 'Current system time is: '.date('Y-m-d H:i:s').PHP_EOL;
   echo 'and you are running '.php_uname();

That is, this simple PHP script when running should display a greeting message, the current system time and the host operating system. A typical output of this program would look like this:

Welcome guest

Current system time is: 2012-09-14 10:08:44
and you are running Microsoft Windows 7 localhost 6.1 build 7600 x86

Here is the C code. Note that you can get a working version of this program here:

  1. /* Compile this file together with the ph7 engine source code to generate
  2. * the executable. For example:
  3. * gcc -W -Wall -O6 -o ph7_test ph7_intro.c ph7.c
  4. */
  5. /*
  6. * This simple program is a quick introduction on how to embed and start
  7. * experimenting with the PH7 engine without having to do a lot of tedious
  8. * reading and configuration.
  9. *
  10. * For an introduction to the PH7 C/C++ interface, please refer to this page
  11. *
  12. * For the full C/C++ API reference guide, please refer to this page
  13. *
  14. */
  15. /*
  16. * The following is the PHP program to execute.
  17. * <?php
  18. * echo 'Welcome guest'.PHP_EOL;
  19. * echo 'Current system time is: '.date('Y-m-d H:i:s').PHP_EOL;
  20. * echo 'and you are running '.php_uname();
  21. * ?>
  22. * That is, this simple program when running should display a greeting
  23. * message, the current system time and the host operating system.
  24. * A typical output of this program would look like this:
  25. *
  26. * Welcome guest
  27. * Current system time is: 2012-09-14 02:08:44
  28. * and you are running Microsoft Windows 7 localhost 6.1 build 7600 x86
  29. *
  30. */
  31. #define PHP_PROG "<?php "\
  32. "echo 'Welcome guest'.PHP_EOL;"\
  33. "echo 'Current system time is: '.date('Y-m-d H:i:s').PHP_EOL;"\
  34. "echo 'and you are running '.php_uname();"\
  35. "?>"
  36. /* Make sure you have the latest release of the PH7 engine
  37. * from:
  38. *
  39. */
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. /* Make sure this header file is available.*/
  43. #include "ph7.h"
  44. /*
  45. * Display an error message and exit.
  46. */
  47. static void Fatal(const char *zMsg)
  48. {
  49.   puts(zMsg);
  50.   /* Shutdown the library */
  51.   ph7_lib_shutdown();
  52.   /* Exit immediately */
  53.    exit(0);
  54.  }
  55. /*
  56. * VM output consumer callback.
  57. * Each time the virtual machine generates some outputs, the following
  58. * function gets called by the underlying virtual machine to consume
  59. * the generated output.
  60. * All this function does is redirecting the VM output to STDOUT.
  61. * This function is registered later via a call to ph7_vm_config()
  62. * with a configuration verb set to: PH7_VM_CONFIG_OUTPUT.
  63. */
  64. static int Output_Consumer(const void *pOutput, unsigned int nOutputLen, void *pUserData /* Unused */)
  65. {
  66.   /*
  67.    * Note that it's preferable to use the write() system call to display the output
  68.    * rather than using the libc printf() which everybody now is extremely slow.
  69.    */
  70.   printf("%.*s",
  71.       nOutputLen,
  72.       (const char *)pOutput /* Not null terminated */
  73.    );
  74.     /* All done, VM output was redirected to STDOUT */
  75.     return PH7_OK;
  76.  }
  77. /*
  78. * Main program: Compile and execute the PHP program defined above.
  79. */
  80. int main(void)
  81. {
  82.   ph7 *pEngine; /* PH7 engine */
  83.   ph7_vm *pVm; /* Compiled PHP program */
  84.   int rc;
  85.   /* Allocate a new PH7 engine instance */
  86.   rc = ph7_init(&pEngine);
  87.   if( rc != PH7_OK ){
  88.    /*
  89.     * If the supplied memory subsystem is so sick that we are unable
  90.     * to allocate a tiny chunk of memory, there is no much we can do here.
  91.     */
  92.    Fatal("Error while allocating a new PH7 engine instance");
  93.   }
  94.   /* Compile the PHP test program defined above */
  95.   rc = ph7_compile_v2(
  96.       pEngine, /* PH7 engine */
  97.       PHP_PROG, /* PHP test program */
  98.       -1 /* Compute input length automatically*/,
  99.       &pVm, /* OUT: Compiled PHP program */
  100.       0 /* IN: Compile flags */
  101.    );
  102.   if( rc != PH7_OK ){
  103.     if( rc == PH7_COMPILE_ERR ){
  104.       const char *zErrLog;
  105.       int nLen;
  106.      /* Extract error log */
  107.      ph7_config(pEngine,
  108.        PH7_CONFIG_ERR_LOG,
  109.        &zErrLog,
  110.        &nLen
  111.      );
  112.    if( nLen > 0 ){
  113.      /* zErrLog is null terminated */
  114.      puts(zErrLog);
  115.     }
  116.   }
  117.   /* Exit */
  118.   Fatal("Compile error");
  119. }
  120. /*
  121.  * Now we have our script compiled, it's time to configure our VM.
  122.  * We will install the output consumer callback defined above
  123.  * so that we can consume and redirect the VM output to STDOUT.
  124.  */
  125. rc = ph7_vm_config(pVm,
  126.       PH7_VM_CONFIG_OUTPUT,
  127.       Output_Consumer, /* Output Consumer callback */
  128.       0 /* Callback private data */
  129.    );
  130.   if( rc != PH7_OK ){
  131.      Fatal("Error while installing the VM output consumer callback");
  132.   }
  133. /*
  134. * And finally, execute our program. Note that your output (STDOUT in our case)
  135. * should display the result.
  136. */
  137. ph7_vm_exec(pVm,0);
  138. /* All done, cleanup the mess left behind.
  139. */
  140. ph7_vm_release(pVm);
  141. ph7_release(pEngine);
  142. return 0;
  143. }

Download the C file.

We create a new PH7 engine instance using a call to ph7_init() on line 86. This is often the first PH7 API call that an application makes and is a prerequisite in order to compile PHP code using one of the compile interfaces.

We compile our PHP test program on line 95 using the ph7_compile_v2() interface.

We configure our Virtual Machine on line 125 by setting a VM output consumer callback named Output_Consumer(). All this callback does is redirecting the VM output to STDOUT using the libc printf() routine or the write() system call.

And finally we execute our PHP program on line 137 using a call to ph7_vm_exec(). You should see now the greeting message, the current date and the host operating system.

Clean-up is done on line 140 and 141 respectively via calls to ph7_vm_release() and ph7_release().

Compile the program

Compile this C file together with the PH7 engine source code to generate the executable. For example:

gcc -W -Wall -O6 -o ph7_test ph7_intro.c ph7.c

When running [./ph7_test ] you should see the greeting message, the current system time and the host operating system.

Stand-alone Interpreter For PH7

The PH7 download page includes a simple stand-alone PHP interpreter named ph7 (or ph7.exe on windows) that allows the user to enter and execute PHP files against a PH7 engine. This utility is available in prebuilt binaries forms or can be compiled from source. You can get a copy of the PH7 interpreter from the download page.

To start the ph7 program, just type "ph7" followed by the name of the PHP file to compile and execute. That is, the first argument is to the interpreter, the rest are scripts arguments, press "Enter" and the PHP code will be executed.

If something goes wrong while processing the PHP script due to a compile-time error, your error output (STDOUT) should display the compile-time error messages.

Usage example of the ph7 interpreter:

Running the interpreter

ph7 scripts/hello_world.php

Running the interpreter with script arguments

ph7 scripts/mp3_tag.php /usr/local/path/to/my_mp3s

The PH7 interpreter package includes more than 70 PHP scripts to test ranging from simple hello world programs to XML processing, zip archive extracting, MP3 tag extracting, UUID generation, JSON encoding/decoding, INI processing, Base32 encoding/decoding and many more. These scripts are available in the scripts directory from the zip archive.


Check out the Introduction To The PH7 C/C++ Interface for an introductory overview and roadmap to the dozens of PH7 interface functions.

A separate document, The PH7 C/C++ Interface, provides detailed specifications for all of the various C/C++ APIs for PH7. Once the reader understands the basic principles of operation for PH7, that document should be used as a reference guide.

Any questions, visit the Support Page for online community support.

Symisc Systems
Copyright © Symisc Systems