Download the PHP package kminet/php-obfuscator without Composer
On this page you can find all versions of the php package kminet/php-obfuscator. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download kminet/php-obfuscator
More information about kminet/php-obfuscator
Files in kminet/php-obfuscator
Package php-obfuscator
Short Description PHP source code obfuscator — transforms namespaces, classes, methods and variables into hashed equivalents while preserving full runtime behaviour
License LGPL-3.0-only
Homepage https://github.com/KminekMatej/PhpObfuscator
Informations about the package php-obfuscator
PhpObfuscator
⚠️ Draft / Work in Progress — This library is not yet production-ready. APIs, behaviour, and output format may change without notice. Use at your own risk.
A PHP code obfuscator that transforms PHP source into functionally identical but hard-to-read code. It uses a "backplate" mapping system to track original-to-obfuscated name transformations and supports multiple obfuscation levels with increasing coverage.
Requirements
- PHP 8.3+
- Composer
Installation
PhpObfuscator can be used in three ways depending on your workflow.
Standalone / global tool
Install it globally and use it from anywhere on your system:
Per-project dev dependency
Install it inside your project and run it as part of your build process:
Cloned locally
Clone the repository and run directly:
Usage
CLI
Examples:
Configuration
PhpObfuscator is configured via a Neon file — the same format used by PHPStan. JSON is also accepted when passing a .json file via --config, which can be easier to generate from shell scripts or CI pipelines. The tool resolves the config file in this order:
- Path given by
--config <file>(explicit, highest priority) phpobf.neonin the current working directory (project-level config, committed to your repo)config/phpobf.default.neonbundled with phpobf (the built-in fallback)
CLI flags always take precedence over the config file — they override any matching key.
Creating a project config
Drop a phpobf.neon in your project root alongside composer.json. PhpObfuscator picks it up automatically without any --config flag:
Config reference
| Key | Type | Default | Description |
|---|---|---|---|
level |
int (0–2) |
1 |
Obfuscation level. Acts as a preset — defines which features are enabled by default. |
obfuscatePaths |
bool |
true |
Relocate output files to match the obfuscated PSR-4 namespace structure. |
testMode |
bool |
false |
Prefix obfuscated names with the original (e.g. Teacher_abc123) for easier debugging. |
keepBackplateFile |
bool |
false |
Save backplate.json alongside obfuscated output. ⚠️ Never distribute this file. |
features |
object |
(from level) | Fine-grained feature toggles. See below. |
block.namespaces |
string[] |
[] |
Regex patterns for namespaces to skip entirely (e.g. "/^Psr\\\\/" preserves PSR interfaces). |
block.classes |
string[] |
[] |
Regex patterns for class names to skip entirely. |
Feature flags
The features object lets you override individual obfuscation features on top of the level preset — the same way JavaScript Obfuscator handles presets. Each key accepts true, false, or null:
null(default) — inherit from the level presettrue— force this feature on, even if the level wouldn't enable itfalse— force this feature off, even if the level would enable it
| Feature | Level 0 | Level 1 | Level 2 | Description |
|---|---|---|---|---|
comments |
✓ | ✓ | ✓ | Strip all comments from source |
namespaces |
✓ | ✓ | ✓ | Rename namespace declarations |
classes |
✓ | ✓ | ✓ | Rename class, interface, and enum names |
interfaces |
✓ | ✓ | ✓ | Rename interface names (subset of classes) |
enums |
✓ | ✓ | ✓ | Rename enum names (subset of classes) |
methods |
✗ | ✓ | ✓ | Rename method and function definitions and call sites |
functions |
✗ | ✓ | ✓ | Rename standalone function definitions and call sites |
constants |
✗ | ✓ | ✓ | Rename class constants and enum cases |
variables |
✗ | ✗ | ✓ | Rename all variables (local, global, parameters) |
properties |
✗ | ✗ | ✓ | Rename class property declarations and $this->prop accesses |
Example — level 1 but without method obfuscation, and with comments preserved:
Example — block PSR and Symfony namespaces from obfuscation:
Ignoring specific declarations
You can exclude individual PHP declarations from obfuscation using two annotations. Both work for classes, interfaces, enums, methods, functions, properties, constants, enum cases, and variables.
@phpobf-ignore-line
The annotation and the declaration must be on the exact same line:
@phpobf-ignore-next-line
The annotation must be on the line immediately before the declaration:
An optional reason can follow either annotation — it is recorded in backplate.json alongside the ignored: true flag for traceability. Both // and /* */ comment styles are supported.
Note: Ignoring a class does not automatically ignore its methods or properties. Each declaration must be annotated individually if you want to exclude multiple members.
In-code API
The obfuscator can also be used programmatically via the fluent builder API:
The obfuscator uses a PSR-3 LoggerInterface — any compliant logger works. When no logger is set, log output is silently discarded. The CLI entry point wires up a Monolog logger with colour-coded output automatically.
API Reference
| Method | Default | Description |
|---|---|---|
setSource(string $source) |
(required) | Path to the PHP file or directory to obfuscate. Directories are scanned recursively. |
setLevel(int $level) |
0 |
Obfuscation level (0–2). See below. |
setTestMode(bool $testMode) |
false |
When true, obfuscated names are prefixed with the original (e.g. Teacher_abc123) for easier debugging. |
setObfuscatePaths(bool $obfuscatePaths) |
true |
When true, files are relocated to match the obfuscated namespace directory structure. |
setKeepBackplateFile(bool $keep) |
false |
When true, saves backplate.json to the output directory alongside obfuscated sources. |
setLogger(LoggerInterface $logger) |
(none) | Attach a PSR-3 logger for progress and diagnostic output. |
new Obfuscator(outputDir: $dir) |
temp/{id}/ |
Custom output directory. Defaults to temp/{obfuscationId}/ relative to the library root. |
Obfuscation Levels
Levels are stacked — each level applies everything from the previous levels plus its own transformations.
Level 0 — Structural obfuscation (namespaces, classes, interfaces, enums)
- Renames all namespace declarations to hashed equivalents
- Renames all class, interface, and enum names to hashed equivalents
- Rewrites all fully-qualified references (type hints,
newexpressions, static calls) to match - Removes
usestatements in production; rewrites them to obfuscated FQCNs in test mode - Strips all comments
- Relocates files to match the obfuscated PSR-4 directory structure (when
setObfuscatePaths(true)) - Skips any class or namespace matched by the block list (e.g.
/^Psr/)
Level 1 — Method & function obfuscation (everything from Level 0, plus):
- Renames method definitions to hashed equivalents (magic methods like
__constructare always skipped) - Rewrites instance method calls (
$obj->method()) by resolving the receiver's type via PHPStan inference, AST walking for chainednewexpressions, or$thisclass reflection - Rewrites static method calls (
Foo::method()) using the fully-qualified class name - Renames standalone function definitions and their call sites
- Leaves a method call unobfuscated (with a warning) if the receiver type cannot be resolved (union types, mixed, or dynamic dispatch
$obj->$method())
Level 2 — Variable & property obfuscation (everything from Level 1, plus):
- Renames all variables (local, global, function parameters) to hashed equivalents
- Renames class property declarations (
private string $name→private string $xR9mLp) - Renames
$this->propertyaccess expressions to match - Skips
$thisand all PHP superglobals ($_SERVER,$_GET,$_POST,$_COOKIE,$_FILES,$_SESSION,$_REQUEST,$_ENV,$GLOBALS) - Throws a
ScopeResolutionExceptionand aborts the file if a dynamic variable-variable ($$var) is encountered, as its runtime name cannot be statically determined - Property accesses on non-
$thisreceivers (e.g.$obj->name) are intentionally skipped — resolving the owner class without full type inference risks renaming unrelated properties that share the same name across different classes
Note: Because the hash is purely name-based, the same variable name always maps to the same obfuscated name everywhere it appears — across methods, closures, and arrow functions — so no per-scope tracking is required.
Output
Obfuscated sources are written to the output directory. A backplate.json file containing the full original-to-obfuscated name mapping can optionally be saved alongside the output using --keep-backplate-file (CLI) or setKeepBackplateFile(true) (API). This file is useful for correlating obfuscated symbols back to their originals (e.g. for stack trace interpretation).
⚠️⚠️ Never distribute
backplate.jsonwith your obfuscated sources. ⚠️⚠️The backplate is a complete reverse-mapping of every obfuscated name back to its original. Anyone with this file can trivially deobfuscate your entire codebase. Keep it private, treat it like a secret key, and delete it from the output directory before shipping.
If the source project contains a composer.json and setObfuscatePaths(true) is used, the autoloader in the output is automatically updated to use a classmap. Run composer dump-autoload in the output directory after obfuscation:
License
This project is licensed under the GNU Lesser General Public License v3.0 (LGPL-3.0).
You are free to use this library in any software, including commercial and closed-source products. However, any modifications to the library itself must be published under the same LGPL-3.0 license.
See the LICENSE file for the full license text.
All versions of php-obfuscator with dependencies
bramus/monolog-colored-line-formatter Version ^3.1
monolog/monolog Version ^3.0
nikic/php-parser Version ^5.0
phpstan/phpstan Version ^2