globus-studio/php-obfuscator

A token-based PHP source code obfuscator with full support for PHP 8.1 through 8.5.

Maintainers

Package info

github.com/GLOBUS-studio/PhpObfuscator

pkg:composer/globus-studio/php-obfuscator

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 18

Open Issues: 0

v1.0.0 2026-04-26 23:39 UTC

This package is auto-updated.

Last update: 2026-04-29 07:53:31 UTC


README

CI Latest Release License: MIT Tested on PHP 8.1 - 8.5 PHPUnit

A token-based PHP source code obfuscator. Renames identifiers, encodes string literals and minifies whitespace, all driven by PHP's own tokenizer rather than brittle regular expressions, so the transformed code keeps its original runtime semantics on every supported PHP version.

The obfuscator is fully tested on PHP 8.1, 8.2, 8.3, 8.4 and 8.5 in CI.

Why another obfuscator?

Most PHP obfuscators on the open web rely on regular expressions. They break on namespaced code, on complex string interpolation, on constructor property promotion and on anything that does not fit a simple textual pattern. This library walks the official PhpToken stream and rewrites identifiers using the same lexical context the engine itself uses, which makes the result predictable and safe to ship.

Features

  • Token-based identifier rewriting (variables, functions, classes, interfaces, traits, enums, methods, properties, class and global constants).
  • Constructor property promotion, readonly, enum, match, arrow functions, nullsafe operator, named arguments and attributes are all recognised.
  • Optional Base64 encoding of string literals (skipped automatically inside constant expressions where PHP requires literal values).
  • Optional comment stripping and whitespace minification driven by a second tokenizer pass, so the output is guaranteed to remain parseable.
  • Optional eval(base64_decode(...)) wrapping for an extra layer of protection.
  • Deterministic PRNG seed for reproducible builds.
  • Inspection of the rename table via getNameMap().
  • Bundled php-obfuscate CLI binary.

Installation

composer require globus-studio/php-obfuscator

Quick start

<?php

require __DIR__ . '/vendor/autoload.php';

use GLOBUSstudio\PhpObfuscator\Obfuscator;
use GLOBUSstudio\PhpObfuscator\Options;

$obfuscator = new Obfuscator();

echo $obfuscator->obfuscate(<<<'PHP'
<?php
function greet(string $name): string {
    return "Hello, $name";
}
echo greet('Ada');
PHP);

The output is a self-contained <?php eval(base64_decode("...")); payload that prints Hello, Ada when executed.

Library API

Obfuscator

$obfuscator = new Obfuscator(new Options(seed: 42));

$code = $obfuscator->obfuscate('<?php echo 1 + 1;');
$code = $obfuscator->obfuscateFile(__DIR__ . '/src/in.php');
$obfuscator->obfuscateFileTo(__DIR__ . '/src/in.php', __DIR__ . '/build/out.php');

$map = $obfuscator->getNameMap();
// [
//     'variables'  => ['userName' => 'vAbCdEfG', ...],
//     'functions'  => [...],
//     'classes'    => [...],
//     'methods'    => [...],
//     'properties' => [...],
//     'constants'  => [...],
// ]

Options

Options is an immutable value object. All flags default to true.

Option Default Description
obfuscateVariables true Rename local variables (superglobals and $this are always preserved).
obfuscateFunctions true Rename user-defined function declarations and their call sites.
obfuscateClasses true Rename classes, interfaces, traits and enums and every reference to them.
obfuscateMethods true Rename methods (magic methods such as __construct are kept untouched).
obfuscateProperties true Rename properties, including promoted constructor parameters and static props.
obfuscateConstants true Rename const, class constants, enum cases and define() constants.
encodeStrings true Replace string literals with base64_decode('...') calls.
removeComments true Strip //, # and /* ... */ comments.
removeWhitespace true Minify whitespace.
wrapWithEval true Wrap the final payload in <?php eval(base64_decode('...'));.
minNameLength 6 Minimum length of generated identifiers.
maxNameLength 12 Maximum length of generated identifiers.
seed null Optional PRNG seed for deterministic, reproducible output.
use GLOBUSstudio\PhpObfuscator\Options;

$options = new Options(
    encodeStrings: false,
    wrapWithEval: false,
    seed: 12345,
);

$options = Options::fromArray(['wrapWithEval' => false]);
$options = $options->with(['seed' => 7]);

Selective obfuscation

use GLOBUSstudio\PhpObfuscator\Obfuscator;
use GLOBUSstudio\PhpObfuscator\Options;

// Public API stays callable from the outside while the internals are scrambled.
$opts = new Options(
    obfuscateClasses:  false,
    obfuscateMethods:  false,
    obfuscateFunctions: false,
);

echo (new Obfuscator($opts))->obfuscate(file_get_contents('Library.php'));

CLI

Usage: php-obfuscate [options] <input.php> [output.php]

Reads PHP source from <input.php> (or `-` for STDIN), obfuscates it and writes
the result to <output.php> (or STDOUT when omitted).

Options:
  --no-eval-wrap         Do not wrap output in eval(base64_decode(...))
  --no-strings           Skip string literal Base64 encoding
  --no-minify            Preserve original whitespace
  --no-comments          Strip comments only (default removes them)
  --keep-variables       Do not rename variables
  --keep-functions       Do not rename functions
  --keep-classes         Do not rename classes
  --keep-methods         Do not rename methods
  --keep-properties      Do not rename properties
  --keep-constants       Do not rename constants
  --seed=<int>           Use a deterministic PRNG seed
  -h, --help             Show this help text
  -V, --version          Print library version

Examples:

vendor/bin/php-obfuscate src/Acme/Service.php build/Service.php
cat src/Acme/Service.php | vendor/bin/php-obfuscate - > build/Service.php
vendor/bin/php-obfuscate --keep-classes --seed=1 src/Service.php

What is preserved by design

  • $this and every PHP superglobal ($_SERVER, $_GET, ...).
  • Magic methods (__construct, __toString, __invoke, ...).
  • Built-in PHP functions, classes, traits and interfaces. The obfuscator only renames identifiers it has previously seen declared in the input, so references to anything from the standard library or third-party packages remain untouched.
  • String literals appearing in constant-expression positions (class constants, enum case values, default parameter values, top-level const initializers) are never wrapped in base64_decode(...), because PHP requires those positions to be literal expressions.

Limitations

  • Namespaced symbol names that appear as T_NAME_QUALIFIED or T_NAME_FULLY_QUALIFIED tokens are not rewritten. If you need to obfuscate namespaced classes, the obfuscator must be applied to a single-namespace file at a time.
  • The obfuscator works at the source level. It is a deterrent that raises the cost of casual reverse engineering, not a cryptographic protection. Anyone able to run your code can trivially recover the runtime behaviour.

Development

composer install
vendor/bin/phpunit

The bundled CI workflow runs the test suite on Ubuntu against PHP 8.1 - 8.5.

License

MIT.