A very simple but fast PHP preprocessor. Buggy and not turing complete.
I use this to turn my code into production version, every time after an update in our CI.
This is done by filtering some lines; performance counters, counting instances, con/destructor stuff, wakeup counters, timings and other metrics.
But also some ifs
for stuff you never or always want in production environments, or are OS relevant.
It turned out to be easy and can save quite some clock cycles!
Enjoy, gizmore
PP is processing text files line by line,
reading kind of annotations by abusing PHP #
comments.
It basically looks for the Sequence #PP#
, case-sensitive, and checks if it is in an actual '<?php'
place.
PP commands start with a #PP#
and are finished by another #
.
#PP#command,args# args do not work yet as not neeed yet.
There are currently 5 commands:
- #PP#delete# to delete the line.
- #PP#start# to begin a delete block.
- #PP#end# to end end a delete block.
- #PP#linux# to keep this line on linux machines.
- #PP#windows# to keep this line on windows machines.
Maybe you want to use PP as a standalone executable instead of using the lib's API:
-
Use composer to install globally.
-
Then the
pp
command should be available. (untested!)pp file # or use stdin/out
It is not 100% Unix style, but should work on windows and linux.
You can control options via the pp executable or by using the API equivalents.
For API: Use $pp->option
to get and $pp->option($value)
to set.
Control your infile source with the parameter or use STDIN.
-
--help: print usage line and exit.
-
--uglify: apply uglify-php with all options enabled.
-
--outfile path: redirect STDOUT to another file.
-
--replace: write output to source file, when not in STDIN.
-
--verbose: print verbose processing info to STDOUT.
-
--recursive: process all files recursively for the input if it's a folder.
-
--simulate: do redirect --outfile to STDOUT. Do not write any physical files.
-
--phpmode: set the initial inside
<?php
state to true. Default is false.
- My phpgdo autoloader
spl_autoload_register(function(string $name) : void
{
if ( ($name[0]==='G') && ($name[3]==='\\') ) # 1 line if
{ # 2 lines path
$name = GDO_PATH . str_replace('\\', '/', $name) . '.php'; #PP#windows# This line is only kept on windows machines.
require $name;
# 2 lines perf, but removed by #PP# PreProcessor
global $GDT_LOADED; # #PP#delete#
$GDT_LOADED++; # #PP#delete#
}
});
Note that we got rid of 3 costy lines in a very hot spot, but only ony windows machines. Like on all my prod servers =)
-
The string replace is only need on windows machines, which i do not recommend for an httpd production-env server.
-
2 lines performance countings could be deleted for prod machines. This does not seem much, but the function is not using globals anymore, which might be a good hint for the optimizer.
Update: LOL, The first str_replace
is always needed,
because $name
is a classname, using \\
to seperate namespaces,
but there are other occassions were we can have a performance boost via #PP#windows#
.
PP is new, so handle it with care. I also found the first problems:
-
Some of your line numbers on prod exception traces are a bit off.
-
The too simple syntax can lead to forced invalid PHP code, which simply makes some usecase ugly or not possible at the moment.
-
#PP#if(n)def,varname#
- to keep the line only if a constant named varname is / is not defined. -
#PP#if(n)is,varname,value#
- to keep the line if a constant named "varname" equals "value". -
--profiler: Replace all
if()
calls with calls to a branch counter for a new performance metric. -
--uglify: Strip comments and whitespace with uglify-php. Tiny speedup for compilation process which is cached anyway, but still.
Of course your pull requests and / or issues are welcome.
if you want to get in touch, send me an email to [email protected], or visit the WeChall website.
PP has almost no third party dependencies.
Beside composer, it uses my own php-filewalker to traverse directories. Filewalker is dependency free.
However, when using the option --uglify uglify-php is required. Hence it is a composer dependency.
I decided to use the MIT license for this small project.