PHPackages                             ircmaxell/php-compiler - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. ircmaxell/php-compiler

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

ircmaxell/php-compiler
======================

A CFG Compiler for PHP

802934[34 issues](https://github.com/ircmaxell/php-compiler/issues)[2 PRs](https://github.com/ircmaxell/php-compiler/pulls)PHP

Since May 5Pushed 7y ago61 watchersCompare

[ Source](https://github.com/ircmaxell/php-compiler)[ Packagist](https://packagist.org/packages/ircmaxell/php-compiler)[ RSS](/packages/ircmaxell-php-compiler/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (2)Used By (0)

A compiler for PHP
==================

[](#a-compiler-for-php)

[![CircleCI](https://camo.githubusercontent.com/40356375e28b2d0f459bd45d8ec25e3fb4d6156fe4a59bf3dae662cc0e41c29a/68747470733a2f2f636972636c6563692e636f6d2f67682f6972636d6178656c6c2f7068702d636f6d70696c65722e7376673f7374796c653d737667)](https://circleci.com/gh/ircmaxell/php-compiler)

Ok, so this used to be a dead project. It required calling out to all sorts of hackery to generate PHP extensions, or PHP itself.

Now, thanks to [FFI landing in PHP 7.4](https://wiki.php.net/rfc/ffi), the potential for all sorts of crazy is HUGE.

So here we go :)

Installation
============

[](#installation)

Install PHP 7.4, being sure to enable the FFI extension, OpenSSL extension, mbstring extension, and zlib extension (`--with-ffi --with-openssl --enable-mbstring --with-zlib`).

Also, you need to install the system dependency `llvm-4.0`. On Ubuntu:

```
me@local:~$ sudo apt-get install llvm-4.0-dev clang-4.0
```

Then run `composer install`.

Using docker
------------

[](#using-docker)

This project comes with one working and one non-working (yet) Dockerfile. The makefile uses a reasonably old version of Ubuntu (16.04), and once FFIMe is fixed for newer versions of glibc, it will switch to use 18.04 (or newer).

To build, use make:

```
me@local:~$ make build
```

This will take a while (upwards of 10 minutes likely). It will install an Ubuntu container with a custom compile of PHP-7.4 and everything you need to get up and running. It will also composer install all dependencies as well as run the pre-processor. Once it's done, you can run tests:

```
me@local:~$ make test
```

This will execute all unit tests inside the container.

To run your own code or play with the compiler, you can open a shell using `make shell`:

```
me@local:~$ make shell
root@662c59ae4527:/compiler# php bin/jit.php -r 'echo "Hello World\n";'
Hello World
```

Running Code
============

[](#running-code)

There are three main ways of using this compiler:

VM - Virtual Machine
--------------------

[](#vm---virtual-machine)

This compiler mode implements its own PHP Virtual Machine, just like PHP does. This is effectively a giant switch statement in a loop.

No, seriously. It's literally [a giant switch statement](lib/VM.php)...

Practically, it's a REALLY slow way to run your PHP code. Well, it's slow because it's in PHP, and PHP is already running on top of a VM written in C.

But what if we could change that...

JIT - Just In Time
------------------

[](#jit---just-in-time)

This compiler mode takes PHP code and generates machine code out of it. Then, instead of letting the code run in the VM above, it just calls to the machine code.

It's WAY faster to run (faster than PHP 7.4, when you don't account for compile time).

But it also takes a long time to compile (compiling is SLOW, because it's being compiled from PHP).

Every time you run it, it compiles again.

That brings us to our final mode:

Compile - Ahead Of Time Compilation
-----------------------------------

[](#compile---ahead-of-time-compilation)

This compiler mode actually generates native machine code, and outputs it to an executable.

This means, that you can take PHP code, and generate a standalone binary. One that's implemented **without a VM**. That means it's (in theory at least) as fast as native C.

Well, that's not true. But it's pretty dang fast.

Okay, Enough, How can I try?
============================

[](#okay-enough-how-can-i-try)

There are four CLI entrypoints, and all 4 behave (somewhat) like the PHP cli:

- `php bin/vm.php` - Run code in a VM
- `php bin/jit.php` - Compile all code, and then run it
- `php bin/compile.php` - Compile all code, and output a `.o` file.
- `php bin/print.php` - Compile and output CFG and the generated OpCodes (useful for debugging)

Executing Code
--------------

[](#executing-code)

Specifying code from `STDIN` (this works for all 4 entrypoints):

```
me@local:~$ echo '
