Skip to content
New PHP 8.5 loader ready — start a free 3-day trial, no card required
Guide 6 min read • June 2025

How to Protect PHP Source Code Before Distribution

When you distribute a PHP application to clients who manage their own servers, your readable source code goes with it. This guide walks through the practical steps to encode your PHP files locally, issue domain-locked licenses, and deploy protected builds — without uploading your source code to any third-party service.

The Problem with Plain PHP Distribution

PHP is an interpreted language. When you hand a client a ZIP of your application, they receive every line of your business logic in plain text. Anyone with server access — the client, their hosting provider, a disgruntled employee — can read, copy, or modify your proprietary algorithms, bypass your license checks, or redistribute your work.

The solution is to encode your PHP files into encrypted binary payloads before distribution. The client's server runs a lightweight loader extension that decrypts and executes the code in RAM — the original source never touches their disk.

Step 1 — Decide What to Encode

Encoding every file in a Laravel or custom PHP project is unnecessary and creates friction. The right approach is selective encoding: protect only the files that contain your intellectual property.

✓ Encode these
  • app/Services/ — business logic
  • app/Http/Controllers/ — request handling
  • app/Models/ — domain models
  • app/Actions/ — domain workflows
  • Modules/ — proprietary modules
Leave readable
  • config/ — client configuration
  • routes/ — routing tables
  • database/migrations/ — schema
  • resources/views/ — templates
  • vendor/ — open-source packages

Create a protected_files.txt listing the paths you want to protect, one per line. This becomes your encoding manifest.

Step 2 — Encode Locally

PHPcube encodes entirely on your machine or CI runner. Your source code never leaves your environment. With the phpcube.so extension loaded in your local PHP CLI and a valid license.lic in your project root, run:

# Encode app/ into dist/app/ (preserves your originals)
php -r "phpcube_encode_dir('app', null, 'dist/app');"

Or encode only the files in your manifest:

php -r "phpcube_encode_list('protected_files.txt', null, 'dist');"

The encoder reads the product_key from your signed license.lic automatically. Each protected file becomes a PHPCUBE:B64: armored payload — unreadable without the loader.

Step 3 — Issue a Client License

For each client deployment, generate a license.lic locked to their domain. This file is cryptographically signed with Ed25519 — if the client edits it, the signature check fails and execution is blocked.

From your customer portal, or via the API:

./phpcube-cli license \
  --client="Acme Corp" \
  --domain="acme.com,*.acme.com" \
  --expires="2026-12-31" \
  --product-key="$KEY" \
  --key-dir=keys \
  --out=dist/license.lic

The license binds the decryption key to the client's domain. Running the protected application on any other domain returns an error.

Step 4 — Deploy to the Client Server

Ship the client:

  • ✓ The encoded PHP files (the dist/ folder)
  • ✓ Their license.lic in the application root
  • ✓ The phpcube.so loader for their PHP version
  • ✓ Plain files: config/, routes/, vendor/

On the client server, add the extension to php.ini:

extension=phpcube.so

Restart PHP-FPM and the application runs normally. The loader discovers license.lic, verifies the Ed25519 signature, decrypts the payload in RAM, and executes it — zero disk writes, zero plaintext exposure.

Automating in CI/CD

For teams using GitHub Actions or GitLab CI, the entire encode-and-license step runs in the pipeline. Your private keys live in CI secrets, the encoder compiles in seconds, and only the encrypted artifact is deployed to the client server.

# GitHub Actions snippet
- name: Encode application
  env:
    KEY: ${{ secrets.PHPCUBE_PRODUCT_KEY }}
  run: |
    php -r "phpcube_encode_dir('app', null, 'dist/app');"

- name: Issue client license
  run: |
    ./phpcube-cli license \
      --domain="$CLIENT_DOMAIN" \
      --expires="$EXPIRY" \
      --product-key="$KEY" \
      --key-dir=keys \
      --out=dist/license.lic

Summary

  • ✓ Encode selectively — only your proprietary business logic
  • ✓ Encode locally — your source never leaves your environment
  • ✓ Issue per-client Ed25519-signed licenses with domain lock and expiry
  • ✓ Deploy the loader + encrypted files — the client never sees your source
  • ✓ Automate the whole pipeline in GitHub Actions or GitLab CI

Ready to protect your PHP application?

Start a free 3-day trial — no payment required. Or let our team handle the encoding for you.

Related Articles

Start free Loader
✓ Copied!