PHP turned out to be a bottleneck for us, but we had no chances to switch to another language.
We invented KPHP. It brings lots of limitations, but when satisfied, PHP code runs much faster.
First of all, KPHP is a compiler. It analyzes your whole project and compiles it to a single Linux binary.
More detailed, KPHP translates PHP sources to C++ equivalent and then compiles/links the resulting C++ code. Limitations of compilability take their roots from C++ — they are similar to all compiled languages.
In PHP, if you made an error in your code — you'll see it only when the execution point reaches that line.
In KPHP, you are unable to build your site until you fix all errors.
In PHP, symbols are resolved while executing. If you forget require_once, PHP will fail. You can define() in the middle of the script. Classes are dynamically autoloaded.
In KPHP, all symbols are resolved at compile-time. You can call any existing function from anywhere — it just exists. All constants are inlined, they don't appear dynamically. A full list of classes is known in advance.
Typical development looks this way:
1) you develop and test your code with PHP — it’s very handy to use PHP as a development tool
2) you compile your code with KPHP and deploy to production — it works identically, but faster
$func_name = "action_handler_" . ($input['action'] ?: 'default');
call_user_func($func_name, $_GET);
You can't call a function by name in any compiled programming language. But you can do this in PHP — and in PHP it's a very common scenario for routing/factories/etc. It won't work in KPHP.
As a consequence, you can't call methods by name, you can't access variables by name, and so on.
In brief, KPHP doesn't support fundamentally:
As a consequence, KPHP won't compile standard frameworks / ORMs / PHPUnit.
f(42);
f("string");
f(new User);
array(1, new User, function(){});
In PHP, you can mix types arbitrary and handle them at runtime. You pass numbers / arrays / objects to the same function. You create hashmaps of anything — and it just works if you access it by correct indexes.
In KPHP, you should always think about types — like in any other compiled language. If you mix types incorrectly, it's a compilation error. You'll need to rewrite lots of your PHP code to satisfy the type system.
We'll discuss the type system later. The main point for now: restrictions are the reason for performance.
Consider the “Various howto” chapter for some bits of advice, how to deal with these limitations.
KPHP was developed at VK.com, and VK.com doesn't use standard databases like Postgres, Redis, and others. All storages and protocols are also self-written (but not open-sourced yet).
Besides, not all PHP standard library is covered. For example, in VK.com mail sending and working with images is done with external engines, so KPHP has never needed imagecreate() and related stuff.
As a result, KPHP has no built-in support of many “real-world” needs:
$_SESSION
superglobal<?= ... ?>
short tagsThis can technically be done — and probably would be done in the future — but making the first public release, we realize, that it is probably the most crucial aspect of disappointment.
You can organize your project in a way, that part of it would be compiled, and part of it would work on PHP.
For example, file uploading can remain PHP-based, whereas API business logic works on KPHP.
KPHP has about PHP 7.4 language level support.
Some parts of PHP syntax can be technically supported, but were not implemented — either they are hard to implement, or there wasn't enough time, or they are considered to be a bad style.
For now, KPHP has the absence of:
Most of them are not hard to implement, they were not just done yet.
(Yes, backend developers at VK.com don't use these features, but none of them are major or a priority to be added)
As a result, KPHP would probably not compile any existing not-too-primitive library. All solutions for VK.com were written from scratch.
How to overcome the current situation?
The killer feature of KPHP is that after compilation your code acts the same as in PHP.
This is 99.9% true. In some strange or very rare cases, KPHP can evaluate differently.
KPHP may differ (and may not) in the following scenarios:
It's unlikely to face misbehavior affecting production — but still, test a compiled site before deploying.
Most of them are dedicated to compile-time checks and runtime performance.
As you see, compilation coupled with static code analysis opens the gates to safe code and efficiency.
Always treat KPHP as a compiled language — not as a tool, making PHP fast. This makes limitations obvious.
Fitting best practices, you can achieve great runtime speed — as if your code was written directly in C++.