pp4php: a preprocessor for PHP in PHP

by Martin Monperrus


pp4php is a pre-processor for PHP written in PHP. The goal of pp4php is to enable the tailoring of the PHP source code that you redistribute:

Example:
Before pp4phpAfter pp4php
<?php /*
#pp4php __codename__ bigjoe
This is xxscript (release __codename__).
Downloaded at __URL__
Last modified: __MTIME__
*/

include("xxscript_utils.php");
@include(
"optional.php");// not resolved because of the @
?>
<H1>You are running xxscript (v__MTIME__, release __codename__)</H1>
<P>
...
</P>
<?
$link 
mysql_connect('localhost',
       
'mysql_user',
       
/*pp4php:hidden*/'mysql_password'/*neddih*//* your password here */);
function 
nicefunction() { $release='__codename__'; }
?>
<?php /*
This is xxscript (release bigjoe).
Downloaded at https://www.monperrus.net/martin/pp4php
Last modified: 20181110
*/

?><?php /* pp4php: including ./xxscript_utils.php (in pp4php-killerapp.txt:8) */ ?><?php
function foo() { ... }
function 
bar() { ... }
?><?php 
@include("optional.php");// not resolved because of the @
?>
<H1>You are running xxscript (v20181110, release bigjoe)</H1>
<P>
...
</P>
<?
$link 
mysql_connect('localhost',
       
'mysql_user',
       
/* your password here */);
function 
nicefunction() { $release='bigjoe'; }
?>

Core concepts


A preprocessor constant (builtin or user-defined) is replaced in PHP comments, embedded HTML code and PHP code. (cf. example above)
On the the contrary, a PHP constant name (define("x1","value")) is available only in PHP code. To define a new constant:
#pp4php __codename__ bigjoe
It has to be terminated by a newline

The graph of included files is unfolded statically (cf. example above).
On the contrary, a PHP include/require is done dynamically.
The main advantage is to enable the distribution of a single PHP file which is the results of multiple input source files used for development. If you want to disable the replacement of an include/require by its content, prefix it by an @:
@include("foo.php");

Strings enclosed by pp4php:hidden and neddih are not shown at all. The main usage is to hide passwords and TODO (cf. example above)

Builtin Variables


First pp4php supports some of the magic constants of PHP.
__PPFILE__ is replaced by the full path the current preprocessed filename. It depends on the graphof include/require.
__PPDIR__ is replaced by the full path of the directory containing the current preprocessed filename.
__PPLINE__ is replaced by the line number in the current preprocessed filename.
__PPSFILE__ is replaced by the file name the current preprocessed filename.
__MTIME__ is replaced by the day-wise modification time of the current preprocessed filename (e.g. 20091025).
__XMTIME__ is replaced by the second-wise modification time of the current preprocessed filename (e.g. 20091025-1324)..

Second, pp4php supports handy special tags:
__NOW__ is replaced by the day-wise download date of the code (e.g. 20091025), useful for traceability links.
__XNOW__ is replaced by the second-wise download date of the code (e.g. 20091025-1810), useful for traceability links.

Third, pp4php supports shortcuts of PHP $_SERVER variables. They are not only shortcuts but also available in PHP comments and embedded HTML code.

__USER_AGENT__ is replaced by the value of $_SERVER["HTTP_USER_AGENT"]
__REFERER__ is replaced by the value of $_SERVER["HTTP_REFERER"]
__USER_NAME__ is replaced by the value of $_SERVER["PHP_AUTH_USER"]
__REMOTE_ADDR__ is replaced by the value of $_SERVER["REMOTE_ADDR"]
__REMOTE_HOST__ is replaced by the value of gethostbyaddr($_SERVER["REMOTE_ADDR"])

Misc:
__POWEREDBY__ is replaced by a mention and a link to pp4php :-)
__ID__ is a shortcut for "__URL__, v__XMTIME__, retrieved __XNOW__", inspired by SVN $id$
/*pp4php:serl*/ DEV_ONLY_ERROR_LEVEL /*lres*/ is replaced by E_ERROR. serl stands for Safe Error Reporting Level. Using SERL, the code you redistribute should not produce undesirable notice and warning messages on different configurations.
__UNIQ__ is replaced by a unique ID.



Usage


The basic usage is to call pp4php and giving it the filename as parameter:
http://domain.com/pp4php.php?pp4php_source=xxscript.php

If you want to hide the the call to pp4php you can encapsulate it in a RewriteRule
# the first loop is required to avoid infinite RewriteRule loops
RewriteRule pp4php.php$ - [L]
RewriteRule (*.php)$ pp4php.php?pp4php_source=$1 [L]

Download


pp4php is released under the GNU General Publice Licence. Here is the source code: http://www.monperrus.net/martin/pp4php.php.txt. Note that pp4php is bootstrapped: the source you obtain is the result of processing pp4php.php with pp4php :-)
For feature requests, bug reports, or patch proposals, please drop me an email.

Tagged as: