PHP opcode is the machine code generated by PHP engine after compiling your source code. Understanding how your syntax influences opcode allows you to drastically optimize CPU performance without major rewrite. This guide explores advanced techniques we use at VOID for our banking applications in Morocco.
What is PHP opcode?
The term opcode (operation code) refers to low-level instructionsexecuted by PHP engine after your source code has been compiled.
Unlike compiled languages like Go or Rust, PHP compiles code at runtime:
- Parsing: raw PHP code analysis
- Tokenization: breaking into tokens
- Compilation: opcode (bytecode) generation
- Caching: memory storage (OPcache)
- Execution: bytecode interpretation by Zend Engine
π‘ Key point: Once compiled and cached, PHP code is no longer parsed or compiled. The engine directly executes bytecode, which drastically reduces CPU load and improves response times.
OPcache: bytecode caching
OPcache is the native PHP extension (included since PHP 5.5) that caches compiled bytecode in memory. Without OPcache, PHP would recompile code on every request, wasting CPU and memory.
β Recommended OPcache configuration
; php.ini or php.d/opcache.ini opcache.enable=1 opcache.memory_consumption=128 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=10000 opcache.revalidate_freq=0 opcache.validate_timestamps=0 opcache.fast_shutdown=1
validate_timestamps=0: doesn't check if file changed (perf gain), but requires purging cache after each deployment via opcache_reset()or restart PHP-FPM.
β οΈ Cache invalidation after deployment
If you don't purge OPcache after deployment, PHP will continue executing the old cached code version.
// Deployment script
<?php
opcache_reset(); // Full cache purge
// or
opcache_invalidate('/path/to/file.php', true);Alternative: systemctl restart php8.2-fpm (brutal but effective method)
How to analyze generated opcode
To optimize, you must first see the generated opcode. Three methods:
1οΈβ£OPcache native functions
<?php // Force compilation opcache_compile_file(__DIR__.'/script.php'); // Get OPcache status $status = opcache_get_status(); // Inspect script print_r($status['scripts'][__DIR__.'/script.php']);
2οΈβ£VLD (Vulcan Logic Disassembler)
PHP extension that disassembles compiled code and displays detailed opcode.
# Installation pecl install vld # Usage php -d vld.active=1 -d vld.execute=0 script.php
Output: line-by-line detail with each operation, fetch, return, operands.
3οΈβ£3v4l.org (Recommended for testing)
Free online tool allowing opcode visualization on all PHP versions (5.x, 7.x, 8.x). Perfect for before/after optimization comparison.
Syntax impact on opcode
Here's the most surprising aspect: two logically identical syntaxes can generate very different opcodes in terms of complexity and number of operations.
β Example: function call in namespace
<?php
namespace App;
strlen('hello'); // β BadGenerated opcode:
line #* op fetch ext return operands
------------------------------------------------------------------------
5 0 INIT_NS_FCALL_BY_NAME 'App%5Cstrlen'
1 SEND_VAL_EX 'hello'
2 DO_FCALL 0
3 RETURN 1Engine searches for App\strlen, doesn't find it, then tries \strlen.Unnecessary double lookup!
β Solution 1: Global backslash
<?php
namespace App;
\strlen('hello'); // β
GoodGenerated opcode:
line #* op fetch ext return operands ---------------------------------------------------- 5 0 RETURN 1
Single instruction! Engine knows exactly where to go. Gain: ~50% operations.
β Solution 2: Function import
<?php
namespace App;
use function strlen;
strlen('hello'); // β
Good tooSame result: engine knows strlen points to global function.
PHP engine automatic optimizations
Since PHP 7.x, the engine includes many automatic optimizations that evaluate static expressions ahead of time. Being aware of these mechanisms allows you to leverage them.
Example: PHP Constants
β Without backslash
<?php
namespace App;
if (PHP_OS === 'Linux') {
echo "Linux";
}FETCH_CONSTANT ~0 'App%5CPHP_OS' IS_IDENTICAL ~0, 'Linux' JMPZ ~1, ->4 ECHO 'Linux'
Searches for App\PHP_OS, then PHP_OS. Evaluates IF on each execution.
β With backslash
<?php
namespace App;
if (\PHP_OS === 'Linux') {
echo "Linux";
}ECHO 'Linux' RETURN 1
Constant resolved at compilation, IF disappears! Nearly empty opcode.
π Real impact: On a platform processing millions of requests/day, these micro-optimizations accumulate and free significant CPU resources. This allows some platforms to run on 2 vCPU instead of 4.
β Best practices and checklist
validate_timestamps=0for maximum gains\ in namespaces (\strlen, \array_map, etc.)use const PHP_OS, PHP_VERSIONopcache_reset()or restart PHP-FPMπ Real case: infrastructure cost impact
At VOID, we applied these optimizations to a banking platform processing over 1 million transactions per day. Here are measured results:
Before optimization
- β’ OPcache enabled but
validate_timestamps=1 - β’ Native functions without backslash
- β’ Constants accessed directly
- β’ 4 vCPU + 16GB RAM
- β’ Average CPU usage: 75%
- β’ P95 response time: 450ms
After optimization
- β’ Optimized OPcache
validate_timestamps=0 - β’ Native functions with
\ - β’ Constants imported via
use const - β’ 2 vCPU + 8GB RAM (-50%)
- β’ Average CPU usage: 45% (-40%)
- β’ P95 response time: 280ms (-38%)
Optimize without major refactoring
PHP opcode optimization is an accessible quick win for everyone. Enable OPcache, add backslashes, import constants: measurable gains without major rewrite. Your servers β and your budget β will thank you.
π Source article and tools
This article is inspired by techniques described by Valerio Barbera (Inspector.dev) on PHP opcode optimization. We adapted the content with our expertise and use cases on banking applications in Morocco.